fix(tpv): 复用的 alloca 与注解类型不一致时 fail-fast(D25 alloca 退化根治)
- get_or_create_sym 只用「名字+作用域」复用(ty 不参与判定),可能命中类型不同的旧 alloca(同名重声明 / 退化 alloca,如裸 list* 对上 list[ast.ASTptr]*)→ alloca 类型与使用点注解类型分裂 → 方法调用按错误元素类型特化 → inttoptr 截断 - 只比较「双方都是指针且 pointee 都是结构体」这一最典型退化形态:结构体名不同即 fatal_error,报出变量名与两个类型,直接暴露退化点(不兜底)
This commit is contained in:
1 parent
b206e7d9c1
commit
590a6a2bbe
1 file changed
+26
@@ -1562,6 +1562,32 @@ class AssignGenMixin:
|
||||
aa,
|
||||
f"无法为变量 {nm.id} 创建存储",
|
||||
"TypeError")
|
||||
# [D25 根治] 复用到的 alloca 类型必须与本次注解解析类型一致。
|
||||
# get_or_create_sym 只用「名字 + 作用域」复用(ty 不参与判定,见 VarGenMixin),
|
||||
# 因此可能命中一个**类型不同**的旧 alloca(同名重声明 / 不同路径建出的退化
|
||||
# alloca,如裸 list* 对上 list[ast.ASTptr]*)→ alloca 类型与使用点注解类型
|
||||
# 分裂 → 方法调用按错误的元素类型特化(list[int].get 返回 i32)→ inttoptr
|
||||
# 截断指针 → 读垃圾 AST 节点(D21/D25 崩溃族)。
|
||||
# 只比较「双方都是指针且 pointee 都是结构体」这一最典型的退化形态:
|
||||
# 结构体名不同即 fail-fast,直接暴露退化点与变量名(不兜底)。
|
||||
if alloca is not None and alloca.Ty is not None and var_ty is not None:
|
||||
av_pt_d: llvmlite.LLVMType | t.CPtr = alloca.Ty.Pointee
|
||||
if av_pt_d is not None and self.Gen.ExprGenBase.is_ptr_type(av_pt_d) != 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(var_ty) != 0:
|
||||
av_in: llvmlite.LLVMType | t.CPtr = av_pt_d.Pointee
|
||||
vt_in: llvmlite.LLVMType | t.CPtr = var_ty.Pointee
|
||||
if av_in is not None and vt_in is not None:
|
||||
av_nm_d: str = llvmlite.get_struct_name(av_in)
|
||||
vt_nm_d: str = llvmlite.get_struct_name(vt_in)
|
||||
if av_nm_d is not None and vt_nm_d is not None \
|
||||
and string.strcmp(av_nm_d, vt_nm_d) != 0:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
aa,
|
||||
f"变量 '{nm.id}' 复用到的存储类型为 '{av_nm_d}*',与注解解析类型 "
|
||||
f"'{vt_nm_d}*' 不一致(同名重声明命中了不同类型的旧 alloca);"
|
||||
f"禁止静默混用——方法调用会按错误元素类型特化并截断指针",
|
||||
"TypeError")
|
||||
|
||||
# FakeDuck: str 变量创建影子结构体 {var}__meta__(per-instance 字段存储)
|
||||
# 仅裸 str 注解(Name("str"))且 _str 已注册时创建;bytes / char|t.CPtr 不创建。
|
||||
# a 保持为 i8*(可 printf/len),a__meta__ 存 __data__/__mbuddy__ 等字段,
|
||||
|
||||
Reference in new issue
Block a user