compiler: Mark erroneous constants as invalid.
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 2 Sep 2015 20:52:42 +0000 (20:52 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 2 Sep 2015 20:52:42 +0000 (20:52 +0000)
    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
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h

index 5fcf1bd796109ad2691b4be66ca99431f05c0bcf..f74d2ca565b31d5f9b17f39658458ba1a647ae8b 100644 (file)
@@ -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 1df9f326561a9bbcec0de2c1deac57b9aa696290..5abfb27b3f1c8b6dd6057e7a0060683e2b2405c6 100644 (file)
@@ -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();
     }
index 5358b021339da740803023acfbdeafe9eb40895d..3e3950985cb623cba588047dd9759493c7822aaa 100644 (file)
@@ -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);