vala r902 - in trunk: . tests vala



Author: juergbi
Date: Thu Jan 24 11:59:48 2008
New Revision: 902
URL: http://svn.gnome.org/viewvc/vala?rev=902&view=rev

Log:
2008-01-24  Juerg Billeter  <j bitron ch>

	* vala/valacfgbuilder.vala: build control flow graph for switch
	  statements, report missing break statements at end of switch
	  sections, fixes bug 511644

	* tests/statements-selection.vala: test switch checks


Modified:
   trunk/ChangeLog
   trunk/tests/statements-selection.vala
   trunk/vala/valacfgbuilder.vala

Modified: trunk/tests/statements-selection.vala
==============================================================================
--- trunk/tests/statements-selection.vala	(original)
+++ trunk/tests/statements-selection.vala	Thu Jan 24 11:59:48 2008
@@ -1,6 +1,16 @@
 using GLib;
 
 class Maman.Bar : Object {
+	static bool test_switch_control_flow_graph () {
+		int a = 0;
+		switch (a) {
+		case 1:
+			return false;
+		default:
+			return true;
+		}
+	}
+
 	static int main (string[] args) {
 		stdout.printf ("For Test: 1");
 
@@ -18,6 +28,8 @@
 
 		stdout.printf (" 7\n");
 
+		test_switch_control_flow_graph ();
+
 		return 0;
 	}
 }

Modified: trunk/vala/valacfgbuilder.vala
==============================================================================
--- trunk/vala/valacfgbuilder.vala	(original)
+++ trunk/vala/valacfgbuilder.vala	Thu Jan 24 11:59:48 2008
@@ -160,6 +160,54 @@
 		}
 	}
 
+	public override void visit_switch_statement (SwitchStatement! stmt) {
+		if (unreachable (stmt)) {
+			return;
+		}
+
+		var after_switch_block = new BasicBlock ();
+		breakable_stack.add (after_switch_block);
+
+		// condition
+		current_block.add_node (stmt.expression);
+		var condition_block = current_block;
+
+		bool has_default_label = false;
+
+		foreach (SwitchSection section in stmt.get_sections ()) {
+			current_block = new BasicBlock ();
+			condition_block.connect (current_block);
+			foreach (Statement stmt in section.get_statements ()) {
+				stmt.accept (this);
+			}
+
+			if (section.has_default_label ()) {
+				has_default_label = true;
+			}
+
+			if (current_block != null) {
+				// end of switch section reachable
+				// we don't allow fall-through
+
+				Report.error (section.source_reference, "missing break statement at end of switch section");
+				section.error = true;
+
+				current_block.connect (after_switch_block);
+			}
+		}
+
+		// after switch
+		// reachable?
+		if (!has_default_label || after_switch_block.get_predecessors ().size > 0) {
+			current_block = after_switch_block;
+		} else {
+			current_block = null;
+			unreachable_reported = false;
+		}
+
+		breakable_stack.remove_at (breakable_stack.size - 1);
+	}
+
 	public override void visit_while_statement (WhileStatement! stmt) {
 		if (unreachable (stmt)) {
 			return;



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