From 02b94293639fed26899a8c5d563ff64b99bb0d65 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 1 Oct 2026 22:07:41 +0800 Subject: [PATCH] =?UTF-8?q?fix(type):=20void*=20=E5=BD=92=E5=B9=B6?= =?UTF-8?q?=E5=88=86=E6=94=AF=E7=9A=84=20match=20=E5=BF=85=E9=A1=BB?= =?UTF-8?q?=E5=AE=88=20None=EF=BC=8C=E4=BF=AE=20ASan=20=E7=A9=BA=E6=8C=87?= =?UTF-8?q?=E9=92=88=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BinOp 的 CPtr 分支里,上一笔为 void* 归并新增的 match other_ty 未判空。 other_ty = resolve_annotation_type(另一边) 在 Phase 1a prescan 时**可以是 None** (本分支下方既有代码就写着 if other_ty is None: ... 回退 Ptr(i8),正说明 None 是 期望值);对 None 做 REnum case 匹配会按其 tag 解引用空指针。 现场:TPV(ASan) 自举 Phase1 报 access-violation on address 0x0(READ), 栈 _prescan_funcdef_signatures → resolve_annotation_type;触发源是用户 WIP 里 新增的 X* 返回注解(parser 把 X* 展开成 BinOp X | t.CPtr,正好走本分支)。 改为 if other_ty is not None: 包住,None 继续走下方既有回退路径。 --- App/lib/core/Gen/Type/TypeGenResolve.vp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index 5cac4cd..0b35574 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -3118,11 +3118,17 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # 解析结果本身即 void(如 `typedef 不透明结构体 = void` 的那个名字, # 或经 typedef 兜底解析出的 void)⇒ 与 CPtr 合并即 void* = i8*, # 与上方 other_is_cvoid 分支同一结论(否则会拼出非法的 Ptr(void))。 - match other_ty: - case llvmlite.LLVMType.Void(): - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - case _: - pass + # **必须守 None**:`X*`(parser 展开为 BinOp `X | t.CPtr`)在 Phase 1a + # prescan 时 X 很可能尚未注册(类定义在函数之后),resolve 返回 None; + # 对 None 做 case 匹配会按 REnum tag 解引用空指针(ASan 现场:address 0x0 + # READ,栈 _prescan_funcdef_signatures → resolve_annotation_type)。 + # None 交由下方既有 `if other_ty is None:` 分支处理。 + if other_ty is not None: + match other_ty: + case llvmlite.LLVMType.Void(): + return llvmlite.Ptr(pool, llvmlite.Int8(pool)) + case _: + pass # 仅裸名(Name)场景验证解析结果必须是已注册 struct: # 损坏节点可能解析出基础类型垃圾(如 Int8 → Ptr(i8))。 # Attribute 场景(Module.Class / t.XXX)resolve 结果直接可用