From 42c13e372bfb207ea3275c72e5a2ea537a10e766 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 1 Oct 2026 18:33:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(HandlesAssign):=20=E5=AF=B9"=E6=8C=87?= =?UTF-8?q?=E9=92=88=E7=9A=84=E6=8C=87=E9=92=88"=E5=8F=B3=E5=80=BC?= =?UTF-8?q?=E7=9A=84=E8=87=AA=E5=8A=A8=E8=A7=A3=E5=BC=95=E7=94=A8=E6=94=B6?= =?UTF-8?q?=E7=AA=84=E4=B8=BA=E5=8F=96=E5=9C=B0=E5=9D=80=E5=BD=A2=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原判据只看右值的 LLVM 类型(Ptr(Ptr(...)))就 load 一层,于是显式 cast 的结果 (`entry = str*(uint64(argv) + idx*8)`,右值是 i8**)被多解一次引用 → 静默取到野指针 (includes/argparse.vp 的 parse_args 因此 ASan access-violation 0xffffffffffffffff)。 现限定为 Name/Attribute/Subscript 这类"取地址形态"(求值结果是存储地址,即"对象即指针" 返回 alloca/字段地址)才解引用;Call(显式 cast、构造/普通函数调用)与其它表达式给出的 是值本身,不再多解一层 —— 与 TransPyV 侧行为对齐(其 _deref_if_ptr_ptr 只用于字段访问 与调用分发,不在普通赋值路径)。 --- lib/core/Handles/HandlesAssign.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/core/Handles/HandlesAssign.py b/lib/core/Handles/HandlesAssign.py index fb7dac4..0810640 100644 --- a/lib/core/Handles/HandlesAssign.py +++ b/lib/core/Handles/HandlesAssign.py @@ -198,6 +198,14 @@ class AssignHandle(BaseHandle): if isinstance(Value.type, ir.VoidType): return Gen._UnregisterTempPtr(Value) + # 【右值形态判定】只有"取地址形态"的右值才需要自动解一层引用:Name/Attribute/ + # Subscript 的求值结果是**存储地址**(变量 alloca / 字段地址 /"对象即指针"), + # 赋给指针变量时必须 load 出内层指针。而 Call(显式 cast 如 `str*(addr)`、 + # `t.CPtr(x)`,以及构造/普通函数调用)与其它表达式给出的是**值本身**, + # 再 load 会多解一层 → 静默取到野指针(现场 includes/argparse.vp 的 + # `entry = str*(uint64(argv) + idx*8)`:i8** 右值被多解一次,entry 变成 + # argv[idx] 本身,随后 entry[0] 去读字符串头 8 字节 → ASan access-violation)。 + _rhs_addr_form: bool = isinstance(Node.value, (ast.Name, ast.Attribute, ast.Subscript)) # 大端局部变量:赋值时 bswap Value = Gen._apply_bswap_if_big(Value, Gen.local_var_byteorders.get(VarName, ""), f"bswap_assign_{VarName}") if isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)): @@ -398,7 +406,7 @@ class AssignHandle(BaseHandle): types_differ = TargetType and Value.type != TargetType except AssertionError: types_differ = False - if isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, ir.PointerType): + if _rhs_addr_form and isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, ir.PointerType): LoadedValue: ir.Value = Gen._load(Value, name=f"Load_{VarName}") Loaded_differ: bool try: @@ -435,7 +443,7 @@ class AssignHandle(BaseHandle): GVar: ir.GlobalVariable = Gen.module.globals[VarName] Gen._store(Value, GVar, Node=Node.value) Gen.variables[VarName] = GVar - elif isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, ir.PointerType): + elif _rhs_addr_form and isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, ir.PointerType): LoadedValue: ir.Value = Gen._load(Value, name=f"Load_{VarName}") var: ir.AllocaInstr = Gen._allocaEntry(LoadedValue.type, name=VarName) Gen._store(LoadedValue, var, Node=Node.value)