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:
1 parent
0e8283551c
commit
daf79af1cc
1 file changed
+39
-4
@@ -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")
|
||||
|
||||
Reference in new issue
Block a user