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();
p != til.end();
++p)
exprs->push_back(this->id_to_expression(p->name(),
p->location()));
exprs->push_back(this->id_to_expression(p->name(), p->location(),
true));
Expression_list* more_exprs =
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_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);
case Named_object::NAMED_OBJECT_SINK:
if (may_be_sink)
@ -2724,7 +2727,7 @@ Parse::composite_lit(Type* type, int depth, Location location)
Gogo* gogo = this->gogo_;
val = this->id_to_expression(gogo->pack_hidden_name(identifier,
is_exported),
location);
location, false);
is_name = true;
}
else
@ -3241,7 +3244,8 @@ Parse::call(Expression* func)
// Return an expression for a single unqualified identifier.
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* 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);
case Named_object::NAMED_OBJECT_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);
case Named_object::NAMED_OBJECT_SINK:
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,
is_rv_exported),
recv_var_loc);
recv_var_loc, true);
saw_comma = true;
}
else
@ -5727,6 +5732,13 @@ Parse::verify_not_sink(Expression* expr)
error_at(expr->location(), "cannot use _ as value");
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;
}

View File

@ -236,7 +236,7 @@ class Parse
bool* is_type_switch, bool* is_parenthesized);
Type* reassociate_chan_direction(Channel_type*, 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*);
bool statement_may_start_here();
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.1 << s) << (1.1 << s) // ERROR "invalid|truncated|complex128"
_, _, _ = x, y, z
}