diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-02-05 01:57:42 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-02-05 01:57:42 +0000 |
commit | 5dfb4d0f3339595881fba857ab5a4b57c681a8e3 (patch) | |
tree | 336c1452068533453093114132ffd040f836b06a /gcc/go/gofrontend/parse.cc | |
parent | 33cdac3baa9e0c8da598d5124ac9196be30a3ccb (diff) | |
download | gcc-5dfb4d0f3339595881fba857ab5a4b57c681a8e3.zip gcc-5dfb4d0f3339595881fba857ab5a4b57c681a8e3.tar.gz gcc-5dfb4d0f3339595881fba857ab5a4b57c681a8e3.tar.bz2 |
compiler: update iota handling, fix using iota in array length
CL 71750 changed the definition of how iota works. This patch updates
gccgo for the new definition.
We've been mishandling iota appearing in a type that appears in a
const expression, as in `c = len([iota]int{})`. Correct that by copying
type expressions when we copy an expression. For simplicity only copy
when it can change the size of a type, as that is the only case where
iota in a type can affect the value of a constant (I think). This is
still a bunch of changes, but almost all boilerplate.
Fixes golang/go#22341
Reviewed-on: https://go-review.googlesource.com/91475
From-SVN: r257379
Diffstat (limited to 'gcc/go/gofrontend/parse.cc')
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 40 |
1 files changed, 7 insertions, 33 deletions
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index cc3791b..4891e75 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -50,7 +50,6 @@ Parse::Parse(Lex* lex, Gogo* gogo) gogo_(gogo), break_stack_(NULL), continue_stack_(NULL), - iota_(0), enclosing_vars_() { } @@ -1407,19 +1406,20 @@ Parse::const_decl() { go_assert(this->peek_token()->is_keyword(KEYWORD_CONST)); this->advance_token(); - this->reset_iota(); + int iota = 0; Type* last_type = NULL; Expression_list* last_expr_list = NULL; if (!this->peek_token()->is_op(OPERATOR_LPAREN)) - this->const_spec(&last_type, &last_expr_list); + this->const_spec(iota, &last_type, &last_expr_list); else { this->advance_token(); while (!this->peek_token()->is_op(OPERATOR_RPAREN)) { - this->const_spec(&last_type, &last_expr_list); + this->const_spec(iota, &last_type, &last_expr_list); + ++iota; if (this->peek_token()->is_op(OPERATOR_SEMICOLON)) this->advance_token(); else if (!this->peek_token()->is_op(OPERATOR_RPAREN)) @@ -1440,7 +1440,7 @@ Parse::const_decl() // ConstSpec = IdentifierList [ [ CompleteType ] "=" ExpressionList ] . void -Parse::const_spec(Type** last_type, Expression_list** last_expr_list) +Parse::const_spec(int iota, Type** last_type, Expression_list** last_expr_list) { Typed_identifier_list til; this->identifier_list(&til); @@ -1492,7 +1492,7 @@ Parse::const_spec(Type** last_type, Expression_list** last_expr_list) pi->set_type(type); if (!Gogo::is_sink_name(pi->name())) - this->gogo_->add_constant(*pi, *pe, this->iota_value()); + this->gogo_->add_constant(*pi, *pe, iota); else { static int count; @@ -1500,15 +1500,13 @@ Parse::const_spec(Type** last_type, Expression_list** last_expr_list) snprintf(buf, sizeof buf, ".$sinkconst%d", count); ++count; Typed_identifier ti(std::string(buf), type, pi->location()); - Named_object* no = this->gogo_->add_constant(ti, *pe, this->iota_value()); + Named_object* no = this->gogo_->add_constant(ti, *pe, iota); no->const_value()->set_is_sink(); } } if (pe != expr_list->end()) go_error_at(this->location(), "too many initializers"); - this->increment_iota(); - return; } @@ -5838,30 +5836,6 @@ Parse::program() } } -// Reset the current iota value. - -void -Parse::reset_iota() -{ - this->iota_ = 0; -} - -// Return the current iota value. - -int -Parse::iota_value() -{ - return this->iota_; -} - -// Increment the current iota value. - -void -Parse::increment_iota() -{ - ++this->iota_; -} - // Skip forward to a semicolon or OP. OP will normally be // OPERATOR_RPAREN or OPERATOR_RCURLY. If we find a semicolon, move // past it and return. If we find OP, it will be the next token to |