aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-04-19 09:45:55 +0200
committerRichard Biener <rguenther@suse.de>2023-04-19 14:24:10 +0200
commit210617b53eee01d0a19117f886f5cf7717aa2319 (patch)
tree4d94933d5fac35d629b6f6e538334953617746bc /gcc
parentfac24d43e68838c63bfe112c8fb63aa3df960429 (diff)
downloadgcc-210617b53eee01d0a19117f886f5cf7717aa2319.zip
gcc-210617b53eee01d0a19117f886f5cf7717aa2319.tar.gz
gcc-210617b53eee01d0a19117f886f5cf7717aa2319.tar.bz2
Transform more gmp/mpfr uses to use RAII
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/builtins.cc4
-rw-r--r--gcc/real.cc22
-rw-r--r--gcc/realmpfr.h1
-rw-r--r--gcc/system.h1
-rw-r--r--gcc/tree-ssa-loop-niter.cc29
-rw-r--r--gcc/ubsan.cc9
6 files changed, 20 insertions, 46 deletions
diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 1bfdc59..80b8b89 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 126695b..cf164e5 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 3824e62..a2b1bf6 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 65d514d..c67bc42 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 dcfba2f..adf9937 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 08c1127..e6ffea3 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;