From d698fad162d32a8d711ce794f76e5ed6bccb73e2 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 20 Aug 2026 15:35:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(TPC):=20=E6=B3=9B=E5=9E=8B=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E7=B1=BB=E5=9E=8B=E5=AD=97=E6=AE=B5=E8=AE=BF=E9=97=AE?= =?UTF-8?q?=E7=89=B9=E5=8C=96=EF=BC=8C=E4=BF=AE=E5=A4=8D=20GSList.Head=20?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E6=B3=9B=E5=9E=8B=E5=8D=A0=E4=BD=8D=20T*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _handle_attr_nested 对声明为特化泛型(GSList[BasicBlock] | t.CPtr)的字段(如 Function.Blocks)访问 Head/Tail/Count 时,基础 GSList 有 body 直接按基础类型返回泛型占位 T*,AnnAssign 存储时变量被污染为 T*(var_struct_class 错设为 T),后续字段访问/while 循环体翻译静默失败 → llvmlite __function.vp _find_max_ssa_number/RenumberSSA 死循环(LLvmLiteTest Test 3 崩溃根因)。 修复:字段类型为泛型占位指针时,用 class_member_element_class 记录的特化版本 bitcast 后访问返回真实元素类型(如 BasicBlock*);AnnAssign 兜底跳过泛型占位参与变量类型重建,防其它 T* 场景污染。 --- lib/core/Handles/HandlesAnnAssign.py | 7 +++++++ lib/core/Handles/HandlesExprAttr.py | 29 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/core/Handles/HandlesAnnAssign.py b/lib/core/Handles/HandlesAnnAssign.py index 5048d10..8a4c413 100644 --- a/lib/core/Handles/HandlesAnnAssign.py +++ b/lib/core/Handles/HandlesAnnAssign.py @@ -623,6 +623,13 @@ class AnnAssignHandle(BaseHandle): Gen._record_var_signedness(VarName, IsUnsigned) return for CN, ST in Gen.structs.items(): + # 泛型占位类型(T/U/V,如 GSList[T].Head 的元素类型)opaque 无 body, + # 不参与变量类型重建/var_struct_class 设置:跟随 T* 会污染注解声明的 + # 真实类型(如 BasicBlock*),导致后续字段访问/循环体翻译静默失败。 + # (属性访问层已特化返回真实元素类型,此处为防御性兜底。) + _cn_short: str = CN.split('.')[-1] if '.' in CN else CN + if _IsGenericTpName(_cn_short): + continue if pointee is ST or pointee == ST: # 若注解是泛型特化(如 ndarray[t.CDouble] | t.CPtr), # 构造正确的特化名(如 ndarray[double]),而非用 opaque 基础名 diff --git a/lib/core/Handles/HandlesExprAttr.py b/lib/core/Handles/HandlesExprAttr.py index a60224b..b51dc94 100644 --- a/lib/core/Handles/HandlesExprAttr.py +++ b/lib/core/Handles/HandlesExprAttr.py @@ -737,6 +737,35 @@ class ExprAttrHandle(BaseHandle): offset = Gen._get_member_offset(Node.attr, CN) if offset is None: break + # 泛型基础类型字段特化(根本修复): + # 当字段声明为特化泛型(如 GSList[BasicBlock])时,基础类型(GSList)的 + # Head/Tail/Count 字段类型是泛型占位 T*。直接按基础类型访问会返回 T*, + # 导致变量类型被污染(后续字段访问/循环体翻译静默失败,见 + # llvmlite __function.vp _find_max_ssa_number 死循环根因)。 + # 用 class_member_element_class 记录的特化类型(parent_hint)重新访问, + # 返回真实元素类型(如 BasicBlock*)。 + if (parent_hint is not None + and isinstance(st, ir.IdentifiedStructType) + and st.elements is not None and offset < len(st.elements) + and isinstance(st.elements[offset], ir.PointerType) + and isinstance(st.elements[offset].pointee, ir.IdentifiedStructType)): + _field_short: str = (st.elements[offset].pointee.name or '').split('.')[-1] + if (len(_field_short) == 1 and _field_short.isalpha() and _field_short.isupper()): + _hint_short: str = parent_hint.split('.')[-1] if '.' in parent_hint else parent_hint + for CN2, ST2 in Gen.structs.items(): + if not isinstance(ST2, ir.IdentifiedStructType): + continue + if ST2 is ST: + continue + if ST2.elements is None: + continue + _spec_short: str = CN2.split('.')[-1] if '.' in CN2 else CN2 + if _spec_short == _hint_short: + _casted: Any = Gen.builder.bitcast(ObjVal, ir.PointerType(ST2), name=f"cast_spec_{CN}") + _off2: int | None = Gen._get_member_offset(Node.attr, CN2) + if _off2 is not None: + return self._gep_and_Load_member(Gen, _casted, _off2, Node.attr, CN2, ST2) + break return self._gep_and_Load_member(Gen, ObjVal, offset, Node.attr, CN, st) return None