From 59865b2a3a05d92f648463a494584c1e90e1bd28 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 1 Oct 2026 21:39:48 +0800 Subject: [PATCH] =?UTF-8?q?feat(TPV):=20void=20=E5=80=BC=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=20fail-fast=EF=BC=88=E5=A3=B0=E6=98=8E=20void=20=E5=8F=98?= =?UTF-8?q?=E9=87=8F=20/=20=E6=8A=8A=20void=20=E5=80=BC=E5=BD=93=E5=80=BC?= =?UTF-8?q?=E7=94=A8=E4=B8=80=E5=BE=8B=E6=8A=A5=20TypeError=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 承上一笔(裸名 void = t.CVoid 别名,仅 `void*` 与 `typedef 不透明结构体 = void` 可用): - ExprGenBase.coerce_to_type 顶部:void 值被 coerce 到**非 void** 目标(赋值 / 传参 / 返回 / 二元运算对齐)直接 fatal_error(TypeError),不再按 LLVM void 硬拼出非法 IR ("load void" / "bitcast ... to void");void → void 属无值传递,放行。 - AssignGenMixin.translate_annassign:注解解析结果为 void 时禁止声明该变量 (否则会按 LLVM void 建槽)。 --- App/lib/core/Gen/AssignGenMixin.vp | 7 +++++++ App/lib/core/Gen/Expr/ExprGenBase.vp | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index 6e3477f..842eb34 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -2159,6 +2159,13 @@ novirtual class AssignGenMixin: f"AnnAssign 缺少类型注解,变量名: {nm.id}", "SyntaxError") + # void 不能声明为变量(用户 2026-10-01:void 只能用于 `void*` 与 + # `typedef 不透明结构体 = void`)——否则会按 LLVM void 建槽,生成非法 IR。 + if var_ty is not None and self.Gen.StmtGenDecl._is_void_type(var_ty) != 0: + self.Gen.TypeGenErr.fatal_error(aa, + f"不能声明 void 类型的变量 '{nm.id}'(void 只能用于 void* 与 typedef 别名)", + "TypeError") + # t.Callable 函数指针:注册返回类型签名(供函数指针间接调用精确返回类型) callable_ret: llvmlite.LLVMType* = self.Gen.TypeGenErr.try_extract_callable_ret(pool, annot, trans._imported_modules, trans._from_imports, trans) if callable_ret is not None: diff --git a/App/lib/core/Gen/Expr/ExprGenBase.vp b/App/lib/core/Gen/Expr/ExprGenBase.vp index 32cc92d..0de14fc 100644 --- a/App/lib/core/Gen/Expr/ExprGenBase.vp +++ b/App/lib/core/Gen/Expr/ExprGenBase.vp @@ -755,6 +755,16 @@ novirtual class ExprGenBase: if self.is_ptr_type(target_ty) != 0: return llvmlite.build_bitcast(builder, val, target_ty) return self._NoneValueAsTarget(builder, target_ty) + # void 类型的值**不允许被当作值使用**(用户 2026-10-01:void 只能用于 `void*` + # 与 `typedef 不透明结构体 = void`)。任何把 void 值 coerce 到非 void 目标 + # (赋值 / 传参 / 返回 / 二元运算对齐)都是无意义操作 ⇒ fail-fast,而不是 + # 按 LLVM void 硬拼出非法 IR("load void"/"bitcast void")。void → void + # 属「无值传递」,放行。 + if self.Gen.StmtGenDecl._is_void_type(val.Ty) != 0: + if self.Gen.StmtGenDecl._is_void_type(target_ty) == 0: + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), + "void 类型的值不能参与任何操作(void 只能用于 void* 与 typedef 别名)", "TypeError") + return val # 函数 → 指针: bitcast(如 CreateThread(..., _thread_alloc_free, ...) 传函数指针) # 函数 Value 的 Ty 是 Func,既不是整数也不是指针,需在整数/浮点转换之前处理 match val.Ty: