]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Transform more gmp/mpfr uses to use RAII
authorRichard Biener <rguenther@suse.de>
Wed, 19 Apr 2023 07:45:55 +0000 (09:45 +0200)
committerRichard Biener <rguenther@suse.de>
Wed, 19 Apr 2023 12:24:10 +0000 (14:24 +0200)
The following picks up the coccinelle generated patch from Bernhard,
leaving out the fortran frontend parts and fixing up the rest.
In particular both gmp.h and mpfr.h contain macros like
  #define mpfr_inf_p(_x)      ((_x)->_mpfr_exp == __MPFR_EXP_INF)
for which I add operator-> overloads to the auto_* classes.

* system.h (auto_mpz::operator->()): New.
* realmpfr.h (auto_mpfr::operator->()): New.
* builtins.cc (do_mpfr_lgamma_r): Use auto_mpfr.
* real.cc (real_from_string): Likewise.
(dconst_e_ptr): Likewise.
(dconst_sqrt2_ptr): Likewise.
* tree-ssa-loop-niter.cc (refine_value_range_using_guard):
Use auto_mpz.
(bound_difference_of_offsetted_base): Likewise.
(number_of_iterations_ne): Likewise.
(number_of_iterations_lt_to_ne): Likewise.
* ubsan.cc: Include realmpfr.h.
(ubsan_instrument_float_cast): Use auto_mpfr.

gcc/builtins.cc
gcc/real.cc
gcc/realmpfr.h
gcc/system.h
gcc/tree-ssa-loop-niter.cc
gcc/ubsan.cc

index 1bfdc598eec530179879a479b54655bae8a88eef..80b8b89d98bd4031b0754dff1845398e17c15f9b 100644 (file)
@@ -11084,15 +11084,13 @@ do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
          const int prec = fmt->p;
          const mpfr_rnd_t rnd = fmt->round_towards_zero? MPFR_RNDZ : MPFR_RNDN;
          int inexact, sg;
-         mpfr_t m;
          tree result_lg;
 
-         mpfr_init2 (m, prec);
+         auto_mpfr m (prec);
          mpfr_from_real (m, ra, MPFR_RNDN);
          mpfr_clear_flags ();
          inexact = mpfr_lgamma (m, &sg, m, rnd);
          result_lg = do_mpfr_ckconv (m, type, inexact);
-         mpfr_clear (m);
          if (result_lg)
            {
              tree result_sg;
index 126695bf2e222a60c49784d2c22410e41b5e99a5..cf164e5e9459f1f04bf4c637e15eecb72bce3efe 100644 (file)
@@ -2131,7 +2131,6 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
     {
       /* Decimal floating point.  */
       const char *cstr = str;
-      mpfr_t m;
       bool inexact;
 
       while (*cstr == '0')
@@ -2148,21 +2147,15 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
        goto is_a_zero;
 
       /* Nonzero value, possibly overflowing or underflowing.  */
-      mpfr_init2 (m, SIGNIFICAND_BITS);
+      auto_mpfr m (SIGNIFICAND_BITS);
       inexact = mpfr_strtofr (m, str, NULL, 10, MPFR_RNDZ);
       /* The result should never be a NaN, and because the rounding is
         toward zero should never be an infinity.  */
       gcc_assert (!mpfr_nan_p (m) && !mpfr_inf_p (m));
       if (mpfr_zero_p (m) || mpfr_get_exp (m) < -MAX_EXP + 4)
-       {
-         mpfr_clear (m);
-         goto underflow;
-       }
+       goto underflow;
       else if (mpfr_get_exp (m) > MAX_EXP - 4)
-       {
-         mpfr_clear (m);
-         goto overflow;
-       }
+       goto overflow;
       else
        {
          real_from_mpfr (r, m, NULL_TREE, MPFR_RNDZ);
@@ -2173,7 +2166,6 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
          gcc_assert (r->cl == rvc_normal);
          /* Set a sticky bit if mpfr_strtofr was inexact.  */
          r->sig[0] |= inexact;
-         mpfr_clear (m);
        }
     }
 
@@ -2474,12 +2466,10 @@ dconst_e_ptr (void)
      These constants need to be given to at least 160 bits precision.  */
   if (value.cl == rvc_zero)
     {
-      mpfr_t m;
-      mpfr_init2 (m, SIGNIFICAND_BITS);
+      auto_mpfr m (SIGNIFICAND_BITS);
       mpfr_set_ui (m, 1, MPFR_RNDN);
       mpfr_exp (m, m, MPFR_RNDN);
       real_from_mpfr (&value, m, NULL_TREE, MPFR_RNDN);
-      mpfr_clear (m);
 
     }
   return &value;
@@ -2517,11 +2507,9 @@ dconst_sqrt2_ptr (void)
      These constants need to be given to at least 160 bits precision.  */
   if (value.cl == rvc_zero)
     {
-      mpfr_t m;
-      mpfr_init2 (m, SIGNIFICAND_BITS);
+      auto_mpfr m (SIGNIFICAND_BITS);
       mpfr_sqrt_ui (m, 2, MPFR_RNDN);
       real_from_mpfr (&value, m, NULL_TREE, MPFR_RNDN);
-      mpfr_clear (m);
     }
   return &value;
 }
index 3824e62da1927f28b3f37bfb3ad5483dc58e124e..a2b1bf6a2db8e4b9ddc56b556fd1bf15e7689b73 100644 (file)
@@ -32,6 +32,7 @@ public:
   ~auto_mpfr () { mpfr_clear (m_mpfr); }
 
   operator mpfr_t& () { return m_mpfr; }
+  mpfr_ptr operator-> () { return m_mpfr; }
 
   auto_mpfr (const auto_mpfr &) = delete;
   auto_mpfr &operator= (const auto_mpfr &) = delete;
index 65d514d3c0178785b96160cdc7764449bfaeea62..c67bc42863fb195c1c3b2bb1a96831b7cb3b0b38 100644 (file)
@@ -709,6 +709,7 @@ public:
   ~auto_mpz () { mpz_clear (m_mpz); }
 
   operator mpz_t& () { return m_mpz; }
+  mpz_ptr operator-> () { return m_mpz; }
 
   auto_mpz (const auto_mpz &) = delete;
   auto_mpz &operator= (const auto_mpz &) = delete;
index dcfba2fc7aec29c950f23413717958e37a2d926d..adf9937b88aa9915f4dbbabea2f8ec6740e1567b 100644 (file)
@@ -159,17 +159,13 @@ refine_value_range_using_guard (tree type, tree var,
 
       if (operand_equal_p (var, c0, 0))
        {
-         mpz_t valc1;
-
          /* Case of comparing VAR with its below/up bounds.  */
-         mpz_init (valc1);
+         auto_mpz valc1;
          wi::to_mpz (wi::to_wide (c1), valc1, TYPE_SIGN (type));
          if (mpz_cmp (valc1, below) == 0)
            cmp = GT_EXPR;
          if (mpz_cmp (valc1, up) == 0)
            cmp = LT_EXPR;
-
-         mpz_clear (valc1);
        }
       else
        {
@@ -506,7 +502,6 @@ bound_difference_of_offsetted_base (tree type, mpz_t x, mpz_t y,
 {
   int rel = mpz_cmp (x, y);
   bool may_wrap = !nowrap_type_p (type);
-  mpz_t m;
 
   /* If X == Y, then the expressions are always equal.
      If X > Y, there are the following possibilities:
@@ -529,7 +524,7 @@ bound_difference_of_offsetted_base (tree type, mpz_t x, mpz_t y,
       return;
     }
 
-  mpz_init (m);
+  auto_mpz m;
   wi::to_mpz (wi::minus_one (TYPE_PRECISION (type)), m, UNSIGNED);
   mpz_add_ui (m, m, 1);
   mpz_sub (bnds->up, x, y);
@@ -542,8 +537,6 @@ bound_difference_of_offsetted_base (tree type, mpz_t x, mpz_t y,
       else
        mpz_add (bnds->up, bnds->up, m);
     }
-
-  mpz_clear (m);
 }
 
 /* From condition C0 CMP C1 derives information regarding the
@@ -975,7 +968,6 @@ number_of_iterations_ne (class loop *loop, tree type, affine_iv *iv,
 {
   tree niter_type = unsigned_type_for (type);
   tree s, c, d, bits, assumption, tmp, bound;
-  mpz_t max;
 
   niter->control = *iv;
   niter->bound = final;
@@ -1003,12 +995,11 @@ number_of_iterations_ne (class loop *loop, tree type, affine_iv *iv,
                       fold_convert (niter_type, iv->base));
     }
 
-  mpz_init (max);
+  auto_mpz max;
   number_of_iterations_ne_max (max, iv->no_overflow, c, s, bnds,
                               exit_must_be_taken);
   niter->max = widest_int::from (wi::from_mpz (niter_type, max, false),
                                 TYPE_SIGN (niter_type));
-  mpz_clear (max);
 
   /* Compute no-overflow information for the control iv.  This can be
      proven when below two conditions are satisfied:
@@ -1155,9 +1146,8 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
   tree niter_type = TREE_TYPE (step);
   tree mod = fold_build2 (FLOOR_MOD_EXPR, niter_type, *delta, step);
   tree tmod;
-  mpz_t mmod;
   tree assumption = boolean_true_node, bound, noloop;
-  bool ret = false, fv_comp_no_overflow;
+  bool fv_comp_no_overflow;
   tree type1 = type;
   if (POINTER_TYPE_P (type))
     type1 = sizetype;
@@ -1168,7 +1158,7 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
     mod = fold_build2 (MINUS_EXPR, niter_type, step, mod);
   tmod = fold_convert (type1, mod);
 
-  mpz_init (mmod);
+  auto_mpz mmod;
   wi::to_mpz (wi::to_wide (mod), mmod, UNSIGNED);
   mpz_neg (mmod, mmod);
 
@@ -1200,7 +1190,7 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
          assumption = fold_build2 (LE_EXPR, boolean_type_node,
                                    iv1->base, bound);
          if (integer_zerop (assumption))
-           goto end;
+           return false;
        }
       if (mpz_cmp (mmod, bnds->below) < 0)
        noloop = boolean_false_node;
@@ -1226,7 +1216,7 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
          assumption = fold_build2 (GE_EXPR, boolean_type_node,
                                    iv0->base, bound);
          if (integer_zerop (assumption))
-           goto end;
+           return false;
        }
       if (mpz_cmp (mmod, bnds->below) < 0)
        noloop = boolean_false_node;
@@ -1254,10 +1244,7 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
   bounds_add (bnds, wi::to_widest (mod), type);
   *delta = fold_build2 (PLUS_EXPR, niter_type, *delta, mod);
 
-  ret = true;
-end:
-  mpz_clear (mmod);
-  return ret;
+  return true;
 }
 
 /* Add assertions to NITER that ensure that the control variable of the loop
index 08c1127c8bdbce5ea224cc4f366a14aa135d5212..e6ffea3ff8b5948fcc7c4bec66972f8fb0fc0474 100644 (file)
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfg.h"
 #include "gimple-fold.h"
 #include "varasm.h"
+#include "realmpfr.h"
 
 /* Map from a tree to a VAR_DECL tree.  */
 
@@ -1877,16 +1878,15 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
       /* For _Decimal128 up to 34 decimal digits, - sign,
         dot, e, exponent.  */
       char buf[64];
-      mpfr_t m;
       int p = REAL_MODE_FORMAT (mode)->p;
       REAL_VALUE_TYPE maxval, minval;
 
       /* Use mpfr_snprintf rounding to compute the smallest
         representable decimal number greater or equal than
         1 << (prec - !uns_p).  */
-      mpfr_init2 (m, prec + 2);
+      auto_mpfr m (prec + 2);
       mpfr_set_ui_2exp (m, 1, prec - !uns_p, MPFR_RNDN);
-      mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
+      mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, (mpfr_srcptr) m);
       decimal_real_from_string (&maxval, buf);
       max = build_real (expr_type, maxval);
 
@@ -1900,11 +1900,10 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
             (-1 << (prec - 1)) - 1.  */
          mpfr_set_si_2exp (m, -1, prec - 1, MPFR_RNDN);
          mpfr_sub_ui (m, m, 1, MPFR_RNDN);
-         mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
+         mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, (mpfr_srcptr) m);
          decimal_real_from_string (&minval, buf);
          min = build_real (expr_type, minval);
        }
-      mpfr_clear (m);
     }
   else
     return NULL_TREE;