From 973b1dac2655fb280f471f0402cb086cb784834b Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Thu, 18 Sep 2014 23:06:09 +0200 Subject: Fix regression introduced by ba1fa07 Hope this is the last time we touch this code. In the owned->unowned case, we want the variable to be floating: - If we assign to a local variable we get an error. - Otherwise the value is destroyed when goes out of scope. In the owned->owned case, we want to avoid copies and thus we transfer the ownership and make the variable non-floating. Fixes bug 736774 --- tests/Makefile.am | 1 + tests/control-flow/bug736774.vala | 23 +++++++++++++++++++++++ vala/valabinaryexpression.vala | 4 +++- vala/valamethodcall.vala | 1 + vala/valaobjectcreationexpression.vala | 2 +- vala/valasemanticanalyzer.vala | 1 + 6 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tests/control-flow/bug736774.vala diff --git a/tests/Makefile.am b/tests/Makefile.am index 1666826cb..4fa911560 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -82,6 +82,7 @@ TESTS = \ control-flow/bug661985.vala \ control-flow/bug665904.vala \ control-flow/bug691514.vala \ + control-flow/bug736774.vala \ enums/enums.vala \ enums/flags.vala \ enums/bug673879.vala \ diff --git a/tests/control-flow/bug736774.vala b/tests/control-flow/bug736774.vala new file mode 100644 index 000000000..34064bd00 --- /dev/null +++ b/tests/control-flow/bug736774.vala @@ -0,0 +1,23 @@ +bool destroyed = false; + +class Foo : Object { + ~Foo() { + destroyed = true; + } +} + +Foo may_fail () throws Error { + return new Foo (); +} + +void func (Foo x) { +} + +void main() { + try { + func (may_fail ()); + } catch { + } + + assert (destroyed); +} diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala index 9bb77d60f..caf3c7e8f 100644 --- a/vala/valabinaryexpression.vala +++ b/vala/valabinaryexpression.vala @@ -233,6 +233,9 @@ public class Vala.BinaryExpression : Expression { insert_statement (context.analyzer.insert_block, decl); insert_statement (context.analyzer.insert_block, if_stmt); + // create before check as local.floating might become false + var temp_access = SemanticAnalyzer.create_temp_access (local, target_type); + if (!decl.check (context)) { error = true; return false; @@ -243,7 +246,6 @@ public class Vala.BinaryExpression : Expression { return false; } - var temp_access = SemanticAnalyzer.create_temp_access (local, target_type); temp_access.check (context); parent_node.replace_expression (this, temp_access); diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala index 9c537f20e..a779293cf 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -632,6 +632,7 @@ public class Vala.MethodCall : Expression { insert_statement (context.analyzer.insert_block, decl); + // create before check as local.floating might become false var temp_access = SemanticAnalyzer.create_temp_access (local, target_type); // don't set initializer earlier as this changes parent_node and parent_statement diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index 4ff604594..e6a05bfdc 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -435,12 +435,12 @@ public class Vala.ObjectCreationExpression : Expression { insert_statement (context.analyzer.insert_block, decl); + // create before check as local.floating might become false var temp_access = SemanticAnalyzer.create_temp_access (local, target_type); // don't set initializer earlier as this changes parent_node and parent_statement local.initializer = this; decl.check (context); - // move temp variable to insert block to ensure the // variable is in the same block as the declaration // otherwise there will be scoping issues in the generated code diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 91f276914..f1d3672df 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -897,6 +897,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { temp_access = new ReferenceTransferExpression (temp_access, local.source_reference); temp_access.target_type = target_type != null ? target_type.copy () : local.variable_type.copy (); temp_access.target_type.value_owned = true; + local.floating = false; } else { temp_access.target_type = target_type != null ? target_type.copy () : null; } -- cgit v1.2.1