feat(TPV): void 值操作 fail-fast(声明 void 变量 / 把 void 值当值用一律报 TypeError)

承上一笔(裸名 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 建槽)。
This commit is contained in:
TermiNexus committed 2026-10-01 21:39:48 +08:00
1 parent e0bcf4bcef
commit 59865b2a3a
2 files changed
+17

No files matched your search

+7
View File
@@ -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:
+10
View File
@@ -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: