Transform more gmp/mpfr uses to use RAII

Message ID 20230419093722.F218A385771D@sourceware.org
State Accepted
Headers
Series Transform more gmp/mpfr uses to use RAII |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Richard Biener April 19, 2023, 9:36 a.m. UTC
  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.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

CCed Jonathan just to make sure I'm not doing anything stupid C++ wise
here.

	* 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            |  4 +---
 gcc/real.cc                | 22 +++++-----------------
 gcc/realmpfr.h             |  1 +
 gcc/system.h               |  1 +
 gcc/tree-ssa-loop-niter.cc | 29 ++++++++---------------------
 gcc/ubsan.cc               |  9 ++++-----
 6 files changed, 20 insertions(+), 46 deletions(-)
  

Patch

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 1bfdc598eec..80b8b89d98b 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -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;
diff --git a/gcc/real.cc b/gcc/real.cc
index 126695bf2e2..cf164e5e945 100644
--- a/gcc/real.cc
+++ b/gcc/real.cc
@@ -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;
 }
diff --git a/gcc/realmpfr.h b/gcc/realmpfr.h
index 3824e62da19..a2b1bf6a2db 100644
--- a/gcc/realmpfr.h
+++ b/gcc/realmpfr.h
@@ -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;
diff --git a/gcc/system.h b/gcc/system.h
index 65d514d3c01..c67bc42863f 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -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;
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index dcfba2fc7ae..adf9937b88a 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -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
diff --git a/gcc/ubsan.cc b/gcc/ubsan.cc
index 08c1127c8bd..e6ffea3ff8b 100644
--- a/gcc/ubsan.cc
+++ b/gcc/ubsan.cc
@@ -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;