From da77acbb1d7cfbbdcabf4a17bd66cef5d22cc686 Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Fri, 4 Feb 2022 09:32:11 +0100 Subject: [PATCH] vala: Make sure to drop our "trap" jump target in case of an error Otherwise this can result in an infinite loop in FlowAnalyzer.intersect() Improve source reference for jump out of finally block Fixes https://gitlab.gnome.org/GNOME/vala/issues/1287 --- tests/Makefile.am | 1 + .../switch-try-finally-throw.test | 24 +++++++++++++++++++ vala/valaflowanalyzer.vala | 5 ++-- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 tests/control-flow/switch-try-finally-throw.test diff --git a/tests/Makefile.am b/tests/Makefile.am index 810ba76b9..72ff16da1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -295,6 +295,7 @@ TESTS = \ control-flow/switch.vala \ control-flow/switch-enum.vala \ control-flow/switch-string.vala \ + control-flow/switch-try-finally-throw.test \ control-flow/sideeffects.vala \ control-flow/unassigned-captured-local-variable.test \ control-flow/unassigned-local-block-variable.test \ diff --git a/tests/control-flow/switch-try-finally-throw.test b/tests/control-flow/switch-try-finally-throw.test new file mode 100644 index 000000000..1cf0ec796 --- /dev/null +++ b/tests/control-flow/switch-try-finally-throw.test @@ -0,0 +1,24 @@ +Invalid Code + +errordomain FooError { + FAIL +} + +void foo () throws FooError { +} + +void bar (int i) throws Error { + switch (i) { + case 23: + try { + } finally { + foo (); + } + break; + default: + throw new FooError.FAIL ("bar"); + } +} + +void main () { +} diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala index a5a8be993..9c9457fd5 100644 --- a/vala/valaflowanalyzer.vala +++ b/vala/valaflowanalyzer.vala @@ -1009,13 +1009,14 @@ public class Vala.FlowAnalyzer : CodeVisitor { stmt.finally_body.accept (this); + jump_stack.remove_at (jump_stack.size - 1); + if (invalid_block.get_predecessors ().size > 0) { // don't allow finally blocks with e.g. return statements - Report.error (stmt.source_reference, "jump out of finally block not permitted"); + Report.error (stmt.finally_body.source_reference, "jump out of finally block not permitted"); stmt.error = true; return; } - jump_stack.remove_at (jump_stack.size - 1); jump_stack.add (new JumpTarget.finally_clause (finally_block, current_block)); } -- 2.47.2