fix(gen,renum): 指针操作符目标写入落盘 + REnum tag 三侧口径统一,修 kind() CastError
- AssignGenMixin: 补 UnaryOp(Deref) 赋值目标分支(*p = v / *&x = *&y),非 Deref 的 &x/-x/~x fail-fast;*p += v 真正实现;Tuple/List 目标合并 - CallGenDispatch: kind() 改四级 REnum 判据(变体表 / struct __tag / pointee 带 __tag / X.field 声明类型反推);修正 build_load 第一参数误传指针类型 rk_tag_p(生成 load i32*, i32* 使返回值 Ty 为 i32*,导致 CallGenLib.vp:355 vk_a: int = val.Ty.kind() 报指针隐式转整数的 CastError),rk_load 分支同步改 rk_ty.Pointee - CallGenCtor / MatchGenMixin: __tag 读/写/比统一取字段声明类型 FieldEntry.Ty - Test/FieldReadTest: 字段读取探针
This commit is contained in:
1 parent
bcf66edebe
commit
f0309e4904
6 files changed
+323
-35
No files matched your search
@@ -1534,9 +1534,47 @@ novirtual class AssignGenMixin:
|
||||
llvmlite.build_store(builder, result, elem_ptr, vol_sa)
|
||||
return 0
|
||||
|
||||
# UnaryOp 目标: *p += v —— 解引用增强赋值。
|
||||
# 目标节点是 UnaryOp(Deref)(SetStoreContext 不改 UnaryOp 的 ctx),
|
||||
# 与 `*p = v` 同一形态;流程同 Subscript 分支:
|
||||
# 操作数求值取指针 → load 当前值 → 二元运算 → store 回同址。
|
||||
if tk == ast.ASTKind.UnaryOp:
|
||||
uo_ag: ast.UnaryOp* = ast.UnaryOp*(target)
|
||||
if uo_ag is None or uo_ag.operand is None:
|
||||
self.Gen.TypeGenErr.fatal_error(target, "增量赋值目标单目运算缺少操作数", "TypeError")
|
||||
if uo_ag.op != ast.OpKind.Deref:
|
||||
self.Gen.TypeGenErr.fatal_error(target,
|
||||
"增量赋值目标只支持单目 '*' 解引用(&x / -x / ~x 不是合法左值)", "SyntaxError")
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
builder: llvmlite.IRBuilder* = trans._cur_builder
|
||||
mod: llvmlite.LLVMModule* = trans.Module
|
||||
ptr_ag: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, uo_ag.operand, None, 0, trans)
|
||||
if ptr_ag is None or ptr_ag.Ty is None \
|
||||
or self.Gen.ExprGenBase.is_ptr_type(ptr_ag.Ty) == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(target,
|
||||
"增量赋值 '*' 的操作数必须是指针类型(类型推断退化)", "TypeError")
|
||||
ty_ag: llvmlite.LLVMType* = ptr_ag.Ty.Pointee
|
||||
if ty_ag is None:
|
||||
self.Gen.TypeGenErr.fatal_error(target,
|
||||
"解引用增量赋值的目标类型缺失(pointee 为空)", "TypeError")
|
||||
old_ag: llvmlite.Value* = llvmlite.build_load(builder, ty_ag, ptr_ag, 0)
|
||||
if old_ag is None:
|
||||
self.Gen.TypeGenErr.fatal_error(target, "无法加载解引用当前值", "TypeError")
|
||||
rhs_ag: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aug.value, None, 0, trans)
|
||||
if rhs_ag is None:
|
||||
self.Gen.TypeGenErr.fatal_error(target, "rhs 翻译失败", "TypeError")
|
||||
res_ag: llvmlite.Value* = self._apply_aug_op(pool, builder, aug.op, old_ag, rhs_ag, node, trans, target)
|
||||
if res_ag is None:
|
||||
self.Gen.TypeGenErr.fatal_error(target, f"解引用二元运算失败 op={aug.op}", "TypeError")
|
||||
res_ag = self.Gen.ExprGenBase.coerce_to_type(builder, res_ag, ty_ag, node, trans)
|
||||
if res_ag is None:
|
||||
self.Gen.TypeGenErr.fatal_error(target, "类型对齐失败", "TypeError")
|
||||
llvmlite.build_store(builder, res_ag, ptr_ag, 0)
|
||||
return 0
|
||||
|
||||
if tk != ast.ASTKind.Name:
|
||||
# fail-fast: 不支持的 AugAssign 目标类型
|
||||
self.Gen.TypeGenErr.fatal_error(target, "AugAssign 目标类型不支持,仅支持 Name/Attribute/Subscript", "TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(target, "AugAssign 目标类型不支持,仅支持 Name/Attribute/Subscript/*解引用", "TypeError")
|
||||
|
||||
nm: ast.Name* = ast.Name*(target)
|
||||
if nm is None or nm.id is None:
|
||||
@@ -2700,10 +2738,13 @@ novirtual class AssignGenMixin:
|
||||
|
||||
tk: int = target.kind()
|
||||
|
||||
# Tuple 赋值: a, b = f() 多返回值解包
|
||||
# Tuple/List 赋值: a, b = f() / [a, b] = f() 多返回值解包
|
||||
# rhs_val 是匿名 struct 值(函数返回 tuple[T1,T2] 打包)→ alloca +
|
||||
# store + GEP 逐字段 load → store 到各 Name 目标。
|
||||
if tk == ast.ASTKind.Tuple:
|
||||
# ast.List 与 ast.Tuple 字段表逐字相同(Nodes.py:119-120 均为
|
||||
# ('elts','ctx')),故按 Tuple 视图统一取 elts;此前只认 Tuple ⇒
|
||||
# `[a, b] = f()` 落入无分支区被静默丢弃(不落盘、不报错)。
|
||||
if tk == ast.ASTKind.Tuple or tk == ast.ASTKind.List:
|
||||
tgt_tup: ast.Tuple* = ast.Tuple*(target)
|
||||
tgt_elts: list[ast.AST*]* = tgt_tup.elts
|
||||
# 守卫:rhs 不是 struct(tuple 打包)时跳过本 target
|
||||
@@ -2887,6 +2928,37 @@ novirtual class AssignGenMixin:
|
||||
self.Gen.TypeGenErr.fatal_error(target, "subscript ptr is None")
|
||||
continue
|
||||
|
||||
# UnaryOp 目标: *p = val —— 解引用写入(与读侧同一节点形态)。
|
||||
# 解析链:语句级 Assign 走 vast_c.c ParseSimpleStmt 的
|
||||
# ParseExprList + SetStoreContext;`*p` 由 ParseFactor 产出
|
||||
# UnaryOp(Deref)(与 `*p` 读侧完全同形),而 SetStoreContext 只改
|
||||
# Attribute/Subscript/Name/Tuple/List/Starred 的 ctx,**不改 UnaryOp**
|
||||
# ⇒ 赋值目标就是 ctx=Load 的 UnaryOp(Deref)。
|
||||
# 此前目标分派(Tuple/Subscript/Attribute/Name)无 UnaryOp 分支且无兜底
|
||||
# ⇒ 该语句被整条静默丢弃(既不落盘也不报错):memhub 的块头
|
||||
# `(order<<1)|1`、空闲链 next、canary 三处写入全不发射 ⇒ 块头恒为 0
|
||||
# (free 被拒)、free_lists 链读到未初始化 0xBE、池单调漏满 ⇒ 1 GiB OOM。
|
||||
# `&x`/`-x` 作目标不是合法左值,故除 Deref 外一律 fail-fast。
|
||||
if tk == ast.ASTKind.UnaryOp:
|
||||
uo_w: ast.UnaryOp* = ast.UnaryOp*(target)
|
||||
if uo_w is None or uo_w.operand is None:
|
||||
self.Gen.TypeGenErr.fatal_error(target, "赋值目标单目运算缺少操作数", "TypeError")
|
||||
if uo_w.op != ast.OpKind.Deref:
|
||||
self.Gen.TypeGenErr.fatal_error(target,
|
||||
"赋值目标只支持单目 '*' 解引用(&x / -x / ~x 不是合法左值)", "SyntaxError")
|
||||
ptr_w: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, uo_w.operand, None, 0, trans)
|
||||
if ptr_w is None or ptr_w.Ty is None \
|
||||
or self.Gen.ExprGenBase.is_ptr_type(ptr_w.Ty) == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(target,
|
||||
"单目 '*' 赋值的操作数必须是指针类型(类型推断退化)", "TypeError")
|
||||
pointee_w: llvmlite.LLVMType* = ptr_w.Ty.Pointee
|
||||
if pointee_w is None:
|
||||
self.Gen.TypeGenErr.fatal_error(target,
|
||||
"解引用写入的目标类型缺失(pointee 为空)", "TypeError")
|
||||
sv_w: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, pointee_w, node, trans)
|
||||
llvmlite.build_store(builder, sv_w, ptr_w)
|
||||
continue
|
||||
|
||||
# Attribute 赋值: obj.field = val
|
||||
if tk == ast.ASTKind.Attribute:
|
||||
# property setter 拦截: obj.attr = v 且 attr 是 @x.setter 方法时,
|
||||
|
||||
Reference in new issue
Block a user