From: Jürg Billeter Date: Sat, 29 Nov 2008 18:59:26 +0000 (+0000) Subject: Fix error handling in inner expressions, fixes bug 475922 X-Git-Tag: VALA_0_5_2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e56930f139ddbbf0a3aabd484ed0aab1a296b8e;p=thirdparty%2Fvala.git Fix error handling in inner expressions, fixes bug 475922 2008-11-29 Jürg Billeter * vala/valamethodcall.vala: Fix error handling in inner expressions, fixes bug 475922 svn path=/trunk/; revision=2086 --- diff --git a/ChangeLog b/ChangeLog index 291be4b64..ec27dc9ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-11-29 Jürg Billeter + + * vala/valamethodcall.vala: + + Fix error handling in inner expressions, fixes bug 475922 + 2008-11-29 Jürg Billeter * vala/valaaddressofexpression.vala: diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala index 477198c92..3f8b773be 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -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; }