fix(tpc): 函数声明创建收口到幂等入口 _CreateOrReuseFuncDecl;清理 DDEBUG 探针
类别:a 编译器缺陷(根因修复)+ 调试探针移除。 现场:翻译 CallGenFd.vp 时抛 llvmlite.ir._utils.DuplicatedNameError: '5d84ea579d83ef73.CallGenFd._translate_fakeduck_call'(llvmlite 的 NameScope 按名字去重,GlobalValue.deduplicate_name=False ⇒ 同名 global 建第二次必抛,且报文只给名字、不给两侧签名)。 根因:BaseGen._get_or_declare_function 建完 ir.Function 后**只加入 module.globals**(llvmlite 自动)而**未登记 Gen.functions**;而 HandlesFunctions._EmitFunctionLlvm 的 need_new 判据只看 Gen.functions (`MangledName not in Gen.functions`)⇒ 同一名字再建一次 → DuplicatedNameError; 该处 except 又把它吞掉(非 strict 模式只 LogWarning)→ 函数始终没进 Gen.functions → 后续其它创建点(FuncGen._get_or_declare_func / get_or_declare_c_func,同样只查 self.functions)再建 → 异常从别处逃逸到 Phase2Translator。 修复: 1. BaseGen 新增 _CreateOrReuseFuncDecl(name, func_type) —— 函数声明创建的 唯一幂等入口:module.globals 已有同名函数且**函数类型结构串相同**则复用 (并补登记 Gen.functions;FunctionType 无 __eq__,只能比 str); 类型不同则 fail-fast 报出两侧签名(declare/define 分裂的真因), 绝不静默复用错签名(调用点会按错签名传参)。 2. _get_or_declare_function 改走该入口(顺带补登记 Gen.functions); FuncGen._get_or_declare_func / get_or_declare_c_func 改走该入口; HandlesFunctions 定义路径改走该入口,且该处 except 对 FailFastError 直接 re-raise(不再吞)。 3. 清理遗留调试探针(含 sys.exit(1)):BaseGen 三处 [DDEBUG] (_get_or_declare_function 双点 / _mangle_func_name 前导点与结果双点)、 HandlesExprAsm 两处 [DDEBUG_ASM]、HandlesExprCall 一处 [DDEBUG] _HandleClosureCallLlvm。
This commit is contained in:
1 parent
3bc3c48dee
commit
9d8aedec4a
5 files changed
+47
-57
No files matched your search
@@ -310,11 +310,6 @@ class ExprAsmHandle(BaseHandle):
|
||||
def _mangle_asm_calls(self, template: str) -> str:
|
||||
Gen: LlvmCodeGenerator = self.Trans.LlvmGen
|
||||
sha1: str = getattr(Gen, 'module_sha1', '')
|
||||
# DDEBUG: 检测 module_sha1 是否带尾随点(双点 bug 根因拦截)
|
||||
if sha1 and sha1.endswith('.'):
|
||||
import sys as _dbg_sys
|
||||
print(f"[DDEBUG_ASM] module_sha1 带尾随点: sha1='{sha1}' len={len(sha1)} template='{template[:80]}'", file=_dbg_sys.stderr)
|
||||
_dbg_sys.exit(1)
|
||||
if not sha1:
|
||||
return template
|
||||
|
||||
@@ -324,11 +319,6 @@ class ExprAsmHandle(BaseHandle):
|
||||
if func_name.lower() in self._X86_REGISTERS:
|
||||
return m.group(0)
|
||||
mangled: str = Gen._mangle_func_name(func_name)
|
||||
# DDEBUG: 检测 mangled 是否含双点(双点 bug 根因拦截)
|
||||
if '..' in mangled:
|
||||
import sys as _dbg_sys
|
||||
print(f"[DDEBUG_ASM] mangled 含双点: func='{func_name}' mangled='{mangled}' sha1='{sha1}'", file=_dbg_sys.stderr)
|
||||
_dbg_sys.exit(1)
|
||||
if '.' in mangled:
|
||||
return f'{prefix}\\22{mangled}\\22'
|
||||
return f"{prefix}{mangled}"
|
||||
|
||||
@@ -2479,15 +2479,6 @@ class ExprCallHandle(BaseHandle):
|
||||
def _HandleClosureCallLlvm(self, Node: ast.Call, FuncName: str) -> ir.Value:
|
||||
Gen = self.Trans.LlvmGen
|
||||
func = Gen.functions.get(FuncName)
|
||||
# DDEBUG: 检测 func.name 含双点(说明 ir.Function 已被错误注册为双点名字)
|
||||
if func is not None and '..' in getattr(func, 'name', ''):
|
||||
import sys
|
||||
sys.stderr.write(f"[DDEBUG] _HandleClosureCallLlvm DOUBLE-DOT func.name='{func.name}' FuncName='{FuncName}'\n")
|
||||
sys.stderr.write(f"[DDEBUG] Gen.functions keys for '{FuncName}': {[k for k in list(Gen.functions.keys()) if '6ddf' in k or k == FuncName][:20]}\n")
|
||||
import traceback
|
||||
traceback.print_stack(file=sys.stderr, limit=10)
|
||||
sys.stderr.flush()
|
||||
sys.exit(1)
|
||||
if not func:
|
||||
if FuncName in self.Trans.FunctionDefCache:
|
||||
FuncDef = self.Trans.FunctionDefCache[FuncName]
|
||||
|
||||
@@ -1253,7 +1253,13 @@ class FunctionHandle(BaseHandle):
|
||||
need_new = True
|
||||
if need_new:
|
||||
try:
|
||||
func: ir.Function = ir.Function(Gen.module, FuncType, name=MangledName)
|
||||
# 统一走幂等入口:module.globals 已有同名函数时复用(并补登记
|
||||
# Gen.functions),签名冲突则 fail-fast —— 绝不直接新建同名
|
||||
# ir.Function(llvmlite NameScope 按名去重,必抛 DuplicatedNameError;
|
||||
# 现场:5d84ea579d83ef73.CallGenFd._translate_fakeduck_call 被此路径新建,
|
||||
# 而 BaseGen._get_or_declare_function 已建过同名声明却未登记
|
||||
# Gen.functions ⇒ need_new 误判为真)。
|
||||
func: ir.Function = Gen._CreateOrReuseFuncDecl(MangledName, FuncType)
|
||||
func.attributes.add('noredzone')
|
||||
if hasattr(self, '_cdefine_funcs') and FuncName in self._cdefine_funcs:
|
||||
func.linkage = 'linkonce_odr'
|
||||
@@ -1270,6 +1276,10 @@ class FunctionHandle(BaseHandle):
|
||||
if MangledName == FuncName or FuncName not in Gen._export_extern_funcs:
|
||||
Gen.functions[FuncName] = func
|
||||
except Exception as _e:
|
||||
from lib.core.LLVMCG.FuncGen import FailFastError
|
||||
if isinstance(_e, FailFastError):
|
||||
# 签名冲突 = declare/define 分裂,必须终止(不吞)
|
||||
raise
|
||||
if _config_mode == "strict":
|
||||
self.Trans.LogWarning(f"异常被忽略: {_e}")
|
||||
else:
|
||||
|
||||
Reference in new issue
Block a user