Commit bdc4349d by Ian Lance Taylor

Don't look outside of function literal for break or continue label.

From-SVN: r168486
parent 82701bd2
......@@ -46,8 +46,8 @@ Parse::Parse(Lex* lex, Gogo* gogo)
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 @@ Parse::function_lit()
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 @@ Parse::range_clause_expr(const Expression_list* vals,
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 @@ Parse::push_break_statement(Statement* enclosing, const Label* label)
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 @@ Parse::push_continue_statement(Statement* enclosing, const Label* label)
void
Parse::pop_break_statement()
{
this->break_stack_.pop_back();
this->break_stack_->pop_back();
}
// Pop the continue stack.
......@@ -4539,7 +4555,7 @@ Parse::pop_break_statement()
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 @@ Parse::pop_continue_statement()
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 @@ Parse::break_stat()
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 @@ Parse::continue_stat()
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)
{
......
......@@ -294,9 +294,9 @@ class Parse
// 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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment