fix(flow): 循环/match 外的 break/continue 改为 fail-fast
- StmtGenDeclMixin:translate_break / translate_continue 增加 node 形参,目标块 缺失(_break_bb / _continue_bb 为 None)时 fatal_error,不再静默不发跳转 - StmtGenMixin:Break / Continue 分派传入 node(供错误定位)
This commit is contained in:
1 parent
43d25e58b9
commit
fb4175736f
2 files changed
+18
-12
No files matched your search
@@ -257,8 +257,8 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
return self.translate_nonlocal(trans, node)
|
||||
return 0
|
||||
|
||||
def translate_break(self, trans: HT.Translator*) -> int:
|
||||
"""翻译 break 语句:跳转到循环 end 块"""
|
||||
def translate_break(self, trans: HT.Translator*, node: ast.AST*) -> int:
|
||||
"""翻译 break 语句:跳转到 break 目标(循环 end / match end)"""
|
||||
builder: llvmlite.IRBuilder* = trans._cur_builder
|
||||
func: llvmlite.Function* = trans._cur_func
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
@@ -266,10 +266,13 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
if builder is None or func is None:
|
||||
return 0
|
||||
|
||||
# 发射 br 到 break 目标
|
||||
if trans._break_bb is not None:
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
|
||||
llvmlite.build_br(builder, trans._break_bb)
|
||||
# 发射 br 到 break 目标(_break_bb 由循环或 match-case 生成侧设置)
|
||||
if trans._break_bb is None:
|
||||
# fail-fast:没有循环 / match-case 时 break 无处可跳,禁止静默无效果
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
"break 只能用在循环或 match-case 体内(当前没有可跳出的目标)", "SyntaxError")
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
|
||||
llvmlite.build_br(builder, trans._break_bb)
|
||||
|
||||
# 创建死代码 BB,用于后续语句(break 后面的代码不可达)
|
||||
cnt: int = trans._label_counter
|
||||
@@ -294,7 +297,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
"fallthrough 只能用在 match-case 语句体内(语义是落到下一个 case)", "SyntaxError")
|
||||
return 0
|
||||
|
||||
def translate_continue(self, trans: HT.Translator*) -> int:
|
||||
def translate_continue(self, trans: HT.Translator*, node: ast.AST*) -> int:
|
||||
"""翻译 continue 语句:跳转到循环 cond/incr 块"""
|
||||
builder: llvmlite.IRBuilder* = trans._cur_builder
|
||||
func: llvmlite.Function* = trans._cur_func
|
||||
@@ -304,9 +307,12 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
return 0
|
||||
|
||||
# 发射 br 到 continue 目标
|
||||
if trans._continue_bb is not None:
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
|
||||
llvmlite.build_br(builder, trans._continue_bb)
|
||||
if trans._continue_bb is None:
|
||||
# fail-fast:循环之外的 continue 无处可跳,禁止静默无效果
|
||||
self.Gen.TypeGenErr.fatal_error(node,
|
||||
"continue 只能用在循环体内(当前没有可继续的循环)", "SyntaxError")
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
|
||||
llvmlite.build_br(builder, trans._continue_bb)
|
||||
|
||||
# 创建死代码 BB,用于后续语句
|
||||
cnt: int = trans._label_counter
|
||||
|
||||
@@ -87,9 +87,9 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
elif k == ast.ASTKind.Pass:
|
||||
return 0
|
||||
elif k == ast.ASTKind.Break:
|
||||
return self.translate_break(trans)
|
||||
return self.translate_break(trans, node)
|
||||
elif k == ast.ASTKind.Continue:
|
||||
return self.translate_continue(trans)
|
||||
return self.translate_continue(trans, node)
|
||||
elif k == ast.ASTKind.FallThrough:
|
||||
return self.translate_fallthrough(trans, node)
|
||||
elif k == ast.ASTKind.Match:
|
||||
|
||||
Reference in new issue
Block a user