diff --git a/lib/core/Handles/HandlesAssign.py b/lib/core/Handles/HandlesAssign.py index 8eccb34..634d85b 100644 --- a/lib/core/Handles/HandlesAssign.py +++ b/lib/core/Handles/HandlesAssign.py @@ -1612,7 +1612,8 @@ class AssignHandle(BaseHandle): f"或把基座显式转为 t.CPtr(无类型指针)后按 8 字节指针语义写入。{SrcInfo}") def _DescribeMemberSlot(self, Gen: "Translator.LlvmGen", ClassName: str | None, - FieldName: str, Offset: int, SelfPtr: ir.Value) -> str: + FieldName: str, Offset: int, SelfPtr: ir.Value, + StructHint: Any = None) -> str: """`self.字段 = 值` 成员槽写入失败的**来源明细**(供 fail-fast 报文引用)。 槽类型有两个**互相独立**的来源,必须自洽: @@ -1622,11 +1623,15 @@ class AssignHandle(BaseHandle): 现场:Generator.ExprGenConst 声明 `%"...ExprGenConst"*` 却落到 `i8**`。 此处把两侧数据逐项列出,直接判定是声明侧退化还是布局侧退化(含 structs 键空间大小与"是否同一对象",用于识别裸名 / sha1 全名双条目)。 + + `StructHint`(可选):调用方实际 GEP 用的那个 struct 实例。偏移基址必须与**那份 + 布局**同源(见 FuncGen._member_base 的 hint 说明)——传入时本报文报出的 base / + 下标才与失败现场一致;不传时行为与改前逐字一致(回落到类键实例)。 """ Lines: list[str] = [] try: Members: list = Gen.class_members.get(ClassName) or [] - Base: int = Gen._member_base(ClassName) + Base: int = Gen._member_base(ClassName, StructHint) Idx: int = Offset - Base Declared: Any = Members[Idx][1] if 0 <= Idx < len(Members) else None Lines.append( diff --git a/lib/core/Handles/HandlesExprBuiltin.py b/lib/core/Handles/HandlesExprBuiltin.py index b16213e..abfafa5 100644 --- a/lib/core/Handles/HandlesExprBuiltin.py +++ b/lib/core/Handles/HandlesExprBuiltin.py @@ -696,10 +696,20 @@ class ExprBuiltinHandle(BaseHandle): try: result = self.Trans.ExprUtils._try_operator_overLoad(field_cls, '__len__', list_val, Gen) except TypeError as _e_len: + # 来源明细(声明侧 class_members 名序/项数 vs 布局侧 elements) + # 追加进报文:本处失败的本质是"偏移算错",只看 偏移=6 无法区分 + # 是"表多一项(→ base 被 delta==0 判 0)"还是"取值处实例与类键实例 + # 不同源"。判据/读数见 AssignHandle._DescribeMemberSlot。 + _extra_len: str = '' + try: + _extra_len = self.Trans.AssignHandler._DescribeMemberSlot( + Gen, bare_cls, attr_name, offset, self_ptr, _STl2) + except Exception as _ea: + _extra_len = f"\n (来源明细生成失败: {type(_ea).__name__}: {_ea})" raise TypeError( f"[fast-fail] len({obj_name}.{attr_name}) 分派 '{field_cls}.__len__' 失败:" f"类='{bare_cls}' 偏移={offset} 接收者类型={list_val.type};" - f"(成员偏移与 struct 布局不一致)原错误: {_e_len}") + f"(成员偏移与 struct 布局不一致)原错误: {_e_len}{_extra_len}") if result is not None: return result val = self.HandleExprLlvm(arg_node)