fix(tpc): 返回 fail-fast 豁免 void 联合注解与 extern/export 声明型函数

- sprintf 误报:返回注解 t.CVoid | t.CExport(BinOp BitOr 联合)被旧判定忽略 -> 掉出末尾误报,且 [FATAL] 终止杀死 include worker -> BrokenProcessPool
- 修复:新增 _IsVoidOrDeclAnnotation 递归识别联合注解(注解中 | 表示 and):void(None/t.CVoid)+ extern/export 声明型辅助符号(State/CExport/CExtern)均豁免
- 验证:t.CVoid|t.CExport / int|t.State / t.CVoid / None -> 豁免;裸 int -> 仍 fail-fast(missing_return 用例保持命中)
This commit is contained in:
TermiNexus committed 2026-08-22 05:17:03 +08:00
1 parent 0e8283551c
commit daf79af1cc
1 file changed
+39 -4
+39 -4
View File
@@ -19,6 +19,42 @@ from lib.includes.t import CTypeRegistry
_T_STORAGE_DECORATORS = frozenset({'CExport', 'CExtern', 'CStatic', 'State', 'CInline', 'TLS'})
def _IsVoidOrDeclAnnotation(Annot: ast.AST) -> bool:
"""判断函数返回注解是否为 void 或 extern/export 声明型辅助符号。
void:None / t.CVoid,含 `|` 联合形式(注解中 `|` 表示 and),
如 `-> t.CVoid | t.CExport`(sprintf 先例)→ 掉出末尾 ret void 合法。
声明型辅助符号:t.State(extern)/ t.CExport(export)/ t.CExtern——
此类函数返回注解被改写为 `<原类型> | 辅助符号` 且 body 为空(extern 声明),
掉出末尾是正常形态,必须豁免 fail-fast。
"""
if isinstance(Annot, ast.Constant):
return Annot.value is None
if isinstance(Annot, ast.Attribute):
return getattr(Annot, 'attr', '') in ('CVoid', 'State', 'CExport', 'CExtern')
if isinstance(Annot, ast.BinOp) and isinstance(Annot.op, ast.BitOr):
return _IsVoidOrDeclAnnotation(Annot.left) or _IsVoidOrDeclAnnotation(Annot.right)
return False
def _IsVoidOrDeclAnnotation(Annot: ast.AST) -> bool:
"""判断函数返回注解是否为 void 或 extern/export 声明型辅助符号。
void:None / t.CVoid,含 `|` 联合形式(注解中 `|` 表示 and),
如 `-> t.CVoid | t.CExport`(sprintf 先例)→ 掉出末尾 ret void 合法。
声明型辅助符号:t.State(extern)/ t.CExport(export)/ t.CExtern——
此类函数返回注解被改写为 `<原类型> | 辅助符号` 且 body 为空(extern 声明),
掉出末尾是正常形态,必须豁免 fail-fast。
"""
if isinstance(Annot, ast.Constant):
return Annot.value is None
if isinstance(Annot, ast.Attribute):
return getattr(Annot, 'attr', '') in ('CVoid', 'State', 'CExport', 'CExtern')
if isinstance(Annot, ast.BinOp) and isinstance(Annot.op, ast.BitOr):
return _IsVoidOrDeclAnnotation(Annot.left) or _IsVoidOrDeclAnnotation(Annot.right)
return False
class FunctionHandle(BaseHandle):
@staticmethod
def _ExtractFuncMeta(decorator_list: list[ast.AST]) -> FuncMeta:
@@ -1852,10 +1888,9 @@ class FunctionHandle(BaseHandle):
_is_ret_or_ctrl_tail: bool = isinstance(_last_stmt, (
ast.Return, ast.If, ast.Match, ast.While, ast.For, ast.Try, ast.With))
if Node.returns is not None and not _is_ret_or_ctrl_tail:
_ret_annot_void: bool = (
isinstance(Node.returns, ast.Constant) and Node.returns.value is None) or (
isinstance(Node.returns, ast.Attribute) and getattr(Node.returns, 'attr', '') == 'CVoid')
if not _ret_annot_void:
# void(None / t.CVoid,含 | 联合)/ extern|export 声明型辅助符号
# (State / CExport / CExtern)→ 掉出合法,不 fail-fast
if not _IsVoidOrDeclAnnotation(Node.returns):
raise Exception(
f"函数 {Node.name} 声明了返回类型但函数体可能掉出末尾(缺少 return 语句);"
f"普通语句掉出末尾 + 有返回注解属于定义缺陷,请补显式 return")