From e65f04f16bcb04424990a2a59345fed0f4ada859 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sun, 27 Sep 2026 17:26:04 +0800 Subject: [PATCH] =?UTF-8?q?fix(codegen):=20=E5=AD=97=E6=AE=B5=E8=A1=A8?= =?UTF-8?q?=E2=86=94=E6=A7=BD=E4=BD=8D=E4=B8=80=E8=87=B4=E6=80=A7=E6=8A=A4?= =?UTF-8?q?=E6=A0=8F=E8=B1=81=E5=85=8D=E8=81=94=E5=90=88=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit union 的字段表有 N 条(每成员一条)但 LLVM 布局只有 1 个槽位(成员全偏移 0、按最大成员定宽),二者本不相等;字段访问走 bitcast 到字段类型后的 GEP,不依赖槽位下标。误报实证:EdgeCaseTest 的 class Data(t.CUnion)(i_val/f_val 两成员 → 1 槽)被护栏拦下。 --- App/lib/core/Gen/StructGenMixin.vp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/App/lib/core/Gen/StructGenMixin.vp b/App/lib/core/Gen/StructGenMixin.vp index a3d62f6..47429ad 100644 --- a/App/lib/core/Gen/StructGenMixin.vp +++ b/App/lib/core/Gen/StructGenMixin.vp @@ -986,6 +986,12 @@ novirtual class StructGenMixin: return 0 if entry.FieldCount <= 0: return 0 + # 联合体豁免:union 的字段表有 N 条(每个成员一条),但 LLVM 布局只有 **1 个 + # 槽位**(成员全部偏移 0、按最大成员定宽),二者本就不相等;字段访问走的是 + # bitcast 到字段类型后的 GEP(见 ExprGenAttr 的 union 分支),不依赖槽位下标, + # 故本护栏不适用(误报实证:EdgeCaseTest 的 `class Data(t.CUnion)`,2 成员 → 1 槽)。 + if entry.IsUnion != 0 or self.is_union_by_type(struct_ty) != 0: + return 0 fcount: int = llvmlite.get_struct_fcount(struct_ty) if fcount <= 0: return 0