diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-08 23:54:15 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-08 23:54:15 +0000 |
commit | 62750cd5c6a8b9ff364516c86e11bb6d1823e591 (patch) | |
tree | 8a2089703104bb2edffd3b879536df152157fa6d /gcc/go | |
parent | b6d0ea24172ec1b0dc9c16abab856a262edb07d6 (diff) | |
download | gcc-62750cd5c6a8b9ff364516c86e11bb6d1823e591.tar.gz |
compiler: Error for qualified ID as field name in struct literal.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203292 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 41 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 7 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 11 |
3 files changed, 50 insertions, 9 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 13d4c1c789a..d5e3a67625a 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -11293,7 +11293,7 @@ Field_reference_expression::do_lower(Gogo* gogo, Named_object* function, } Expression* e = Expression::make_composite_literal(array_type, 0, false, - bytes, loc); + bytes, false, loc); Variable* var = new Variable(array_type, e, true, false, false, loc); @@ -13236,9 +13236,11 @@ class Composite_literal_expression : public Parser_expression { public: Composite_literal_expression(Type* type, int depth, bool has_keys, - Expression_list* vals, Location location) + Expression_list* vals, bool all_are_names, + Location location) : Parser_expression(EXPRESSION_COMPOSITE_LITERAL, location), - type_(type), depth_(depth), vals_(vals), has_keys_(has_keys) + type_(type), depth_(depth), vals_(vals), has_keys_(has_keys), + all_are_names_(all_are_names) { } protected: @@ -13256,6 +13258,7 @@ class Composite_literal_expression : public Parser_expression (this->vals_ == NULL ? NULL : this->vals_->copy()), + this->all_are_names_, this->location()); } @@ -13285,6 +13288,9 @@ class Composite_literal_expression : public Parser_expression // If this is true, then VALS_ is a list of pairs: a key and a // value. In an array initializer, a missing key will be NULL. bool has_keys_; + // If this is true, then HAS_KEYS_ is true, and every key is a + // simple identifier. + bool all_are_names_; }; // Traversal. @@ -13387,6 +13393,8 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type) std::vector<Expression*> vals(field_count); std::vector<int>* traverse_order = new(std::vector<int>); Expression_list::const_iterator p = this->vals_->begin(); + Expression* external_expr = NULL; + const Named_object* external_no = NULL; while (p != this->vals_->end()) { Expression* name_expr = *p; @@ -13492,6 +13500,12 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type) if (no != NULL) { + if (no->package() != NULL && external_expr == NULL) + { + external_expr = name_expr; + external_no = no; + } + name = no->name(); // A predefined name won't be packed. If it starts with a @@ -13541,6 +13555,23 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type) traverse_order->push_back(index); } + if (!this->all_are_names_) + { + // This is a weird case like bug462 in the testsuite. + if (external_expr == NULL) + error_at(this->location(), "unknown field in %qs literal", + (type->named_type() != NULL + ? type->named_type()->message_name().c_str() + : "unnamed struct")); + else + error_at(external_expr->location(), "unknown field %qs in %qs", + external_no->message_name().c_str(), + (type->named_type() != NULL + ? type->named_type()->message_name().c_str() + : "unnamed struct")); + return Expression::make_error(location); + } + Expression_list* list = new Expression_list; list->reserve(field_count); for (size_t i = 0; i < field_count; ++i) @@ -13830,11 +13861,11 @@ Composite_literal_expression::do_dump_expression( Expression* Expression::make_composite_literal(Type* type, int depth, bool has_keys, - Expression_list* vals, + Expression_list* vals, bool all_are_names, Location location) { return new Composite_literal_expression(type, depth, has_keys, vals, - location); + all_are_names, location); } // Return whether this expression is a composite literal. diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index b4cca5453b0..bc7a25f766a 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -291,10 +291,13 @@ class Expression make_unsafe_cast(Type*, Expression*, Location); // Make a composite literal. The DEPTH parameter is how far down we - // are in a list of composite literals with omitted types. + // are in a list of composite literals with omitted types. HAS_KEYS + // is true if the expression list has keys alternating with values. + // ALL_ARE_NAMES is true if all the keys could be struct field + // names. static Expression* make_composite_literal(Type*, int depth, bool has_keys, Expression_list*, - Location); + bool all_are_names, Location); // Make a struct composite literal. static Expression* diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index e68f1753f87..498125bb241 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -2690,15 +2690,17 @@ Parse::composite_lit(Type* type, int depth, Location location) { this->advance_token(); return Expression::make_composite_literal(type, depth, false, NULL, - location); + false, location); } bool has_keys = false; + bool all_are_names = true; Expression_list* vals = new Expression_list; while (true) { Expression* val; bool is_type_omitted = false; + bool is_name = false; const Token* token = this->peek_token(); @@ -2719,6 +2721,7 @@ Parse::composite_lit(Type* type, int depth, Location location) val = this->id_to_expression(gogo->pack_hidden_name(identifier, is_exported), location); + is_name = true; } else { @@ -2744,6 +2747,7 @@ Parse::composite_lit(Type* type, int depth, Location location) { if (has_keys) vals->push_back(NULL); + is_name = false; } else { @@ -2790,6 +2794,9 @@ Parse::composite_lit(Type* type, int depth, Location location) vals->push_back(val); + if (!is_name) + all_are_names = false; + if (token->is_op(OPERATOR_COMMA)) { if (this->advance_token()->is_op(OPERATOR_RCURLY)) @@ -2830,7 +2837,7 @@ Parse::composite_lit(Type* type, int depth, Location location) } return Expression::make_composite_literal(type, depth, has_keys, vals, - location); + all_are_names, location); } // FunctionLit = "func" Signature Block . |