Files
TransPyC/lib/core
TermiNexus b06dac1d6b fix(LLVMCG): 字段偏移改用「冻结表有效性锚点 + 尾部对齐」,AnnAssign.value 不再读到 i32
类别:a 编译器缺陷(TPC 侧)

现象:编译 TranslatorGenMixin.vp 时 fail-fast —— getelementptr(GEP) 的指针操作数不是
指针类型:操作数类型=i32、操作数名='value.9'、GEP 名='vtable_slot_AST'。即
`aa.value.kind()`(TranslatorGenMixin.vp:788)的接收者读成了整数:AnnAssign.value 落到
槽 3(lineno, i32),随后虚分派取 vtable 时把 i32 当指针用。

根因(两条独立判据,均写进代码注释与告警报文):
1) 冻结表陈旧:StructGen 建 body 时把「成员名→槽位」挂在 struct 实例上,而 body 之后会被
   「不完整即清除」(StructGen 预检 existing_st.elements = None)与 stub 加载
   (HandlesImports._TryLoadStructFromStub 的 set_body)清空后重设,重设路径不更新该表
   ⇒ 陈旧表按旧布局取槽(AnnAssign 在「自有 4 字段 + vtable」时冻结 {'value': 3},body
   被重设为 12 槽正确布局后仍取槽 3)。修:建表时同时记下 body 对象身份
   (_tpc_member_body,set_body 每次赋新 tuple),查询侧用 `is` 判同一性,失效即不再采用。
2) 未展平成员表:表只含自有字段(父类前缀未补齐)时,「base(0/1) + 表内下标」会把整类字段
   整体前移(target/annotation 落到指针槽 ⇒ 类型巧合、静默读错对象;value 落到 i32 槽 ⇒
   本次崩溃)。修:表短于 body 字段区时按**尾部对齐**取槽(展平规则 = 父类前缀 + 自有字段
   ⇒ 自有字段恒为 body 尾部 len(表) 项),并用 _MemberSlotAccepts 逐项类型比对自校验;
   表自洽(长度 == 字段区)时本路径不介入 ⇒ 对既有正确行为零变化;REnum 是 max-variant
   镜像布局,明确排除。命中时每类留一次告警,报出表长/字段区/取槽结果。

验证:8 例冒烟(冻结表新鲜;陈旧×展平表 / ×自有表;无冻结×自有表 / ×展平表;无 vtable;
整类逐字段 = 8/9/10/11;尾部类型不符时落回旧路径)全部通过;两文件 py_compile 通过。
2026-09-29 23:18:37 +08:00
..
2026-07-18 19:25:40 +08:00
2026-07-18 19:25:40 +08:00
2026-07-18 19:25:40 +08:00
2026-07-18 19:25:40 +08:00
2026-07-18 19:25:40 +08:00