Files
TransPyC/lib
TermiNexus 935a5b372b fix(tpc): 属性读取返回 None 时登记「确切原因」,5 个 return None 点不再同义
类别:a(编译器缺陷 —— fail-fast 报文缺根因区分,5 个不同故障同报"求值为空")

现象:`self.Gen.ExprGen.translate_value(builder, pool, mod, ie.orelse, ...)`
(ExprGenOps.vp:97)报「调用实参编译期求值为空」,而同函数同对象的 `ie.test`
(:43)、`ie.body`(:78)求值正常。三个字段在 `IfExp` 布局里是**连续三槽**
(stub: %"…IfExp" = { i8*, AST*, MemBuddy*, i32×4, list*, AST*(test),
AST*(body), AST*(orelse) },共 11 元素),只有最后那个失败 ⇒ 必然是"偏移越出
body 元素数"这一类,但报文只说"求值为空",无法与"类名未解析 / 基座求值为空 /
结构体未匹配 / stub 无 body"区分。

改动(纯取证,不改变任何判定与 IR):
1. HandlesBase 新增 `_NoteAttrNone(Gen, ClassName, AttrName, Reason)`:把
   `(类名, 字段名, 原因)` 记到 `Gen._LastAttrNone`。
2. HandlesExprAttr 的 5 个 return None 点全部登记:
   - `_gep_and_Load_member`:偏移为 None;**偏移越界**(附 offset / body 元素数 /
     st 版元素数 / 成员表项数)。
   - `_handle_attr_name`:类名未解析;基座自身求值为空;结构体未匹配(附 ObjVal
     类型);stub 无 body;槽位越界(附 offset / pointee 元素数 / st 元素数)。
3. `_DescribeAttrBase` 追加三项事实:`struct body 元素数`、`字段 X 计算偏移`
   (`_get_member_offset`,异常则报异常类型)、以及与被报节点 (类名, 字段名)
   一致时回显 `读取侧原因=...`(不一致不回显,避免嵌套读取的旧记录冒充)。

依据:字段名在成员表里能找到却没读到值,只可能是"偏移 ≥ body 元素数"
(`_get_member_offset` 找不到字段时已 fail-fast,不会返回 None);因此
`偏移/body元素数/成员表项数` 三个数字是判定该情况的唯一依据,必须一次报全。
2026-09-29 17:46:58 +08:00
..