From 2922af79f1759009266d5df3419e85b415f76137 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 18 Aug 2026 12:50:31 +0800 Subject: [PATCH] =?UTF-8?q?fix(LLVMCG):=20=E7=A6=81=E6=AD=A2=E5=AF=B9=20nu?= =?UTF-8?q?ll=20=E6=8C=87=E9=92=88=E5=B8=B8=E9=87=8F=E5=81=9A=20load=20?= =?UTF-8?q?=E8=BD=AC=20int=20=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _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 处理。 --- lib/core/LLVMCG/MemoryOps.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/core/LLVMCG/MemoryOps.py b/lib/core/LLVMCG/MemoryOps.py index 07003e6..40cc4b6 100644 --- a/lib/core/LLVMCG/MemoryOps.py +++ b/lib/core/LLVMCG/MemoryOps.py @@ -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: