fix(LLVMCG): 禁止对 null 指针常量做 load 转 int 字段
_coerce_value 中 target 为 IntType 且 val 为 PointerType 时,若 val 是 null 常量且 pointee.width == target.width,此前直接 builder.load(null) 生成 load i32, i32* null,运行时 ASAN access-violation。根因场景:Generator.__init__ 里 self.ClassMetaKinds = None(字段注解 t.CInt | t.CPtr,联合类型 退化为 i32 槽位,None 解析为 i32* null)。修复:null 常量赋 int 字段直接返回 0;_store 的 null 分支同步补 IntType 处理。
This commit is contained in:
1 parent
0e80019033
commit
2922af79f1
1 file changed
+9
@@ -194,6 +194,11 @@ class MemoryOpsMixin:
|
||||
val = self.builder.zext(val, ir.IntType(64), name="zext_ptr_store")
|
||||
return self.builder.inttoptr(val, target_type, name="int_to_ptr_store")
|
||||
if isinstance(target_type, ir.IntType) and isinstance(val.type, ir.PointerType):
|
||||
if isinstance(val, ir.Constant) and val.constant is None:
|
||||
# null 指针常量赋给 int 字段 → 0。绝不能对 null 做 load
|
||||
# (此前 pointee.width == target.width 时直接 load null,
|
||||
# 生成 `load i32, i32* null` → ASAN access-violation)
|
||||
return ir.Constant(target_type, 0)
|
||||
if isinstance(val.type.pointee, ir.IntType) and val.type.pointee.width == target_type.width:
|
||||
return self.builder.load(val, name="load_ptr_as_int_store")
|
||||
if target_type.width <= 8 and isinstance(val.type.pointee, ir.IntType):
|
||||
@@ -264,6 +269,10 @@ class MemoryOpsMixin:
|
||||
elif isinstance(target_type, ir.IdentifiedStructType):
|
||||
val = ir.Constant(ir.PointerType(target_type), None)
|
||||
ptr = self.builder.bitcast(ptr, ir.PointerType(ir.PointerType(target_type)), name="null_struct_ptr_cast")
|
||||
elif isinstance(target_type, ir.IntType):
|
||||
# null 指针常量赋给 int 字段 → 0(与 _coerce_value 一致,
|
||||
# 防止 `store i32* null, i32*` 类型错乱 IR)
|
||||
val = ir.Constant(target_type, 0)
|
||||
else:
|
||||
coerced: ir.Value | None = self._coerce_value(val, target_type)
|
||||
if coerced is not None:
|
||||
|
||||
Reference in new issue
Block a user