compiler: Error for qualified ID as field name in struct literal.
From-SVN: r203292
This commit is contained in:
parent
a81169d8fa
commit
8ae4c35c1e
3 changed files with 50 additions and 9 deletions
|
@ -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.
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -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 .
|
||||
|
|
Loading…
Add table
Reference in a new issue