This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Go patch committed: Don't look for break out of function literal
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Tue, 04 Jan 2011 14:17:39 -0800
- Subject: 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