diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index 16daa92..db00575 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -5063,11 +5063,39 @@ class ExprCallHandle(BaseHandle): print(f"[DEBUG_CLASSNEW] _HandleClassNewLlvm called for Asm, module_sha1={module_sha1}", file=_dbg_sys.stderr) # 跨模块类型引用:优先用 {module_sha1}.{ClassName} 查找 struct _struct_full_key: str | None = f"{module_sha1}.{ClassName}" if module_sha1 else None + # 【同名类消歧(2026-09-30)】ClassName 可能是**导入别名**( + # `from .astaux import Keyword as KwNode` 后写作 KwNode)或短名,而 + # `Gen.structs` / `Gen.functions` 的**短名键**在"两个模块各定义同名类"时是有歧义的 + # ——现场:Keyword 同时存在于 ast.astaux(8312ce86a2fd82c0) 与 + # ast.tokens(fef783da4d24330d)。ctor 的 self 实参按短名取到了 tokens.Keyword*, + # 而 callee 是 astaux 的 `8312ce86a2fd82c0.Keyword.__new__` ⇒ `_adjust_args` 报 + # "指针隐式转换已禁止(非基本类型(结构体/类/联合)):第 0 个实参 + # %"fef783da4d24330d.Keyword"* 不能隐式转为形参 %"8312ce86a2fd82c0.Keyword"*" + # (includes/ast/parser.vp:1774 `kw: rawptr[AST] = KwNode(ps.pool, None, val)`)。 + # 真名从**已解析到的构造函数对象**上取(其 IR 名是 `{sha1}.{Class}.{method}`), + # 与 callee 同源;取不到时保持原行为(短名回退),对无同名冲突的类零变化。 + _QCls: str | None = None + for _probe_key in (f'{ClassName}.__new__', f'{ClassName}.__before_init__', f'{ClassName}.__init__'): + _probe_fn: Any = Gen._find_function(_probe_key) + _probe_nm: str = (getattr(_probe_fn, 'name', '') or '') if _probe_fn is not None else '' + if _probe_nm.count('.') >= 2: + _QCls = _probe_nm.rsplit('.', 1)[0] + break def _get_struct_type(name: str) -> ir.Type | None: - """优先用 SHA1 前缀完整名查找,回退到短名""" + """优先用 SHA1 前缀完整名查找,再按"与 callee 同源的限定名"消歧,最后回退短名""" if _struct_full_key and _struct_full_key in Gen.structs: return Gen.structs[_struct_full_key] + if _QCls and _QCls != name and _QCls in Gen.structs: + _qc: Any = Gen.structs[_QCls] + # 只在"**同短名**(即确实是同名类的另一份实例)且**已具化**"时改判: + # 同短名保证不会把无关类引进来;已具化保证 `_allocaEntry` 的尺寸正确 + # (opaque 实例算不出大小,会让 ctor 的 self 指向尺寸错误的块)。 + if (isinstance(_qc, ir.IdentifiedStructType) + and (getattr(_qc, 'name', '') or '').rsplit('.', 1)[-1] + == (name or '').rsplit('.', 1)[-1] + and _qc.elements is not None): + return _qc return Gen.structs.get(name) if hasattr(self.Trans.ClassHandler, '_generic_class_templates') and ClassName in self.Trans.ClassHandler._generic_class_templates: