From: Rico Tzschichholz Date: Thu, 10 Feb 2022 17:07:56 +0000 (+0100) Subject: vala: Catch and throw possible inner error of lock statements X-Git-Tag: 0.48.24~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2999d0b615b3b79cc1817b891eeee7dac1c592dd;p=thirdparty%2Fvala.git vala: Catch and throw possible inner error of lock statements See 40c1dbfbfedb6c4a6b88df045eb1c2e7bdd38d93 Fixes https://gitlab.gnome.org/GNOME/vala/issues/83 --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 48d9a9b01..22039493a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -275,6 +275,7 @@ TESTS = \ control-flow/for-switch-continue.vala \ control-flow/foreach.vala \ control-flow/local-clash-with-implicit-this.vala \ + control-flow/lock-if-throw.vala \ control-flow/missing-break.test \ control-flow/missing-return.test \ control-flow/nested-conditional.vala \ diff --git a/tests/control-flow/lock-if-throw.vala b/tests/control-flow/lock-if-throw.vala new file mode 100644 index 000000000..22747c560 --- /dev/null +++ b/tests/control-flow/lock-if-throw.vala @@ -0,0 +1,24 @@ +errordomain FooError { + FAIL; +} + +class Foo { + bool manam = true; + + public bool bar () throws Error { + bool result; + + lock (manam) { + if (manam) { + throw new FooError.FAIL ("foo"); + } else { + result = true; + } + } + + return result; + } +} + +void main () { +} diff --git a/vala/valalockstatement.vala b/vala/valalockstatement.vala index c9cc96e7c..d0f9d0932 100644 --- a/vala/valalockstatement.vala +++ b/vala/valalockstatement.vala @@ -84,14 +84,26 @@ public class Vala.LockStatement : CodeNode, Statement { public override bool check (CodeContext context) { if (body != null) { - // if the statement isn't empty, it is converted into a try statement + if (!body.check (context)) { + return false; + } + // if the statement isn't empty, it is converted into a try statement var fin_body = new Block (source_reference); fin_body.add_statement (new UnlockStatement (resource, source_reference)); + var try_stmt = new TryStatement (body, fin_body, source_reference); + if (body.tree_can_fail) { + var catch_body = new Block (source_reference); + catch_body.add_statement (new ThrowStatement (new ReferenceTransferExpression (new MemberAccess.simple ("_lock_error_")), source_reference)); + var catch_clause = new CatchClause (new ErrorType (null, null), "_lock_error_", catch_body, source_reference); + catch_clause.error_type.value_owned = true; + try_stmt.add_catch_clause (catch_clause); + } + var block = new Block (source_reference); block.add_statement (new LockStatement (resource, null, source_reference)); - block.add_statement (new TryStatement (body, fin_body, source_reference)); + block.add_statement (try_stmt); var parent_block = (Block) parent_node; parent_block.replace_statement (this, block);