* Go patch committed: mark erroneous constants as invalid
@ 2015-09-02 20:55 Ian Lance Taylor
0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2015-09-02 20:55 UTC (permalink / raw)
To: gcc-patches, gofrontend-dev
[-- Attachment #1: Type: text/plain, Size: 284 bytes --]
This patch by Chris Manghane avoids a compiler crash by marking
erroneous constants as invalid and turning them into error expressions
when seen. This fixes https://golang.org/issue/11541 . Bootstrapped
and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to
mainline.
Ian
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 7469 bytes --]
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE (revision 227395)
+++ gcc/go/gofrontend/MERGE (working copy)
@@ -1,4 +1,4 @@
-a63e173b20baa1a48470dd31a1fb1f2704b37011
+3f8feb4f905535448833a14e4f5c83f682087749
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc (revision 227395)
+++ gcc/go/gofrontend/expressions.cc (working copy)
@@ -4567,6 +4567,7 @@ Binary_expression::eval_integer(Operator
if (mpz_sizeinbase(val, 2) > 0x100000)
{
error_at(location, "constant addition overflow");
+ nc->set_invalid();
mpz_set_ui(val, 1);
}
break;
@@ -4575,6 +4576,7 @@ Binary_expression::eval_integer(Operator
if (mpz_sizeinbase(val, 2) > 0x100000)
{
error_at(location, "constant subtraction overflow");
+ nc->set_invalid();
mpz_set_ui(val, 1);
}
break;
@@ -4589,6 +4591,7 @@ Binary_expression::eval_integer(Operator
if (mpz_sizeinbase(val, 2) > 0x100000)
{
error_at(location, "constant multiplication overflow");
+ nc->set_invalid();
mpz_set_ui(val, 1);
}
break;
@@ -4598,6 +4601,7 @@ Binary_expression::eval_integer(Operator
else
{
error_at(location, "division by zero");
+ nc->set_invalid();
mpz_set_ui(val, 0);
}
break;
@@ -4607,6 +4611,7 @@ Binary_expression::eval_integer(Operator
else
{
error_at(location, "division by zero");
+ nc->set_invalid();
mpz_set_ui(val, 0);
}
break;
@@ -4618,6 +4623,7 @@ Binary_expression::eval_integer(Operator
else
{
error_at(location, "shift count overflow");
+ nc->set_invalid();
mpz_set_ui(val, 1);
}
break;
@@ -4629,6 +4635,7 @@ Binary_expression::eval_integer(Operator
if (mpz_cmp_ui(right_val, shift) != 0)
{
error_at(location, "shift count overflow");
+ nc->set_invalid();
mpz_set_ui(val, 1);
}
else
@@ -4723,6 +4730,7 @@ Binary_expression::eval_float(Operator o
else
{
error_at(location, "division by zero");
+ nc->set_invalid();
mpfr_set_ui(val, 0, GMP_RNDN);
}
break;
@@ -4787,6 +4795,7 @@ Binary_expression::eval_complex(Operator
if (mpc_cmp_si(right_val, 0) == 0)
{
error_at(location, "division by zero");
+ nc->set_invalid();
mpc_set_ui(val, 0, MPC_RNDNN);
break;
}
@@ -4849,7 +4858,14 @@ Binary_expression::do_lower(Gogo* gogo,
Numeric_constant nc;
if (!Binary_expression::eval_constant(op, &left_nc, &right_nc,
location, &nc))
- return this;
+ {
+ if (nc.is_invalid())
+ {
+ go_assert(saw_errors());
+ return Expression::make_error(location);
+ }
+ return this;
+ }
return nc.expression(location);
}
}
@@ -15189,7 +15205,7 @@ Numeric_constant::set_type(Type* type, b
bool
Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
- Location location) const
+ Location location)
{
mpz_t val;
switch (this->classification_)
@@ -15203,7 +15219,11 @@ Numeric_constant::check_int_type(Integer
if (!mpfr_integer_p(this->u_.float_val))
{
if (issue_error)
- error_at(location, "floating point constant truncated to integer");
+ {
+ error_at(location,
+ "floating point constant truncated to integer");
+ this->set_invalid();
+ }
return false;
}
mpz_init(val);
@@ -15215,7 +15235,10 @@ Numeric_constant::check_int_type(Integer
|| !mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
{
if (issue_error)
- error_at(location, "complex constant truncated to integer");
+ {
+ error_at(location, "complex constant truncated to integer");
+ this->set_invalid();
+ }
return false;
}
mpz_init(val);
@@ -15253,7 +15276,10 @@ Numeric_constant::check_int_type(Integer
}
if (!ret && issue_error)
- error_at(location, "integer constant overflow");
+ {
+ error_at(location, "integer constant overflow");
+ this->set_invalid();
+ }
return ret;
}
@@ -15281,7 +15307,10 @@ Numeric_constant::check_float_type(Float
if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
{
if (issue_error)
- error_at(location, "complex constant truncated to float");
+ {
+ this->set_invalid();
+ error_at(location, "complex constant truncated to float");
+ }
return false;
}
mpfr_init_set(val, mpc_realref(this->u_.complex_val), GMP_RNDN);
@@ -15344,7 +15373,10 @@ Numeric_constant::check_float_type(Float
mpfr_clear(val);
if (!ret && issue_error)
- error_at(location, "floating point constant overflow");
+ {
+ error_at(location, "floating point constant overflow");
+ this->set_invalid();
+ }
return ret;
}
@@ -15399,7 +15431,10 @@ Numeric_constant::check_complex_type(Com
&& mpfr_get_exp(mpc_realref(val)) > max_exp)
{
if (issue_error)
- error_at(location, "complex real part overflow");
+ {
+ error_at(location, "complex real part overflow");
+ this->set_invalid();
+ }
ret = false;
}
@@ -15409,7 +15444,10 @@ Numeric_constant::check_complex_type(Com
&& mpfr_get_exp(mpc_imagref(val)) > max_exp)
{
if (issue_error)
- error_at(location, "complex imaginary part overflow");
+ {
+ error_at(location, "complex imaginary part overflow");
+ this->set_invalid();
+ }
ret = false;
}
@@ -15455,6 +15493,9 @@ Numeric_constant::expression(Location lo
return Expression::make_float(&this->u_.float_val, this->type_, loc);
case NC_COMPLEX:
return Expression::make_complex(&this->u_.complex_val, this->type_, loc);
+ case NC_INVALID:
+ go_assert(saw_errors());
+ return Expression::make_error(loc);
default:
go_unreachable();
}
Index: gcc/go/gofrontend/expressions.h
===================================================================
--- gcc/go/gofrontend/expressions.h (revision 227299)
+++ gcc/go/gofrontend/expressions.h (working copy)
@@ -3460,6 +3460,11 @@ class Numeric_constant
void
set_complex(Type*, const mpc_t);
+ // Mark numeric constant as invalid.
+ void
+ set_invalid()
+ { this->classification_ = NC_INVALID; }
+
// Classifiers.
bool
is_int() const
@@ -3477,6 +3482,10 @@ class Numeric_constant
is_complex() const
{ return this->classification_ == Numeric_constant::NC_COMPLEX; }
+ bool
+ is_invalid() const
+ { return this->classification_ == Numeric_constant::NC_INVALID; }
+
// Value retrievers. These will initialize the values as well as
// set them. GET_INT is only valid if IS_INT returns true, and
// likewise respectively.
@@ -3554,7 +3563,7 @@ class Numeric_constant
mpfr_to_unsigned_long(const mpfr_t fval, unsigned long *val) const;
bool
- check_int_type(Integer_type*, bool, Location) const;
+ check_int_type(Integer_type*, bool, Location);
bool
check_float_type(Float_type*, bool, Location);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2015-09-02 20:52 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-02 20:55 Go patch committed: mark erroneous constants as invalid Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).