Commit 8ae4c35c by Ian Lance Taylor

compiler: Error for qualified ID as field name in struct literal.

From-SVN: r203292
parent a81169d8
...@@ -11293,7 +11293,7 @@ Field_reference_expression::do_lower(Gogo* gogo, Named_object* function, ...@@ -11293,7 +11293,7 @@ Field_reference_expression::do_lower(Gogo* gogo, Named_object* function,
} }
Expression* e = Expression::make_composite_literal(array_type, 0, false, 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); Variable* var = new Variable(array_type, e, true, false, false, loc);
...@@ -13236,9 +13236,11 @@ class Composite_literal_expression : public Parser_expression ...@@ -13236,9 +13236,11 @@ class Composite_literal_expression : public Parser_expression
{ {
public: public:
Composite_literal_expression(Type* type, int depth, bool has_keys, 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), : 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: protected:
...@@ -13256,6 +13258,7 @@ class Composite_literal_expression : public Parser_expression ...@@ -13256,6 +13258,7 @@ class Composite_literal_expression : public Parser_expression
(this->vals_ == NULL (this->vals_ == NULL
? NULL ? NULL
: this->vals_->copy()), : this->vals_->copy()),
this->all_are_names_,
this->location()); this->location());
} }
...@@ -13285,6 +13288,9 @@ class Composite_literal_expression : public Parser_expression ...@@ -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 // 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. // value. In an array initializer, a missing key will be NULL.
bool has_keys_; bool has_keys_;
// If this is true, then HAS_KEYS_ is true, and every key is a
// simple identifier.
bool all_are_names_;
}; };
// Traversal. // Traversal.
...@@ -13387,6 +13393,8 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type) ...@@ -13387,6 +13393,8 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
std::vector<Expression*> vals(field_count); std::vector<Expression*> vals(field_count);
std::vector<int>* traverse_order = new(std::vector<int>); std::vector<int>* traverse_order = new(std::vector<int>);
Expression_list::const_iterator p = this->vals_->begin(); Expression_list::const_iterator p = this->vals_->begin();
Expression* external_expr = NULL;
const Named_object* external_no = NULL;
while (p != this->vals_->end()) while (p != this->vals_->end())
{ {
Expression* name_expr = *p; Expression* name_expr = *p;
...@@ -13492,6 +13500,12 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type) ...@@ -13492,6 +13500,12 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
if (no != NULL) if (no != NULL)
{ {
if (no->package() != NULL && external_expr == NULL)
{
external_expr = name_expr;
external_no = no;
}
name = no->name(); name = no->name();
// A predefined name won't be packed. If it starts with a // 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) ...@@ -13541,6 +13555,23 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
traverse_order->push_back(index); 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; Expression_list* list = new Expression_list;
list->reserve(field_count); list->reserve(field_count);
for (size_t i = 0; i < field_count; ++i) for (size_t i = 0; i < field_count; ++i)
...@@ -13830,11 +13861,11 @@ Composite_literal_expression::do_dump_expression( ...@@ -13830,11 +13861,11 @@ Composite_literal_expression::do_dump_expression(
Expression* Expression*
Expression::make_composite_literal(Type* type, int depth, bool has_keys, Expression::make_composite_literal(Type* type, int depth, bool has_keys,
Expression_list* vals, Expression_list* vals, bool all_are_names,
Location location) Location location)
{ {
return new Composite_literal_expression(type, depth, has_keys, vals, return new Composite_literal_expression(type, depth, has_keys, vals,
location); all_are_names, location);
} }
// Return whether this expression is a composite literal. // Return whether this expression is a composite literal.
......
...@@ -291,10 +291,13 @@ class Expression ...@@ -291,10 +291,13 @@ class Expression
make_unsafe_cast(Type*, Expression*, Location); make_unsafe_cast(Type*, Expression*, Location);
// Make a composite literal. The DEPTH parameter is how far down we // 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* static Expression*
make_composite_literal(Type*, int depth, bool has_keys, Expression_list*, make_composite_literal(Type*, int depth, bool has_keys, Expression_list*,
Location); bool all_are_names, Location);
// Make a struct composite literal. // Make a struct composite literal.
static Expression* static Expression*
......
...@@ -2690,15 +2690,17 @@ Parse::composite_lit(Type* type, int depth, Location location) ...@@ -2690,15 +2690,17 @@ Parse::composite_lit(Type* type, int depth, Location location)
{ {
this->advance_token(); this->advance_token();
return Expression::make_composite_literal(type, depth, false, NULL, return Expression::make_composite_literal(type, depth, false, NULL,
location); false, location);
} }
bool has_keys = false; bool has_keys = false;
bool all_are_names = true;
Expression_list* vals = new Expression_list; Expression_list* vals = new Expression_list;
while (true) while (true)
{ {
Expression* val; Expression* val;
bool is_type_omitted = false; bool is_type_omitted = false;
bool is_name = false;
const Token* token = this->peek_token(); const Token* token = this->peek_token();
...@@ -2719,6 +2721,7 @@ Parse::composite_lit(Type* type, int depth, Location location) ...@@ -2719,6 +2721,7 @@ Parse::composite_lit(Type* type, int depth, Location location)
val = this->id_to_expression(gogo->pack_hidden_name(identifier, val = this->id_to_expression(gogo->pack_hidden_name(identifier,
is_exported), is_exported),
location); location);
is_name = true;
} }
else else
{ {
...@@ -2744,6 +2747,7 @@ Parse::composite_lit(Type* type, int depth, Location location) ...@@ -2744,6 +2747,7 @@ Parse::composite_lit(Type* type, int depth, Location location)
{ {
if (has_keys) if (has_keys)
vals->push_back(NULL); vals->push_back(NULL);
is_name = false;
} }
else else
{ {
...@@ -2790,6 +2794,9 @@ Parse::composite_lit(Type* type, int depth, Location location) ...@@ -2790,6 +2794,9 @@ Parse::composite_lit(Type* type, int depth, Location location)
vals->push_back(val); vals->push_back(val);
if (!is_name)
all_are_names = false;
if (token->is_op(OPERATOR_COMMA)) if (token->is_op(OPERATOR_COMMA))
{ {
if (this->advance_token()->is_op(OPERATOR_RCURLY)) if (this->advance_token()->is_op(OPERATOR_RCURLY))
...@@ -2830,7 +2837,7 @@ Parse::composite_lit(Type* type, int depth, Location location) ...@@ -2830,7 +2837,7 @@ Parse::composite_lit(Type* type, int depth, Location location)
} }
return Expression::make_composite_literal(type, depth, has_keys, vals, return Expression::make_composite_literal(type, depth, has_keys, vals,
location); all_are_names, location);
} }
// FunctionLit = "func" Signature Block . // FunctionLit = "func" Signature Block .
......
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