From: Jürg Billeter Date: Thu, 21 Oct 2010 08:08:04 +0000 (+0200) Subject: Support return statements in constructors and destructors X-Git-Tag: 0.11.1~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ef5b2ca13572bef194df3af65f4cced13ef4be7;p=thirdparty%2Fvala.git Support return statements in constructors and destructors Fixes bug 573763. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index a1bc6998c..561f535dc 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -121,10 +121,36 @@ public class Vala.CCodeBaseModule : CodeGenerator { } } + if (is_in_constructor () || is_in_destructor ()) { + return void_type; + } + return null; } } + bool is_in_constructor () { + var sym = current_symbol; + while (sym != null) { + if (sym is Constructor) { + return true; + } + sym = sym.parent_symbol; + } + return false; + } + + bool is_in_destructor () { + var sym = current_symbol; + while (sym != null) { + if (sym is Destructor) { + return true; + } + sym = sym.parent_symbol; + } + return false; + } + public Block? current_closure_block { get { return next_closure_block (current_symbol); @@ -3326,7 +3352,13 @@ public class Vala.CCodeBaseModule : CodeGenerator { } } - if (current_method is CreationMethod) { + if (is_in_constructor ()) { + ccode.add_return (new CCodeIdentifier ("obj")); + } else if (is_in_destructor ()) { + // do not call return as member cleanup and chain up to base finalizer + // stil need to be executed + ccode.add_goto ("_return"); + } else if (current_method is CreationMethod) { ccode.add_return (new CCodeIdentifier ("self")); } else if (current_method != null && current_method.coroutine) { } else if (current_return_type is VoidType || current_return_type.is_real_non_null_struct_type ()) { diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index e5d0bc423..61c61f117 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -1653,6 +1653,9 @@ public class Vala.GTypeModule : GErrorModule { if (current_method_inner_error) { ccode.add_declaration ("GError *", new CCodeVariableDeclarator.zero ("_inner_error_", new CCodeConstant ("NULL"))); } + + // support return statements in destructors + ccode.add_label ("_return"); } pop_context (); diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index c6b718b90..22d394f48 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -123,6 +123,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } } + if (is_in_constructor () || is_in_destructor ()) { + return void_type; + } + return null; } } @@ -885,4 +889,15 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } return false; } + + public bool is_in_destructor () { + var sym = current_symbol; + while (sym != null) { + if (sym is Destructor) { + return true; + } + sym = sym.parent_symbol; + } + return false; + } }