compiler: If a variable that is only set, give not used error.

From-SVN: r212876
This commit is contained in:
Ian Lance Taylor 2014-07-20 20:26:20 +00:00
parent dbb400d707
commit f67341b624
3 changed files with 22 additions and 8 deletions

View File

@ -2115,8 +2115,8 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
for (Typed_identifier_list::const_iterator p = til.begin(); for (Typed_identifier_list::const_iterator p = til.begin();
p != til.end(); p != til.end();
++p) ++p)
exprs->push_back(this->id_to_expression(p->name(), exprs->push_back(this->id_to_expression(p->name(), p->location(),
p->location())); true));
Expression_list* more_exprs = Expression_list* more_exprs =
this->expression_list(NULL, true, may_be_composite_lit); this->expression_list(NULL, true, may_be_composite_lit);
@ -2509,7 +2509,10 @@ Parse::operand(bool may_be_sink, bool* is_parenthesized)
} }
case Named_object::NAMED_OBJECT_VAR: case Named_object::NAMED_OBJECT_VAR:
case Named_object::NAMED_OBJECT_RESULT_VAR: case Named_object::NAMED_OBJECT_RESULT_VAR:
this->mark_var_used(named_object); // Any left-hand-side can be a sink, so if this can not be
// a sink, then it must be a use of the variable.
if (!may_be_sink)
this->mark_var_used(named_object);
return Expression::make_var_reference(named_object, location); return Expression::make_var_reference(named_object, location);
case Named_object::NAMED_OBJECT_SINK: case Named_object::NAMED_OBJECT_SINK:
if (may_be_sink) if (may_be_sink)
@ -2724,7 +2727,7 @@ Parse::composite_lit(Type* type, int depth, Location location)
Gogo* gogo = this->gogo_; Gogo* gogo = this->gogo_;
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, false);
is_name = true; is_name = true;
} }
else else
@ -3241,7 +3244,8 @@ Parse::call(Expression* func)
// Return an expression for a single unqualified identifier. // Return an expression for a single unqualified identifier.
Expression* Expression*
Parse::id_to_expression(const std::string& name, Location location) Parse::id_to_expression(const std::string& name, Location location,
bool is_lhs)
{ {
Named_object* in_function; Named_object* in_function;
Named_object* named_object = this->gogo_->lookup(name, &in_function); Named_object* named_object = this->gogo_->lookup(name, &in_function);
@ -3260,7 +3264,8 @@ Parse::id_to_expression(const std::string& name, Location location)
return Expression::make_const_reference(named_object, location); return Expression::make_const_reference(named_object, location);
case Named_object::NAMED_OBJECT_VAR: case Named_object::NAMED_OBJECT_VAR:
case Named_object::NAMED_OBJECT_RESULT_VAR: case Named_object::NAMED_OBJECT_RESULT_VAR:
this->mark_var_used(named_object); if (!is_lhs)
this->mark_var_used(named_object);
return Expression::make_var_reference(named_object, location); return Expression::make_var_reference(named_object, location);
case Named_object::NAMED_OBJECT_SINK: case Named_object::NAMED_OBJECT_SINK:
return Expression::make_sink(location); return Expression::make_sink(location);
@ -5025,7 +5030,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
*val = this->id_to_expression(gogo->pack_hidden_name(recv_var, *val = this->id_to_expression(gogo->pack_hidden_name(recv_var,
is_rv_exported), is_rv_exported),
recv_var_loc); recv_var_loc, true);
saw_comma = true; saw_comma = true;
} }
else else
@ -5727,6 +5732,13 @@ Parse::verify_not_sink(Expression* expr)
error_at(expr->location(), "cannot use _ as value"); error_at(expr->location(), "cannot use _ as value");
expr = Expression::make_error(expr->location()); expr = Expression::make_error(expr->location());
} }
// If this can not be a sink, and it is a variable, then we are
// using the variable, not just assigning to it.
Var_expression* ve = expr->var_expression();
if (ve != NULL)
this->mark_var_used(ve->named_object());
return expr; return expr;
} }

View File

@ -236,7 +236,7 @@ class Parse
bool* is_type_switch, bool* is_parenthesized); bool* is_type_switch, bool* is_parenthesized);
Type* reassociate_chan_direction(Channel_type*, Location); Type* reassociate_chan_direction(Channel_type*, Location);
Expression* qualified_expr(Expression*, Location); Expression* qualified_expr(Expression*, Location);
Expression* id_to_expression(const std::string&, Location); Expression* id_to_expression(const std::string&, Location, bool);
void statement(Label*); void statement(Label*);
bool statement_may_start_here(); bool statement_may_start_here();
void labeled_stmt(const std::string&, Location); void labeled_stmt(const std::string&, Location);

View File

@ -238,4 +238,6 @@ func _() {
z = (1. << s) << (1 << s) // ERROR "non-integer|type complex128" z = (1. << s) << (1 << s) // ERROR "non-integer|type complex128"
z = (1. << s) << (1. << s) // ERROR "non-integer|type complex128" z = (1. << s) << (1. << s) // ERROR "non-integer|type complex128"
z = (1.1 << s) << (1.1 << s) // ERROR "invalid|truncated|complex128" z = (1.1 << s) << (1.1 << s) // ERROR "invalid|truncated|complex128"
_, _, _ = x, y, z
} }