[vala] dova: Fix flow analysis of error handling in non-void methods



commit 9fbe219b715326a9a77b29636d542591cf16f3b0
Author: Jürg Billeter <j bitron ch>
Date:   Thu Jun 17 21:53:31 2010 +0200

    dova: Fix flow analysis of error handling in non-void methods

 codegen/valaccodebasemodule.vala   |    2 +-
 codegen/valaccodemethodmodule.vala |    2 +-
 vala/valaflowanalyzer.vala         |   29 ++++++++++++++++++++++-------
 vala/valamethod.vala               |    2 ++
 vala/valapropertyaccessor.vala     |    2 ++
 5 files changed, 28 insertions(+), 9 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index d2f47ab..5b2c101 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -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);
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 2e30afe..180f417 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -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")));
 					}
 				}
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index 37fc7ea..74c35f6 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -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;
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 60995c8..8b75efd 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -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; }
 
 	/**
diff --git a/vala/valapropertyaccessor.vala b/vala/valapropertyaccessor.vala
index 0f02efb..a4227d9 100644
--- a/vala/valapropertyaccessor.vala
+++ b/vala/valapropertyaccessor.vala
@@ -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; }
 
 	/**



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]