This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Don't look for break out of function literal


This patch to the Go frontend avoids looking for the loop associated
with a break or continue statement outside of a function literal.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

diff -r 26a980d0c8d6 go/parse.cc
--- a/go/parse.cc	Tue Jan 04 14:15:00 2011 -0800
+++ b/go/parse.cc	Tue Jan 04 14:16:34 2011 -0800
@@ -46,8 +46,8 @@
     unget_token_(Token::make_invalid_token(0)),
     unget_token_valid_(false),
     gogo_(gogo),
-    break_stack_(),
-    continue_stack_(),
+    break_stack_(NULL),
+    continue_stack_(NULL),
     iota_(0),
     enclosing_vars_()
 {
@@ -2569,12 +2569,24 @@
   if (!this->peek_token()->is_op(OPERATOR_LCURLY))
     return Expression::make_type(type, location);
 
+  Bc_stack* hold_break_stack = this->break_stack_;
+  Bc_stack* hold_continue_stack = this->continue_stack_;
+  this->break_stack_ = NULL;
+  this->continue_stack_ = NULL;
+
   Named_object* no = this->gogo_->start_function("", type, true, location);
 
   source_location end_loc = this->block();
 
   this->gogo_->finish_function(end_loc);
 
+  if (this->break_stack_ != NULL)
+    delete this->break_stack_;
+  if (this->continue_stack_ != NULL)
+    delete this->continue_stack_;
+  this->break_stack_ = hold_break_stack;
+  this->continue_stack_ = hold_continue_stack;
+
   hold_enclosing_vars.swap(this->enclosing_vars_);
 
   Expression* closure = this->create_closure(no, &hold_enclosing_vars,
@@ -4515,7 +4527,9 @@
 void
 Parse::push_break_statement(Statement* enclosing, const Label* label)
 {
-  this->break_stack_.push_back(std::make_pair(enclosing, label));
+  if (this->break_stack_ == NULL)
+    this->break_stack_ = new Bc_stack();
+  this->break_stack_->push_back(std::make_pair(enclosing, label));
 }
 
 // Push a statement on the continue stack.
@@ -4523,7 +4537,9 @@
 void
 Parse::push_continue_statement(Statement* enclosing, const Label* label)
 {
-  this->continue_stack_.push_back(std::make_pair(enclosing, label));
+  if (this->continue_stack_ == NULL)
+    this->continue_stack_ = new Bc_stack();
+  this->continue_stack_->push_back(std::make_pair(enclosing, label));
 }
 
 // Pop the break stack.
@@ -4531,7 +4547,7 @@
 void
 Parse::pop_break_statement()
 {
-  this->break_stack_.pop_back();
+  this->break_stack_->pop_back();
 }
 
 // Pop the continue stack.
@@ -4539,7 +4555,7 @@
 void
 Parse::pop_continue_statement()
 {
-  this->continue_stack_.pop_back();
+  this->continue_stack_->pop_back();
 }
 
 // Find a break or continue statement given a label name.
@@ -4547,6 +4563,8 @@
 Statement*
 Parse::find_bc_statement(const Bc_stack* bc_stack, const std::string& label)
 {
+  if (bc_stack == NULL)
+    return NULL;
   for (Bc_stack::const_reverse_iterator p = bc_stack->rbegin();
        p != bc_stack->rend();
        ++p)
@@ -4567,17 +4585,17 @@
   Statement* enclosing;
   if (!token->is_identifier())
     {
-      if (this->break_stack_.empty())
+      if (this->break_stack_ == NULL || this->break_stack_->empty())
 	{
 	  error_at(this->location(),
 		   "break statement not within for or switch or select");
 	  return;
 	}
-      enclosing = this->break_stack_.back().first;
+      enclosing = this->break_stack_->back().first;
     }
   else
     {
-      enclosing = this->find_bc_statement(&this->break_stack_,
+      enclosing = this->find_bc_statement(this->break_stack_,
 					  token->identifier());
       if (enclosing == NULL)
 	{
@@ -4621,16 +4639,16 @@
   Statement* enclosing;
   if (!token->is_identifier())
     {
-      if (this->continue_stack_.empty())
+      if (this->continue_stack_ == NULL || this->continue_stack_->empty())
 	{
 	  error_at(this->location(), "continue statement not within for");
 	  return;
 	}
-      enclosing = this->continue_stack_.back().first;
+      enclosing = this->continue_stack_->back().first;
     }
   else
     {
-      enclosing = this->find_bc_statement(&this->continue_stack_,
+      enclosing = this->find_bc_statement(this->continue_stack_,
 					  token->identifier());
       if (enclosing == NULL)
 	{
diff -r 26a980d0c8d6 go/parse.h
--- a/go/parse.h	Tue Jan 04 14:15:00 2011 -0800
+++ b/go/parse.h	Tue Jan 04 14:16:34 2011 -0800
@@ -294,9 +294,9 @@
   // The code we are generating.
   Gogo* gogo_;
   // A stack of statements for which break may be used.
-  Bc_stack break_stack_;
+  Bc_stack* break_stack_;
   // A stack of statements for which continue may be used.
-  Bc_stack continue_stack_;
+  Bc_stack* continue_stack_;
   // The current iota value.
   int iota_;
   // References from the local function to variables defined in

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]