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:
1 parent
59865b2a3a
commit
2f6db41b11
3 files changed
+35
No files matched your search
@@ -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**),
|
||||
|
||||
@@ -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, _):
|
||||
|
||||
@@ -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, _):
|
||||
|
||||
Reference in new issue
Block a user