fix(void): 形参与字段注解禁止 void,改为编译期 fail-fast

void 只允许用于 void* 与 typedef 不透明结构体别名(用户 2026-10-01 定)。
此前 def f(p: void) / class C: x: void 不走 translate_annassign,会按 LLVM void
直接建形参/字段槽,生成非法 IR 拖到 llc 阶段才暴露。现补 6 处形参落点
(FuncGenDef 前向声明/外部声明/函数体/alloca 各一、ClassGenVTable 签名/alloca 各一)
与 1 处字段落点(ClassGenDef),统一编译期 TypeError。
void* 已在上游归并为 i8*,不受影响。
This commit is contained in:
TermiNexus committed 2026-10-01 21:43:11 +08:00
1 parent 59865b2a3a
commit 2f6db41b11
3 files changed
+35

No files matched your search

+6
View File
@@ -347,6 +347,12 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
# 解析字段类型
field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0)
# void 不是合法字段类型(用户 2026-10-01:void 只能用于 `void*` 与
# `typedef 不透明结构体 = void`);`void*` 已在上游归并为 i8*,不会命中。
# 放任会按 LLVM void 建字段槽 ⇒ 结构体布局非法(拖到 llc 才暴露),
# 故此处编译期 fail-fast。
if field_ty is not None and self.Gen.StmtGenDecl._is_void_type(field_ty) != 0:
self.Gen.TypeGenErr.fatal_error(aa, f"字段 '{tgt.id}' 不能是 void 类型(void 只能用于 void* 与 typedef 别名)", "TypeError")
# 单参 t.CArray[elem] + 列表字面量 → 静态数组 [N x elem]
# (与局部 AnnAssign 路径一致,对齐 TPC ParseListAnnotation 语义):
# 否则字段保持 Ptr(elem)(如 t.CArray[str] → i8**),
+11
View File
@@ -779,6 +779,13 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
# (append 返回后悬垂,G5 Test4 head.Value 读到垃圾)。
# CArray 形参 → 元素指针 ty*(数组衰减,C 语义,与函数形参一致)。
match resolved:
case llvmlite.LLVMType.Void():
# void 不是合法形参类型(用户 2026-10-01:void 只能用于
# `void*` 与 `typedef 不透明结构体 = void`);`void*` 已在上游
# 归并为 i8*,不会命中此分支。放任会按 LLVM void 建形参 ⇒
# 非法 IR 拖到 llc 才暴露,改编译期 fail-fast。
self.Gen.TypeGenErr.fatal_error(arg, f"方法 '{class_name}.{method_name}' 形参 '{arg.arg}' 不能是 void 类型(void 只能用于 void* 与 typedef 别名)", "TypeError")
return 0
case llvmlite.LLVMType.Struct(_, _, _):
param_ty = llvmlite.Ptr(pool, resolved)
case llvmlite.LLVMType.Array(aelem_ty, _):
@@ -923,6 +930,10 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
# 与 add_param 保持一致:裸类形参 → Ptr(struct)(对象即指针)
# CArray 形参 → 元素指针 ty*(数组衰减,与 add_param 一致)
match resolved2:
case llvmlite.LLVMType.Void():
# void 不是合法形参类型(用户 2026-10-01,见上方同款判据)
self.Gen.TypeGenErr.fatal_error(arg2, f"方法 '{class_name}.{method_name}' 形参 '{arg2.arg}' 不能是 void 类型(void 只能用于 void* 与 typedef 别名)", "TypeError")
return 0
case llvmlite.LLVMType.Struct(_, _, _):
param_ty2 = llvmlite.Ptr(pool, resolved2)
case llvmlite.LLVMType.Array(aelem_ty2, _):
+18
View File
@@ -254,6 +254,13 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
# 注册完整定义再按值(ensure_struct_def_in_module,先例
# CallGenCtor.vp L478);不命中(真 opaque)保持 Ptr(struct)。
match resolved:
case llvmlite.LLVMType.Void():
# void 不是合法形参类型(用户 2026-10-01:void 只能用于
# `void*` 与 `typedef 不透明结构体 = void`)。放任会按
# LLVM void 建形参 ⇒ 非法 IR 拖到 llc 才暴露,改编译期 fail-fast。
# 注意 `void*` 已在上游归并为 i8*,不会命中此分支。
self.Gen.TypeGenErr.fatal_error(arg, f"形参 '{arg.arg}' 不能是 void 类型(void 只能用于 void* 与 typedef 别名)", "TypeError")
return 0
case llvmlite.LLVMType.Struct(_, _, _):
if is_extern_decl != 0 and self.Gen.StructGen.find_struct_by_type(resolved) is not None:
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, resolved)
@@ -506,6 +513,9 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
# 同 forward_declare_functions / VpiReader
# _AggregateParamTy,三处必须同步)。
match resolved_e:
case llvmlite.LLVMType.Void():
# void 不是合法形参类型(用户 2026-10-01,见上方同款判据)
self.Gen.TypeGenErr.fatal_error(arg_e, f"形参 '{arg_e.arg}' 不能是 void 类型(void 只能用于 void* 与 typedef 别名)", "TypeError")
case llvmlite.LLVMType.Struct(_, _, _):
if self.Gen.StructGen.find_struct_by_type(resolved_e) is not None:
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, resolved_e)
@@ -614,6 +624,10 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
# 的 out 指向调用方数组首元素;传 Ptr(数组) 会使 out[i] 的
# GEP 以整个数组为步长错位,摘要垃圾根因)
match resolved:
case llvmlite.LLVMType.Void():
# void 不是合法形参类型(用户 2026-10-01,见上方同款判据)
self.Gen.TypeGenErr.fatal_error(arg, f"形参 '{arg.arg}' 不能是 void 类型(void 只能用于 void* 与 typedef 别名)", "TypeError")
return 0
case llvmlite.LLVMType.Struct(_, _, _):
param_ty = llvmlite.Ptr(pool, resolved)
case llvmlite.LLVMType.Array(aelem_ty, _):
@@ -765,6 +779,10 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
# CArray 形参 → 元素指针 ty*(数组衰减,alloca 类型须与形参一致,
# 否则 store ty* 到 [N x ty]* 容器类型不匹配)
match resolved2:
case llvmlite.LLVMType.Void():
# void 不是合法形参类型(用户 2026-10-01,见上方同款判据)
self.Gen.TypeGenErr.fatal_error(arg2, f"形参 '{arg2.arg}' 不能是 void 类型(void 只能用于 void* 与 typedef 别名)", "TypeError")
return 0
case llvmlite.LLVMType.Struct(_, _, _):
param_ty2 = llvmlite.Ptr(pool, resolved2)
case llvmlite.LLVMType.Array(aelem_ty2, _):