]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Make sure to drop our "trap" jump target in case of an error
authorRico Tzschichholz <ricotz@ubuntu.com>
Fri, 4 Feb 2022 08:32:11 +0000 (09:32 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Fri, 4 Feb 2022 08:32:11 +0000 (09:32 +0100)
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
tests/control-flow/switch-try-finally-throw.test [new file with mode: 0644]
vala/valaflowanalyzer.vala

index 810ba76b942f4bff3ea1bf47c5be97b229a990c3..72ff16da1549dca8d3cc8737893d1585f860858a 100644 (file)
@@ -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 (file)
index 0000000..1cf0ec7
--- /dev/null
@@ -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 () {
+}
index a5a8be993f00c3121f922db79d7a511ff6c0d6d3..9c9457fd5295772217cbcf4a9b0cadda0aaf0de6 100644 (file)
@@ -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));
                }