fix(HandlesAssign): 对"指针的指针"右值的自动解引用收窄为取地址形态
原判据只看右值的 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 只用于字段访问 与调用分发,不在普通赋值路径)。
This commit is contained in:
1 parent
2ba38ae842
commit
42c13e372b
1 file changed
+10
-2
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user