Commit 62afb87d by Ian Lance Taylor

re PR go/78763 (go1: internal compiler error: in do_get_backend, at…

re PR go/78763 (go1: internal compiler error: in do_get_backend, at go/gofrontend/expressions.cc:8352)

	PR go/78763
    compiler: call determine_types even for constant expressions
    
    We need to call determine_types even for constant expressions, since a
    constant expression may include code like unsafe.Sizeof(0).  Something
    needs to determine the type of the untyped 0, and that should be the
    determine_types pass.
    
    Implementing that triggered a compiler crash on test/const1.go because
    it permitted some erroneous constants to make it all the way to the
    backend.  Catch that case by checking whether we get a constant
    overflow error, and marking the expression invalid if we do.  This is
    a good change in any case, as previously we reported the same constant
    overflow error multiple times, and now we only report it once.
    
    Fixes GCC PR 78763.
    
    Reviewed-on: https://go-review.googlesource.com/34496

From-SVN: r243729
parent 7cdb6e4c
5eb55901861f360c2c2ff70f14a8315694934c97 e807c1deec1e7114bc4757b6193510fdae13e75f
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -3738,8 +3738,12 @@ Unary_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int) ...@@ -3738,8 +3738,12 @@ Unary_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
if (expr->numeric_constant_value(&nc)) if (expr->numeric_constant_value(&nc))
{ {
Numeric_constant result; Numeric_constant result;
if (Unary_expression::eval_constant(op, &nc, loc, &result)) bool issued_error;
if (Unary_expression::eval_constant(op, &nc, loc, &result,
&issued_error))
return result.expression(loc); return result.expression(loc);
else if (issued_error)
return Expression::make_error(this->location());
} }
} }
...@@ -3900,12 +3904,15 @@ Unary_expression::do_is_static_initializer() const ...@@ -3900,12 +3904,15 @@ Unary_expression::do_is_static_initializer() const
} }
// Apply unary opcode OP to UNC, setting NC. Return true if this // Apply unary opcode OP to UNC, setting NC. Return true if this
// could be done, false if not. Issue errors for overflow. // could be done, false if not. On overflow, issues an error and sets
// *ISSUED_ERROR.
bool bool
Unary_expression::eval_constant(Operator op, const Numeric_constant* unc, Unary_expression::eval_constant(Operator op, const Numeric_constant* unc,
Location location, Numeric_constant* nc) Location location, Numeric_constant* nc,
bool* issued_error)
{ {
*issued_error = false;
switch (op) switch (op)
{ {
case OPERATOR_PLUS: case OPERATOR_PLUS:
...@@ -4050,7 +4057,12 @@ Unary_expression::eval_constant(Operator op, const Numeric_constant* unc, ...@@ -4050,7 +4057,12 @@ Unary_expression::eval_constant(Operator op, const Numeric_constant* unc,
mpz_clear(uval); mpz_clear(uval);
mpz_clear(val); mpz_clear(val);
return nc->set_type(unc->type(), true, location); if (!nc->set_type(unc->type(), true, location))
{
*issued_error = true;
return false;
}
return true;
} }
// Return the integral constant value of a unary expression, if it has one. // Return the integral constant value of a unary expression, if it has one.
...@@ -4061,8 +4073,9 @@ Unary_expression::do_numeric_constant_value(Numeric_constant* nc) const ...@@ -4061,8 +4073,9 @@ Unary_expression::do_numeric_constant_value(Numeric_constant* nc) const
Numeric_constant unc; Numeric_constant unc;
if (!this->expr_->numeric_constant_value(&unc)) if (!this->expr_->numeric_constant_value(&unc))
return false; return false;
bool issued_error;
return Unary_expression::eval_constant(this->op_, &unc, this->location(), return Unary_expression::eval_constant(this->op_, &unc, this->location(),
nc); nc, &issued_error);
} }
// Return the type of a unary expression. // Return the type of a unary expression.
...@@ -4737,13 +4750,15 @@ Binary_expression::compare_complex(const Numeric_constant* left_nc, ...@@ -4737,13 +4750,15 @@ Binary_expression::compare_complex(const Numeric_constant* left_nc,
// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC. Return // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC. Return
// true if this could be done, false if not. Issue errors at LOCATION // true if this could be done, false if not. Issue errors at LOCATION
// as appropriate. // as appropriate, and sets *ISSUED_ERROR if it did.
bool bool
Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc, Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc,
Numeric_constant* right_nc, Numeric_constant* right_nc,
Location location, Numeric_constant* nc) Location location, Numeric_constant* nc,
bool* issued_error)
{ {
*issued_error = false;
switch (op) switch (op)
{ {
case OPERATOR_OROR: case OPERATOR_OROR:
...@@ -4792,7 +4807,11 @@ Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc, ...@@ -4792,7 +4807,11 @@ Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc,
r = Binary_expression::eval_integer(op, left_nc, right_nc, location, nc); r = Binary_expression::eval_integer(op, left_nc, right_nc, location, nc);
if (r) if (r)
{
r = nc->set_type(type, true, location); r = nc->set_type(type, true, location);
if (!r)
*issued_error = true;
}
return r; return r;
} }
...@@ -5115,9 +5134,15 @@ Binary_expression::do_lower(Gogo* gogo, Named_object*, ...@@ -5115,9 +5134,15 @@ Binary_expression::do_lower(Gogo* gogo, Named_object*,
else else
{ {
Numeric_constant nc; Numeric_constant nc;
bool issued_error;
if (!Binary_expression::eval_constant(op, &left_nc, &right_nc, if (!Binary_expression::eval_constant(op, &left_nc, &right_nc,
location, &nc)) location, &nc,
&issued_error))
{
if (issued_error)
return Expression::make_error(location);
return this; return this;
}
return nc.expression(location); return nc.expression(location);
} }
} }
...@@ -5458,8 +5483,9 @@ Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const ...@@ -5458,8 +5483,9 @@ Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const
Numeric_constant right_nc; Numeric_constant right_nc;
if (!this->right_->numeric_constant_value(&right_nc)) if (!this->right_->numeric_constant_value(&right_nc))
return false; return false;
bool issued_error;
return Binary_expression::eval_constant(this->op_, &left_nc, &right_nc, return Binary_expression::eval_constant(this->op_, &left_nc, &right_nc,
this->location(), nc); this->location(), nc, &issued_error);
} }
// Note that the value is being discarded. // Note that the value is being discarded.
...@@ -5558,7 +5584,12 @@ Binary_expression::do_determine_type(const Type_context* context) ...@@ -5558,7 +5584,12 @@ Binary_expression::do_determine_type(const Type_context* context)
Type_context subcontext(*context); Type_context subcontext(*context);
if (is_comparison) if (is_constant_expr)
{
subcontext.type = NULL;
subcontext.may_be_abstract = true;
}
else if (is_comparison)
{ {
// In a comparison, the context does not determine the types of // In a comparison, the context does not determine the types of
// the operands. // the operands.
...@@ -5600,7 +5631,6 @@ Binary_expression::do_determine_type(const Type_context* context) ...@@ -5600,7 +5631,6 @@ Binary_expression::do_determine_type(const Type_context* context)
subcontext.type = subcontext.type->make_non_abstract_type(); subcontext.type = subcontext.type->make_non_abstract_type();
} }
if (!is_constant_expr)
this->left_->determine_type(&subcontext); this->left_->determine_type(&subcontext);
if (is_shift_op) if (is_shift_op)
...@@ -5621,7 +5651,6 @@ Binary_expression::do_determine_type(const Type_context* context) ...@@ -5621,7 +5651,6 @@ Binary_expression::do_determine_type(const Type_context* context)
subcontext.may_be_abstract = false; subcontext.may_be_abstract = false;
} }
if (!is_constant_expr)
this->right_->determine_type(&subcontext); this->right_->determine_type(&subcontext);
if (is_comparison) if (is_comparison)
......
...@@ -1775,10 +1775,11 @@ class Unary_expression : public Expression ...@@ -1775,10 +1775,11 @@ class Unary_expression : public Expression
} }
// Apply unary opcode OP to UNC, setting NC. Return true if this // Apply unary opcode OP to UNC, setting NC. Return true if this
// could be done, false if not. Issue errors for overflow. // could be done, false if not. On overflow, issues an error and
// sets *ISSUED_ERROR.
static bool static bool
eval_constant(Operator op, const Numeric_constant* unc, eval_constant(Operator op, const Numeric_constant* unc,
Location, Numeric_constant* nc); Location, Numeric_constant* nc, bool *issued_error);
static Expression* static Expression*
do_import(Import*); do_import(Import*);
...@@ -1893,11 +1894,11 @@ class Binary_expression : public Expression ...@@ -1893,11 +1894,11 @@ class Binary_expression : public Expression
// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC. // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC.
// Return true if this could be done, false if not. Issue errors at // Return true if this could be done, false if not. Issue errors at
// LOCATION as appropriate. // LOCATION as appropriate, and sets *ISSUED_ERROR if it did.
static bool static bool
eval_constant(Operator op, Numeric_constant* left_nc, eval_constant(Operator op, Numeric_constant* left_nc,
Numeric_constant* right_nc, Location location, Numeric_constant* right_nc, Location location,
Numeric_constant* nc); Numeric_constant* nc, bool* issued_error);
// Compare constants LEFT_NC and RIGHT_NC according to OP, setting // Compare constants LEFT_NC and RIGHT_NC according to OP, setting
// *RESULT. Return true if this could be done, false if not. Issue // *RESULT. Return true if this could be done, false if not. Issue
......
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