From 5825e7e000e52c2f05d276d5ea2295b1df859989 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sun, 27 Sep 2026 15:16:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(codegen):=20=E5=8D=95=E7=9B=AE=20&=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AF=B9=E6=9E=84=E9=80=A0=E8=B0=83=E7=94=A8?= =?UTF-8?q?/=E5=87=BD=E6=95=B0=E8=B0=83=E7=94=A8=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E5=8F=96=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 与 TransPyV 侧 ExprGenOps._addrof_of_call 同口径:复用 _HandleUnaryOpLlvm 已求值的 OperandVal;构造调用 _HandleClassNewLlvm 返回临时对象的 Ptr(Struct),原样返回;其它类型落到 allocaEntry 临时槽。避免二次求值导致 __before_init__/__init__ 跑两遍。 --- lib/core/Handles/HandlesExprOps.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/core/Handles/HandlesExprOps.py b/lib/core/Handles/HandlesExprOps.py index c382ee8..956677a 100644 --- a/lib/core/Handles/HandlesExprOps.py +++ b/lib/core/Handles/HandlesExprOps.py @@ -288,9 +288,26 @@ class ExprOpsHandle(BaseHandle): SubPtr: ir.Value | None = self.Trans.ExprAttrHandle.HandleSubscriptPtrLlvm(Node.operand) if SubPtr and isinstance(SubPtr.type, ir.PointerType): return SubPtr + elif isinstance(Node.operand, ast.Call): + # &() → rvalue 取址。复用上面已求值的 OperandVal,绝不二次求值 + # (构造调用会再跑一遍 __before_init__/__init__)。 + # · 构造调用(_HandleClassNewLlvm)返回的就是临时对象的栈存储指针 + # Ptr(Struct) —— 该指针即"栈构造结构体的地址"本身,原样返回; + # 不能再套 alloca+store(会得到 Ptr(Ptr(Struct)),赋值端还得 + # load 一次回落,语义也从"对象地址"变"槽地址")。 + # · 其它返回值(标量、按值返回的结构体值):入口临时槽承载—— + # allocaEntry 同类型槽 → store → 返回槽地址(与 TransPyV 侧 + # ExprGenOps._addrof_of_call 同口径)。 + OperandType: ir.Type = OperandVal.type + if isinstance(OperandType, ir.PointerType) \ + and isinstance(OperandType.pointee, (ir.IdentifiedStructType, ir.LiteralStructType)): + return OperandVal + TmpSlot: ir.Value = Gen._allocaEntry(OperandType, name="addrof_tmp") + Gen.builder.store(OperandVal, TmpSlot) + return TmpSlot raise TypeError( f"[fast-fail] 单目 '&' 取地址的操作数必须是左值" - f"(Name/Attribute/Subscript),实际为 {type(Node.operand).__name__}" + f"(Name/Attribute/Subscript)或构造调用/函数调用结果,实际为 {type(Node.operand).__name__}" ) return None