diff --git a/lib/core/Handles/HandlesAnnAssign.py b/lib/core/Handles/HandlesAnnAssign.py index b922ef7..c34a3b2 100644 --- a/lib/core/Handles/HandlesAnnAssign.py +++ b/lib/core/Handles/HandlesAnnAssign.py @@ -848,6 +848,21 @@ class AnnAssignHandle(BaseHandle): _ann_base_v = _ann_base_v.value if isinstance(_ann_base_v, ast.Name): _ann_gen_base = _ann_base_v.id + # 「反向重建」方向判定(其二,见下方 _rb_is_upcast)所需的**注解侧 + # 被指类**:注解被 TypeMerge 折叠成 i8*(rawptr[X] / t.CPtr[X],见 + # 上方 635-684)时 VarType.pointee 不是结构体,此时用该处恢复进 + # var_struct_class 的 X —— 那正是注解写明的被指类。 + _ann_pointee: ir.Type | None = None + if isinstance(VarType, ir.PointerType): + _ap: ir.Type = VarType.pointee + if isinstance(_ap, ir.IdentifiedStructType): + _ann_pointee = _ap + else: + _ask: str | None = Gen.var_struct_class.get(VarName) + _ann_st: ir.Type | None = Gen.structs.get(_ask) if _ask else None + if isinstance(_ann_st, ir.PointerType): + _ann_st = _ann_st.pointee + _ann_pointee = _ann_st for CN, ST in Gen.structs.items(): # 泛型占位类型(T/U/V,如 GSList[T].Head 的元素类型)opaque 无 body, # 不参与变量类型重建/var_struct_class 设置:跟随 T* 会污染注解声明的 @@ -905,7 +920,22 @@ class AnnAssignHandle(BaseHandle): and '[' not in _cn_short and _cn_short == _ann_gen_base ) - if not _rb_is_bare_generic: + # 方向判定(其二):注解写明的被指类是 RHS 被指类的 + # **基类**时,注解就是合法的「基类指针」声明,RHS 只是 + # 继承上转 —— 以 RHS 重建 alloca 会把声明类型**窄化**成 + # 派生类,使同一变量随后赋基类/兄弟类的值被指针隐式 + # 转换 fail-fast 拦下(includes/ast/parser.vp + # `node: rawptr[AST] = Name(...)` 之后 + # `node = _new_const_str(...)` 现场根因)。 + # 判据只拦「上转被窄化」这一个确定的方向错误:注解退化 + # 成 i8*/裸占位(_ann_pointee 非其基类)时不受影响。 + _rb_is_upcast: bool = ( + _ann_pointee is not None + and _ann_pointee is not ST + and _ann_pointee != ST + and Gen._IsInheritanceUpcastPointee(pointee, _ann_pointee) + ) + if not _rb_is_bare_generic and not _rb_is_upcast: var = Gen._allocaEntry(ir.PointerType(pointee), name=VarName) VarType = ir.PointerType(pointee) break