summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2022-02-04 09:32:11 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2022-02-16 18:39:38 +0100
commit48ccb34ced23eb690acfabf3d328effb66371325 (patch)
tree0e4900937d81440e236179abfd33428eea307175
parent8c86b4e5a124c0c913652ce76f244ea006037fce (diff)
downloadvala-48ccb34ced23eb690acfabf3d328effb66371325.tar.gz
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
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/control-flow/switch-try-finally-throw.test24
-rw-r--r--vala/valaflowanalyzer.vala5
3 files changed, 28 insertions, 2 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c36f4aad3..3d4d7cff3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
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 03aae237f..86bb92aae 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -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));
}