]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
dova: Fix flow analysis of error handling in non-void methods
authorJürg Billeter <j@bitron.ch>
Thu, 17 Jun 2010 19:53:31 +0000 (21:53 +0200)
committerJürg Billeter <j@bitron.ch>
Thu, 17 Jun 2010 19:53:31 +0000 (21:53 +0200)
codegen/valaccodebasemodule.vala
codegen/valaccodemethodmodule.vala
vala/valaflowanalyzer.vala
vala/valamethod.vala
vala/valapropertyaccessor.vala

index d2f47abcedc32e76c11e10ef9a3dc6dd930ee032..5b2c101800db3157dce161935fd120292db7cc42 100644 (file)
@@ -1634,7 +1634,7 @@ public class Vala.CCodeBaseModule : CCodeModule {
 
                        if (acc.readable && !returns_real_struct) {
                                // do not declare result variable if exit block is known to be unreachable
-                               if (acc.exit_block == null || acc.exit_block.get_predecessors ().size > 0) {
+                               if (acc.return_block == null || acc.return_block.get_predecessors ().size > 0) {
                                        var cdecl = new CCodeDeclaration (acc.value_type.get_cname ());
                                        cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
                                        function.block.prepend_statement (cdecl);
index 2e30afe2ce792e53d0f28b18494796748c1f835b..180f417f57eb9ccd4f3fc87eaf5a2f18e4b6b1fd 100644 (file)
@@ -575,7 +575,7 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
                                        cinit.append (cdecl);
 
                                        // add dummy return if exit block is known to be unreachable to silence C compiler
-                                       if (m.exit_block != null && m.exit_block.get_predecessors ().size == 0) {
+                                       if (m.return_block != null && m.return_block.get_predecessors ().size == 0) {
                                                function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
                                        }
                                }
index 37fc7ea472f33b48b0100bb674bf0b7bfc7fff05..74c35f6f73e418ee733c7645443c81366e22df27 100644 (file)
@@ -30,6 +30,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                public bool is_break_target { get; set; }
                public bool is_continue_target { get; set; }
                public bool is_return_target { get; set; }
+               public bool is_exit_target { get; set; }
                public bool is_error_target { get; set; }
                public ErrorDomain? error_domain { get; set; }
                public ErrorCode? error_code { get; set; }
@@ -54,6 +55,11 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        is_return_target = true;
                }
 
+               public JumpTarget.exit_target (BasicBlock basic_block) {
+                       this.basic_block = basic_block;
+                       is_exit_target = true;
+               }
+
                public JumpTarget.error_target (BasicBlock basic_block, CatchClause catch_clause, ErrorDomain? error_domain, ErrorCode? error_code, Class? error_class) {
                        this.basic_block = basic_block;
                        this.catch_clause = catch_clause;
@@ -68,6 +74,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        is_break_target = true;
                        is_continue_target = true;
                        is_return_target = true;
+                       is_exit_target = true;
                        is_error_target = true;
                }
 
@@ -172,20 +179,24 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                }
 
                m.entry_block = new BasicBlock.entry ();
+               m.return_block = new BasicBlock ();
                m.exit_block = new BasicBlock.exit ();
 
+               m.return_block.connect (m.exit_block);
+
                if (context.profile == Profile.DOVA && !(m.return_type is VoidType)) {
                        // ensure result is defined at end of method
                        var result_ma = new MemberAccess.simple ("result", m.source_reference);
                        result_ma.symbol_reference = m.result_var;
-                       m.exit_block.add_node (result_ma);
+                       m.return_block.add_node (result_ma);
                }
 
                current_block = new BasicBlock ();
                m.entry_block.connect (current_block);
                current_block.add_node (m);
 
-               jump_stack.add (new JumpTarget.return_target (m.exit_block));
+               jump_stack.add (new JumpTarget.return_target (m.return_block));
+               jump_stack.add (new JumpTarget.exit_target (m.exit_block));
 
                m.accept_children (this);
 
@@ -199,7 +210,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                                m.error = true;
                        }
 
-                       current_block.connect (m.exit_block);
+                       current_block.connect (m.return_block);
                }
 
                analyze_body (m.entry_block);
@@ -494,19 +505,23 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                }
 
                acc.entry_block = new BasicBlock.entry ();
+               acc.return_block = new BasicBlock ();
                acc.exit_block = new BasicBlock.exit ();
 
+               acc.return_block.connect (acc.exit_block);
+
                if (context.profile == Profile.DOVA && acc.readable) {
                        // ensure result is defined at end of method
                        var result_ma = new MemberAccess.simple ("result", acc.source_reference);
                        result_ma.symbol_reference = acc.result_var;
-                       acc.exit_block.add_node (result_ma);
+                       acc.return_block.add_node (result_ma);
                }
 
                current_block = new BasicBlock ();
                acc.entry_block.connect (current_block);
 
-               jump_stack.add (new JumpTarget.return_target (acc.exit_block));
+               jump_stack.add (new JumpTarget.return_target (acc.return_block));
+               jump_stack.add (new JumpTarget.exit_target (acc.exit_block));
 
                acc.accept_children (this);
 
@@ -520,7 +535,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                                acc.error = true;
                        }
 
-                       current_block.connect (acc.exit_block);
+                       current_block.connect (acc.return_block);
                }
 
                analyze_body (acc.entry_block);
@@ -844,7 +859,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 
                                for (int i = jump_stack.size - 1; i >= 0; i--) {
                                        var jump_target = jump_stack[i];
-                                       if (jump_target.is_return_target) {
+                                       if (jump_target.is_exit_target) {
                                                current_block.connect (jump_target.basic_block);
                                                current_block = null;
                                                unreachable_reported = false;
index 60995c81e9880275170dcf7eba06fd45dfe94614..8b75efd75e6c2b0ec7c574bfcad068972294abcd 100644 (file)
@@ -55,6 +55,8 @@ public class Vala.Method : Member {
 
        public BasicBlock entry_block { get; set; }
 
+       public BasicBlock return_block { get; set; }
+
        public BasicBlock exit_block { get; set; }
 
        /**
index 0f02efb379b98cc6550255b7b6f359a210501b94..a4227d987ad1bd7450f14d1940e6cf1abf5b8ccc 100644 (file)
@@ -77,6 +77,8 @@ public class Vala.PropertyAccessor : Symbol {
 
        public BasicBlock entry_block { get; set; }
 
+       public BasicBlock return_block { get; set; }
+
        public BasicBlock exit_block { get; set; }
 
        /**