From e33ac795ed1015d8d2968b710618ac2a7e9d0d52 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sun, 27 Sep 2026 16:02:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(codegen):=20=E6=8C=87=E9=92=88=E5=BC=BA?= =?UTF-8?q?=E8=BD=AC=E5=9F=BA=E5=BA=A7=20T*(x)=20=E7=9A=84=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E5=86=99=E5=85=A5=E8=A1=A5=E8=81=94=E5=90=88=E7=B1=BB?= =?UTF-8?q?=E5=90=8D=E9=80=9A=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 与读取侧 _handle_attr_call_result 的联合分支同口径:_get_attr_ptr 新增 Call 基座分支,用 _extract_union_base_class 取裸类名后 bitcast/inttoptr 回 Ptr(类) 再 GEP 成员。此前写入侧只认 Name/Attribute/Subscript,强转基座的字段写入静默返回 None。 --- lib/core/Handles/HandlesExprAttr.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/core/Handles/HandlesExprAttr.py b/lib/core/Handles/HandlesExprAttr.py index 7ba840b..d99906d 100644 --- a/lib/core/Handles/HandlesExprAttr.py +++ b/lib/core/Handles/HandlesExprAttr.py @@ -1527,6 +1527,35 @@ class ExprAttrHandle(BaseHandle): if offset is not None: MemberPtr = Gen.builder.gep(SubPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=Node.attr) return MemberPtr + elif isinstance(Node.value, ast.Call): + # 指针强转基座(`(ast.Call*(vinner)).IsVolatile = 1`):`T*(x)` 被 vast 的 + # _ConsumePtrSuffixCall 解析为 `(T | t.CPtr)(x)` 强转调用,结果类型是联合 + # 简化后的 i8*(struct 身份丢失),故须从强转注解(func 是 BitOr 联合) + # 提真实类名,bitcast/inttoptr 回 Ptr(类) 后 GEP 成员。 + # 与读取侧 _handle_attr_call_result 的联合分支(_extract_union_base_class) + # 逐字同口径;此前写入侧只认 Name/Attribute/Subscript,强转基座的字段 + # 写入一律静默返回 None。 + ObjVal: Any = self.HandleExprLlvm(Node.value) + if ObjVal is not None and isinstance(Node.value.func, ast.BinOp) \ + and isinstance(Node.value.func.op, ast.BitOr): + UnionCls: str | None = self._extract_union_base_class(Node.value.func) + if UnionCls and UnionCls in Gen.structs: + ST: Any = Gen.structs[UnionCls] + if isinstance(ST, ir.IdentifiedStructType) and (ST.elements is None or len(ST.elements) == 0): + self.Trans.ImportHandler._TryLoadStructFromStub(UnionCls, Gen) + ST = Gen.structs.get(UnionCls, ST) + TargetPtrTy: Any = ir.PointerType(ST) + if isinstance(ObjVal.type, ir.PointerType): + if ObjVal.type != TargetPtrTy: + ObjVal = Gen.builder.bitcast(ObjVal, TargetPtrTy, name=f"cast_{UnionCls}") + elif isinstance(ObjVal.type, ir.IntType): + ObjVal = Gen.builder.inttoptr(ObjVal, TargetPtrTy, name=f"int2ptr_{UnionCls}") + else: + return None + offset: int | None = Gen._get_member_offset(Node.attr, UnionCls) + if offset is not None: + MemberPtr = Gen.builder.gep(ObjVal, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=Node.attr) + return MemberPtr return None def _HandleSliceLlvm(self, base_val: ir.Value, slice_node: ast.Slice | ast.Index, base_ast: ast.AST) -> ir.Value | None: