]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Fix error handling in inner expressions, fixes bug 475922
authorJürg Billeter <j@bitron.ch>
Sat, 29 Nov 2008 18:59:26 +0000 (18:59 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sat, 29 Nov 2008 18:59:26 +0000 (18:59 +0000)
2008-11-29  Jürg Billeter  <j@bitron.ch>

* vala/valamethodcall.vala:

Fix error handling in inner expressions, fixes bug 475922

svn path=/trunk/; revision=2086

ChangeLog
vala/valamethodcall.vala

index 291be4b642ec00b03d7e869c09d470aa9a93301f..ec27dc9ab176ae2a5d2ef94a45c60ad27ebd3c03 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-11-29  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valamethodcall.vala:
+
+       Fix error handling in inner expressions, fixes bug 475922
+
 2008-11-29  Jürg Billeter  <j@bitron.ch>
 
        * vala/valaaddressofexpression.vala:
index 477198c921c2774f0a7eb6e4ae9b4ef5cfdb22ee..3f8b773bef8a98f898402dc9bf8959d271a4f668 100644 (file)
@@ -391,9 +391,13 @@ public class Vala.MethodCall : Expression {
                formal_value_type = ret_type;
                value_type = formal_value_type.get_actual_type (target_object_type, this);
 
+               bool may_throw = false;
+
                if (mtype is MethodType) {
                        var m = ((MethodType) mtype).method_symbol;
                        foreach (DataType error_type in m.get_error_types ()) {
+                               may_throw = true;
+
                                // ensure we can trace back which expression may throw errors of this type
                                var call_error_type = error_type.copy ();
                                call_error_type.source_reference = source_reference;
@@ -404,6 +408,30 @@ public class Vala.MethodCall : Expression {
 
                analyzer.check_arguments (this, mtype, params, get_argument_list ());
 
+               if (may_throw) {
+                       if (parent_node is LocalVariable || parent_node is ExpressionStatement) {
+                               // simple statements, no side effects after method call
+                       } else {
+                               // store parent_node as we need to replace the expression in the old parent node later on
+                               var old_parent_node = parent_node;
+
+                               var local = new LocalVariable (value_type, get_temp_name (), null, source_reference);
+                               var decl = new DeclarationStatement (local, source_reference);
+
+                               insert_statement ((Block) analyzer.current_symbol, decl);
+
+                               var temp_access = new MemberAccess.simple (local.name, source_reference);
+                               temp_access.target_type = target_type;
+
+                               // don't set initializer earlier as this changes parent_node and parent_statement
+                               local.initializer = this;
+                               decl.check (analyzer);
+                               temp_access.check (analyzer);
+
+                               old_parent_node.replace_expression (this, temp_access);
+                       }
+               }
+
                return !error;
        }