From db3015e9e3b5bd8bae0cf6c629f4f8333a01f855 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 2 Sep 2015 20:52:42 +0000 Subject: [PATCH] compiler: Mark erroneous constants as invalid. When the compiler failed to evaluate a numeric constant because because it was erroneous, there was no way for parent nodes to discover the error and lower themselves into error nodes. This patch now uses the NC_INVALID enumerator to mark numeric constants with a known, reported error. Fixes golang/go#11541. Reviewed-on: https://go-review.googlesource.com/13904 From-SVN: r227420 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 59 +++++++++++++++++++++++++++----- gcc/go/gofrontend/expressions.h | 11 +++++- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 5fcf1bd7961..f74d2ca565b 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 1df9f326561..5abfb27b3f1 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -4567,6 +4567,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc, 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 op, const Numeric_constant* left_nc, 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 op, const Numeric_constant* left_nc, 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 op, const Numeric_constant* left_nc, 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 op, const Numeric_constant* left_nc, 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 op, const Numeric_constant* left_nc, 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 op, const Numeric_constant* left_nc, 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 op, const Numeric_constant* left_nc, 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 op, const Numeric_constant* left_nc, 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, Named_object*, 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, bool issue_error, Location loc) 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_type* type, bool issue_error, 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_type* type, bool issue_error, || !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_type* type, bool issue_error, } 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_type* type, bool issue_error, 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_type* type, bool issue_error, 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(Complex_type* type, bool issue_error, && 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(Complex_type* type, bool issue_error, && 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 loc) const 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(); } diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 5358b021339..3e3950985cb 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -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); -- 2.30.2