diff mbox

Go patch committed: Fix type switch block

Message ID mcraa5cyga0.fsf@dhcp-172-18-216-180.mtv.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor Jan. 24, 2012, 8:52 p.m. UTC
In Go, in a type switch like
	switch t := 0; t := x.(type)
the two variables named 't' are in different blocks; they are not a
redefinition.  This patch implements that in gccgo.  Bootstrapped and
ran Go testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

diff -r 725daf468f17 go/parse.cc
--- a/go/parse.cc	Tue Jan 24 11:31:26 2012 -0800
+++ b/go/parse.cc	Tue Jan 24 12:49:40 2012 -0800
@@ -4057,6 +4057,7 @@ 
   Expression* switch_val = NULL;
   bool saw_send_stmt;
   Type_switch type_switch;
+  bool have_type_switch_block = false;
   if (this->simple_stat_may_start_here())
     {
       switch_val = this->simple_stat(false, &saw_send_stmt, NULL,
@@ -4099,7 +4100,14 @@ 
 							     id_loc));
 	      if (is_coloneq)
 		{
-		  // This must be a TypeSwitchGuard.
+		  // This must be a TypeSwitchGuard.  It is in a
+		  // different block from any initial SimpleStat.
+		  if (saw_simple_stat)
+		    {
+		      this->gogo_->start_block(id_loc);
+		      have_type_switch_block = true;
+		    }
+
 		  switch_val = this->simple_stat(false, &saw_send_stmt, NULL,
 						 &type_switch);
 		  if (!type_switch.found)
@@ -4142,13 +4150,23 @@ 
 	  if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
 	    this->advance_token();
 	  if (!this->peek_token()->is_op(OPERATOR_LCURLY))
-	    return;
+	    {
+	      if (have_type_switch_block)
+		this->gogo_->add_block(this->gogo_->finish_block(location),
+				       location);
+	      this->gogo_->add_block(this->gogo_->finish_block(location),
+				     location);
+	      return;
+	    }
 	  if (type_switch.found)
 	    type_switch.expr = Expression::make_error(location);
 	}
       else
 	{
 	  error_at(this->location(), "expected %<{%>");
+	  if (have_type_switch_block)
+	    this->gogo_->add_block(this->gogo_->finish_block(this->location()),
+				   location);
 	  this->gogo_->add_block(this->gogo_->finish_block(this->location()),
 				 location);
 	  return;
@@ -4165,6 +4183,10 @@ 
   if (statement != NULL)
     this->gogo_->add_statement(statement);
 
+  if (have_type_switch_block)
+    this->gogo_->add_block(this->gogo_->finish_block(this->location()),
+			   location);
+
   this->gogo_->add_block(this->gogo_->finish_block(this->location()),
 			 location);
 }