compiler: Fix crash in go/defer of some builtin functions.
From-SVN: r194113
This commit is contained in:
parent
1698b1e37b
commit
27307783d8
|
@ -89,10 +89,11 @@ Expression::do_traverse(Traverse*)
|
|||
// expression is being discarded. By default, we give an error.
|
||||
// Expressions with side effects override.
|
||||
|
||||
void
|
||||
bool
|
||||
Expression::do_discarding_value()
|
||||
{
|
||||
this->unused_value_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
// This virtual function is called to export expressions. This will
|
||||
|
@ -109,7 +110,7 @@ Expression::do_export(Export*) const
|
|||
void
|
||||
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
|
||||
|
@ -789,9 +790,9 @@ class Error_expression : public Expression
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
do_discarding_value()
|
||||
{ }
|
||||
{ return true; }
|
||||
|
||||
Type*
|
||||
do_type()
|
||||
|
@ -1152,9 +1153,9 @@ class Sink_expression : public Expression
|
|||
{ }
|
||||
|
||||
protected:
|
||||
void
|
||||
bool
|
||||
do_discarding_value()
|
||||
{ }
|
||||
{ return true; }
|
||||
|
||||
Type*
|
||||
do_type();
|
||||
|
@ -5323,13 +5324,19 @@ Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const
|
|||
|
||||
// Note that the value is being discarded.
|
||||
|
||||
void
|
||||
bool
|
||||
Binary_expression::do_discarding_value()
|
||||
{
|
||||
if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND)
|
||||
this->right_->discarding_value();
|
||||
{
|
||||
this->right_->discarding_value();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
this->unused_value_error();
|
||||
{
|
||||
this->unused_value_error();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get type.
|
||||
|
@ -6528,7 +6535,7 @@ class Builtin_call_expression : public Call_expression
|
|||
bool
|
||||
do_numeric_constant_value(Numeric_constant*) const;
|
||||
|
||||
void
|
||||
bool
|
||||
do_discarding_value();
|
||||
|
||||
Type*
|
||||
|
@ -7330,7 +7337,7 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
|
|||
// discarding the value of an ordinary function call, but we do for
|
||||
// builtin functions, purely for consistency with the gc compiler.
|
||||
|
||||
void
|
||||
bool
|
||||
Builtin_call_expression::do_discarding_value()
|
||||
{
|
||||
switch (this->code_)
|
||||
|
@ -7351,7 +7358,7 @@ Builtin_call_expression::do_discarding_value()
|
|||
case BUILTIN_OFFSETOF:
|
||||
case BUILTIN_SIZEOF:
|
||||
this->unused_value_error();
|
||||
break;
|
||||
return false;
|
||||
|
||||
case BUILTIN_CLOSE:
|
||||
case BUILTIN_COPY:
|
||||
|
@ -7360,7 +7367,7 @@ Builtin_call_expression::do_discarding_value()
|
|||
case BUILTIN_PRINT:
|
||||
case BUILTIN_PRINTLN:
|
||||
case BUILTIN_RECOVER:
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -360,10 +360,11 @@ class Expression
|
|||
|
||||
// This is called if the value of this expression is being
|
||||
// discarded. This issues warnings about computed values being
|
||||
// unused.
|
||||
void
|
||||
// unused. This returns true if all is well, false if it issued an
|
||||
// error message.
|
||||
bool
|
||||
discarding_value()
|
||||
{ this->do_discarding_value(); }
|
||||
{ return this->do_discarding_value(); }
|
||||
|
||||
// Return whether this is an error expression.
|
||||
bool
|
||||
|
@ -689,7 +690,7 @@ class Expression
|
|||
{ return false; }
|
||||
|
||||
// Called by the parser if the value is being discarded.
|
||||
virtual void
|
||||
virtual bool
|
||||
do_discarding_value();
|
||||
|
||||
// Child class holds type.
|
||||
|
@ -1205,7 +1206,7 @@ class Binary_expression : public Expression
|
|||
bool
|
||||
do_numeric_constant_value(Numeric_constant*) const;
|
||||
|
||||
void
|
||||
bool
|
||||
do_discarding_value();
|
||||
|
||||
Type*
|
||||
|
@ -1373,9 +1374,9 @@ class Call_expression : public Expression
|
|||
virtual Expression*
|
||||
do_lower(Gogo*, Named_object*, Statement_inserter*, int);
|
||||
|
||||
void
|
||||
bool
|
||||
do_discarding_value()
|
||||
{ }
|
||||
{ return true; }
|
||||
|
||||
virtual Type*
|
||||
do_type();
|
||||
|
@ -2051,9 +2052,9 @@ class Receive_expression : public Expression
|
|||
do_traverse(Traverse* traverse)
|
||||
{ return Expression::traverse(&this->channel_, traverse); }
|
||||
|
||||
void
|
||||
bool
|
||||
do_discarding_value()
|
||||
{ }
|
||||
{ return true; }
|
||||
|
||||
Type*
|
||||
do_type();
|
||||
|
|
|
@ -2006,6 +2006,8 @@ Thunk_statement::do_determine_types()
|
|||
void
|
||||
Thunk_statement::do_check_types(Gogo*)
|
||||
{
|
||||
if (!this->call_->discarding_value())
|
||||
return;
|
||||
Call_expression* ce = this->call_->call_expression();
|
||||
if (ce == NULL)
|
||||
{
|
||||
|
@ -2471,11 +2473,15 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
|
|||
Expression_statement* es =
|
||||
static_cast<Expression_statement*>(call_statement);
|
||||
Call_expression* ce = es->expr()->call_expression();
|
||||
go_assert(ce != NULL);
|
||||
if (may_call_recover)
|
||||
ce->set_is_deferred();
|
||||
if (recover_arg != NULL)
|
||||
ce->set_recover_arg(recover_arg);
|
||||
if (ce == NULL)
|
||||
go_assert(saw_errors());
|
||||
else
|
||||
{
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue