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) ...@@ -46,8 +46,8 @@ Parse::Parse(Lex* lex, Gogo* gogo)
unget_token_(Token::make_invalid_token(0)), unget_token_(Token::make_invalid_token(0)),
unget_token_valid_(false), unget_token_valid_(false),
gogo_(gogo), gogo_(gogo),
break_stack_(), break_stack_(NULL),
continue_stack_(), continue_stack_(NULL),
iota_(0), iota_(0),
enclosing_vars_() enclosing_vars_()
{ {
...@@ -2569,12 +2569,24 @@ Parse::function_lit() ...@@ -2569,12 +2569,24 @@ Parse::function_lit()
if (!this->peek_token()->is_op(OPERATOR_LCURLY)) if (!this->peek_token()->is_op(OPERATOR_LCURLY))
return Expression::make_type(type, location); 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); Named_object* no = this->gogo_->start_function("", type, true, location);
source_location end_loc = this->block(); source_location end_loc = this->block();
this->gogo_->finish_function(end_loc); 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_); hold_enclosing_vars.swap(this->enclosing_vars_);
Expression* closure = this->create_closure(no, &hold_enclosing_vars, Expression* closure = this->create_closure(no, &hold_enclosing_vars,
...@@ -4515,7 +4527,9 @@ Parse::range_clause_expr(const Expression_list* vals, ...@@ -4515,7 +4527,9 @@ Parse::range_clause_expr(const Expression_list* vals,
void void
Parse::push_break_statement(Statement* enclosing, const Label* label) 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. // Push a statement on the continue stack.
...@@ -4523,7 +4537,9 @@ Parse::push_break_statement(Statement* enclosing, const Label* label) ...@@ -4523,7 +4537,9 @@ Parse::push_break_statement(Statement* enclosing, const Label* label)
void void
Parse::push_continue_statement(Statement* enclosing, const Label* label) 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. // Pop the break stack.
...@@ -4531,7 +4547,7 @@ Parse::push_continue_statement(Statement* enclosing, const Label* label) ...@@ -4531,7 +4547,7 @@ Parse::push_continue_statement(Statement* enclosing, const Label* label)
void void
Parse::pop_break_statement() Parse::pop_break_statement()
{ {
this->break_stack_.pop_back(); this->break_stack_->pop_back();
} }
// Pop the continue stack. // Pop the continue stack.
...@@ -4539,7 +4555,7 @@ Parse::pop_break_statement() ...@@ -4539,7 +4555,7 @@ Parse::pop_break_statement()
void void
Parse::pop_continue_statement() Parse::pop_continue_statement()
{ {
this->continue_stack_.pop_back(); this->continue_stack_->pop_back();
} }
// Find a break or continue statement given a label name. // Find a break or continue statement given a label name.
...@@ -4547,6 +4563,8 @@ Parse::pop_continue_statement() ...@@ -4547,6 +4563,8 @@ Parse::pop_continue_statement()
Statement* Statement*
Parse::find_bc_statement(const Bc_stack* bc_stack, const std::string& label) 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(); for (Bc_stack::const_reverse_iterator p = bc_stack->rbegin();
p != bc_stack->rend(); p != bc_stack->rend();
++p) ++p)
...@@ -4567,17 +4585,17 @@ Parse::break_stat() ...@@ -4567,17 +4585,17 @@ Parse::break_stat()
Statement* enclosing; Statement* enclosing;
if (!token->is_identifier()) if (!token->is_identifier())
{ {
if (this->break_stack_.empty()) if (this->break_stack_ == NULL || this->break_stack_->empty())
{ {
error_at(this->location(), error_at(this->location(),
"break statement not within for or switch or select"); "break statement not within for or switch or select");
return; return;
} }
enclosing = this->break_stack_.back().first; enclosing = this->break_stack_->back().first;
} }
else else
{ {
enclosing = this->find_bc_statement(&this->break_stack_, enclosing = this->find_bc_statement(this->break_stack_,
token->identifier()); token->identifier());
if (enclosing == NULL) if (enclosing == NULL)
{ {
...@@ -4621,16 +4639,16 @@ Parse::continue_stat() ...@@ -4621,16 +4639,16 @@ Parse::continue_stat()
Statement* enclosing; Statement* enclosing;
if (!token->is_identifier()) 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"); error_at(this->location(), "continue statement not within for");
return; return;
} }
enclosing = this->continue_stack_.back().first; enclosing = this->continue_stack_->back().first;
} }
else else
{ {
enclosing = this->find_bc_statement(&this->continue_stack_, enclosing = this->find_bc_statement(this->continue_stack_,
token->identifier()); token->identifier());
if (enclosing == NULL) if (enclosing == NULL)
{ {
......
...@@ -294,9 +294,9 @@ class Parse ...@@ -294,9 +294,9 @@ class Parse
// The code we are generating. // The code we are generating.
Gogo* gogo_; Gogo* gogo_;
// A stack of statements for which break may be used. // 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. // A stack of statements for which continue may be used.
Bc_stack continue_stack_; Bc_stack* continue_stack_;
// The current iota value. // The current iota value.
int iota_; int iota_;
// References from the local function to variables defined in // 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