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