diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-01-04 22:18:20 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-01-04 22:18:20 +0000 |
commit | bdc4349d7eece0bc3aaf864ee3b32fe8cc3637a3 (patch) | |
tree | 251dd7336921b162feba9d89d792092af292fe1a /gcc | |
parent | 82701bd204992a7349168cddc8b35884da478be0 (diff) | |
download | gcc-bdc4349d7eece0bc3aaf864ee3b32fe8cc3637a3.zip gcc-bdc4349d7eece0bc3aaf864ee3b32fe8cc3637a3.tar.gz gcc-bdc4349d7eece0bc3aaf864ee3b32fe8cc3637a3.tar.bz2 |
Don't look outside of function literal for break or continue label.
From-SVN: r168486
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 42 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.h | 4 |
2 files changed, 32 insertions, 14 deletions
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index 9e62583..b91e2c7 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -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) { diff --git a/gcc/go/gofrontend/parse.h b/gcc/go/gofrontend/parse.h index 65f1586..6f2ac64 100644 --- a/gcc/go/gofrontend/parse.h +++ b/gcc/go/gofrontend/parse.h @@ -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 |