fix(tpv): extern declare 返回类型含真实类型时不再误归 Void + 白名单兜底
vpi 注入 extern declare 时 has_state→Void 无条件触发:注解 HANDLE | t.State(FindFirstFileA/GetStdHandle)被归为 void → declare 返回 void,运行期 FindFirstFileA 句柄丢失 → 文件存在性判断失效(文件实际存在但报不存在)。修复:仅纯标记注解归 Void;含真实类型但解析 miss 时回退外部函数返回类型白名单(FindFirstFileA/GetStdHandle→i8*),GenApi 新增 infer_external_func_ret_ty 委托。
This commit is contained in:
1 parent
efc8f7948f
commit
2b2c242d14
2 files changed
+39
-1
No files matched your search
@@ -1863,8 +1863,28 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
pool, fd.returns, imported_modules, from_imports, trans)
|
||||
# 如果返回类型是纯 t.State(无实际类型),用 Void
|
||||
if ret_ty is None and fd.returns is not None:
|
||||
if has_state != 0:
|
||||
# t.State/t.CExtern 是存储类装饰器标记,非真实返回类型。
|
||||
# 注解 "HANDLE | t.State"(FindFirstFileA)含真实类型 → 不能归 Void
|
||||
# (此前无条件 has_state→Void,extern declare 返回 void,运行期
|
||||
# FindFirstFileA 句柄丢失 → 文件存在性判断失效根因)。
|
||||
# 仅纯标记注解(t.State/t.CExtern/t.CExport 单独出现)才返回 Void。
|
||||
is_pure_marker_rt: int = 0
|
||||
rk2_rt: int = fd.returns.kind()
|
||||
if rk2_rt == ast.ASTKind.Name or rk2_rt == ast.ASTKind.Constant:
|
||||
is_pure_marker_rt = 1
|
||||
elif rk2_rt == ast.ASTKind.Attribute:
|
||||
pm_at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(fd.returns)
|
||||
if pm_at.attr is not None and (string.strcmp(pm_at.attr, "State") == 0
|
||||
or string.strcmp(pm_at.attr, "CExtern") == 0
|
||||
or string.strcmp(pm_at.attr, "CExport") == 0):
|
||||
is_pure_marker_rt = 1
|
||||
if is_pure_marker_rt != 0:
|
||||
ret_ty = llvmlite.Void(pool)
|
||||
elif has_state != 0 or has_extern != 0 or has_export != 0:
|
||||
# 含真实类型但解析失败:回退外部函数返回类型白名单
|
||||
# (FindFirstFileA/GetStdHandle → i8* HANDLE 等),避免默认 i32
|
||||
# 截断指针(vpi 缓存/AST 解析 miss 时的稳健兜底)。
|
||||
ret_ty = GenApi.infer_external_func_ret_ty(pool, fd.name)
|
||||
# 默认返回 i32
|
||||
if ret_ty is None:
|
||||
ret_ty = i32_ty
|
||||
|
||||
@@ -126,6 +126,24 @@ def resolve_typedef_or_map(pool: memhub.MemBuddy | t.CPtr,
|
||||
return None
|
||||
|
||||
|
||||
# ---------------- infer_external_func_ret_ty(委托 CallGenLib._infer_external_func_ret_ty) ----------------
|
||||
def infer_external_func_ret_ty(pool: memhub.MemBuddy | t.CPtr,
|
||||
func_name: str) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""委托到 gen.CallGenLib._infer_external_func_ret_ty(外部函数返回类型白名单)
|
||||
|
||||
vpi 注入 extern declare 时返回类型解析 miss 的兜底:FindFirstFileA/
|
||||
GetStdHandle 等 Win32 HANDLE 返回函数 → i8*,避免默认 i32/void 导致
|
||||
声明签名错误(运行期 FindFirstFileA 句柄丢失 → 文件存在性判断失效根因)。
|
||||
fatal_if_unknown=0:白名单未命中返回默认 i32(不 fail-fast,注入上下文
|
||||
无法收敛判断交给调用侧)。
|
||||
"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLib._infer_external_func_ret_ty(pool, func_name, None, 0)
|
||||
return None
|
||||
|
||||
|
||||
# ---------------- get_current_file(委托 TypeGenResolve.get_current_file) ----------------
|
||||
def get_current_file() -> str:
|
||||
"""委托到 gen.get_current_file(原 Handles 壳)"""
|
||||
|
||||
Reference in new issue
Block a user