]> 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>
Wed, 16 Feb 2022 17:39:38 +0000 (18:39 +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 c36f4aad30d214b3a1ecd8a8d45ad5e6a69ed8a0..3d4d7cff3f04bf6bc3f3f7ba7d557a85d744de33 100644 (file)
@@ -285,6 +285,7 @@ TESTS = \
        control-flow/pre-post-increment-property.vala \
        control-flow/switch.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 03aae237f982cb18d7e370bc388ea5daf066d56b..86bb92aae768a05083b4f9cf1245c053e85ef5e6 100644 (file)
@@ -968,13 +968,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));
                }