Commit 3f7af571 by Ian Lance Taylor

compiler: Fix crash in go/defer of some builtin functions.

From-SVN: r194114
parent 114d8843
...@@ -80,10 +80,11 @@ Expression::do_traverse(Traverse*) ...@@ -80,10 +80,11 @@ Expression::do_traverse(Traverse*)
// expression is being discarded. By default, we give an error. // expression is being discarded. By default, we give an error.
// Expressions with side effects override. // Expressions with side effects override.
void bool
Expression::do_discarding_value() Expression::do_discarding_value()
{ {
this->unused_value_error(); this->unused_value_error();
return false;
} }
// This virtual function is called to export expressions. This will // This virtual function is called to export expressions. This will
...@@ -100,7 +101,7 @@ Expression::do_export(Export*) const ...@@ -100,7 +101,7 @@ Expression::do_export(Export*) const
void void
Expression::unused_value_error() Expression::unused_value_error()
{ {
error_at(this->location(), "value computed is not used"); this->report_error(_("value computed is not used"));
} }
// Note that this expression is an error. This is called by children // Note that this expression is an error. This is called by children
...@@ -786,9 +787,9 @@ class Error_expression : public Expression ...@@ -786,9 +787,9 @@ class Error_expression : public Expression
return true; return true;
} }
void bool
do_discarding_value() do_discarding_value()
{ } { return true; }
Type* Type*
do_type() do_type()
...@@ -1149,9 +1150,9 @@ class Sink_expression : public Expression ...@@ -1149,9 +1150,9 @@ class Sink_expression : public Expression
{ } { }
protected: protected:
void bool
do_discarding_value() do_discarding_value()
{ } { return true; }
Type* Type*
do_type(); do_type();
...@@ -5326,13 +5327,16 @@ Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const ...@@ -5326,13 +5327,16 @@ Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const
// Note that the value is being discarded. // Note that the value is being discarded.
void bool
Binary_expression::do_discarding_value() Binary_expression::do_discarding_value()
{ {
if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND) if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND)
this->right_->discarding_value(); return this->right_->discarding_value();
else else
this->unused_value_error(); {
this->unused_value_error();
return false;
}
} }
// Get type. // Get type.
...@@ -6536,7 +6540,7 @@ class Builtin_call_expression : public Call_expression ...@@ -6536,7 +6540,7 @@ class Builtin_call_expression : public Call_expression
bool bool
do_numeric_constant_value(Numeric_constant*) const; do_numeric_constant_value(Numeric_constant*) const;
void bool
do_discarding_value(); do_discarding_value();
Type* Type*
...@@ -7338,7 +7342,7 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const ...@@ -7338,7 +7342,7 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
// discarding the value of an ordinary function call, but we do for // discarding the value of an ordinary function call, but we do for
// builtin functions, purely for consistency with the gc compiler. // builtin functions, purely for consistency with the gc compiler.
void bool
Builtin_call_expression::do_discarding_value() Builtin_call_expression::do_discarding_value()
{ {
switch (this->code_) switch (this->code_)
...@@ -7359,7 +7363,7 @@ Builtin_call_expression::do_discarding_value() ...@@ -7359,7 +7363,7 @@ Builtin_call_expression::do_discarding_value()
case BUILTIN_OFFSETOF: case BUILTIN_OFFSETOF:
case BUILTIN_SIZEOF: case BUILTIN_SIZEOF:
this->unused_value_error(); this->unused_value_error();
break; return false;
case BUILTIN_CLOSE: case BUILTIN_CLOSE:
case BUILTIN_COPY: case BUILTIN_COPY:
...@@ -7368,7 +7372,7 @@ Builtin_call_expression::do_discarding_value() ...@@ -7368,7 +7372,7 @@ Builtin_call_expression::do_discarding_value()
case BUILTIN_PRINT: case BUILTIN_PRINT:
case BUILTIN_PRINTLN: case BUILTIN_PRINTLN:
case BUILTIN_RECOVER: case BUILTIN_RECOVER:
break; return true;
} }
} }
......
...@@ -360,10 +360,11 @@ class Expression ...@@ -360,10 +360,11 @@ class Expression
// This is called if the value of this expression is being // This is called if the value of this expression is being
// discarded. This issues warnings about computed values being // discarded. This issues warnings about computed values being
// unused. // unused. This returns true if all is well, false if it issued an
void // error message.
bool
discarding_value() discarding_value()
{ this->do_discarding_value(); } { return this->do_discarding_value(); }
// Return whether this is an error expression. // Return whether this is an error expression.
bool bool
...@@ -689,7 +690,7 @@ class Expression ...@@ -689,7 +690,7 @@ class Expression
{ return false; } { return false; }
// Called by the parser if the value is being discarded. // Called by the parser if the value is being discarded.
virtual void virtual bool
do_discarding_value(); do_discarding_value();
// Child class holds type. // Child class holds type.
...@@ -1205,7 +1206,7 @@ class Binary_expression : public Expression ...@@ -1205,7 +1206,7 @@ class Binary_expression : public Expression
bool bool
do_numeric_constant_value(Numeric_constant*) const; do_numeric_constant_value(Numeric_constant*) const;
void bool
do_discarding_value(); do_discarding_value();
Type* Type*
...@@ -1373,9 +1374,9 @@ class Call_expression : public Expression ...@@ -1373,9 +1374,9 @@ class Call_expression : public Expression
virtual Expression* virtual Expression*
do_lower(Gogo*, Named_object*, Statement_inserter*, int); do_lower(Gogo*, Named_object*, Statement_inserter*, int);
void bool
do_discarding_value() do_discarding_value()
{ } { return true; }
virtual Type* virtual Type*
do_type(); do_type();
...@@ -2056,9 +2057,9 @@ class Receive_expression : public Expression ...@@ -2056,9 +2057,9 @@ class Receive_expression : public Expression
do_traverse(Traverse* traverse) do_traverse(Traverse* traverse)
{ return Expression::traverse(&this->channel_, traverse); } { return Expression::traverse(&this->channel_, traverse); }
void bool
do_discarding_value() do_discarding_value()
{ } { return true; }
Type* Type*
do_type(); do_type();
......
...@@ -2006,6 +2006,8 @@ Thunk_statement::do_determine_types() ...@@ -2006,6 +2006,8 @@ Thunk_statement::do_determine_types()
void void
Thunk_statement::do_check_types(Gogo*) Thunk_statement::do_check_types(Gogo*)
{ {
if (!this->call_->discarding_value())
return;
Call_expression* ce = this->call_->call_expression(); Call_expression* ce = this->call_->call_expression();
if (ce == NULL) if (ce == NULL)
{ {
...@@ -2471,11 +2473,15 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name) ...@@ -2471,11 +2473,15 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
Expression_statement* es = Expression_statement* es =
static_cast<Expression_statement*>(call_statement); static_cast<Expression_statement*>(call_statement);
Call_expression* ce = es->expr()->call_expression(); Call_expression* ce = es->expr()->call_expression();
go_assert(ce != NULL); if (ce == NULL)
if (may_call_recover) go_assert(saw_errors());
ce->set_is_deferred(); else
if (recover_arg != NULL) {
ce->set_recover_arg(recover_arg); if (may_call_recover)
ce->set_is_deferred();
if (recover_arg != NULL)
ce->set_recover_arg(recover_arg);
}
} }
// That is all the thunk has to do. // That is all the thunk has to do.
......
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