On Mon, 6 Mar 2023 11:29:30 +0000 (UTC)
Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> wrote:

> On Mon, 6 Mar 2023, Jakub Jelinek wrote:
> 
> > On Mon, Mar 06, 2023 at 11:01:18AM +0000, Richard Biener wrote:  
> > > +  auto_mpfr &operator=(const auto_mpfr &) = delete;
> > > +  auto_mpz &operator=(const auto_mpz &) = delete;  
> > 
> > Just formatting nit, space before (.
> > 
> > Looks like nice improvement and thanks Jonathan for the suggestions ;)  
> 
> Good, I've queued it for stage1 unless fortran folks want to pick it
> up earlier for the purpose of fixing leaks.

You did not Cc the fortran list though, not sure if Tobias is aware of
this possibility.

While it's a nice idea, there have been resentments towards (visible)
C++ in the fortran frontend and especially the library, i think.
I do not know if this has changed in the meantime.

PS: not sure about libgfortran/intrinsics/trigd.inc
FTYPE s
in #ifdef SIND_SMALL_LITERAL
when this is true:
if (mpfr_cmp_ld (ax, SIND_SMALL_LITERAL) < 0)
ISTM we leak s in the return x;

This seems to happen both in SIND and TAND, from the looks.

PPS: without handling (mpfr|mpz)_clears proper, hence missing quite
some potential spots, i guess one could potentially discuss at least
$ git diff | diffstat -ulp1
gcc/builtins.cc
gcc/fold-const-call.cc
gcc/fortran/arith.cc
gcc/fortran/array.cc
gcc/fortran/check.cc
gcc/fortran/data.cc
gcc/fortran/dependency.cc
gcc/fortran/expr.cc
gcc/fortran/resolve.cc
gcc/fortran/simplify.cc
gcc/fortran/target-memory.cc
gcc/fortran/trans-array.cc
gcc/fortran/trans-intrinsic.cc
gcc/real.cc
gcc/rust/backend/rust-compile-expr.cc
gcc/tree-ssa-loop-niter.cc
gcc/ubsan.cc

See the spots highlighted in the attached patch, which i did not try to
compile. I did not filter out the files you patched already, nor
externally maintained files like rust (which seems to leak fval and
ival not only on errors, from a quick look).

That was from
find ./ \( -name "*.c[cp]" -o -name "*.[ch]" -o -name "*.inc" \) -a \( ! -path 
"./gcc/testsuite/*" -a ! -path "./gcc/contrib/*" \) -exec spatch --sp-file 
~/coccinelle/auto_mpfrz.2.cocci --in-place {} \;

thanks,
// mpz and mpfr -> auto_\1
// Remember to s/= [[:space:]]*XXXZXXX//g
// to get rid of the disguise-in-c hack
// TODO: properly handle (mpfr|mpz)_clears
@ mpfr_1 @
typedef mpfr_t;
identifier i;
@@
- mpfr_t i;
+ auto_mpfr i;
...
- mpfr_init (i);
...
(
- mpfr_clear (i);
|
mpfr_clears (
 ...,
- i,
 ...
 );
)

@ mpfr_2 @
typedef mpfr_t;
identifier i;
expression prec;
@@
- mpfr_t i;
+ auto_mpfr i = XXXZXXX(prec);
...
- mpfr_init2 (i, prec);
...
(
- mpfr_clear (i);
|
mpfr_clears (
 ...,
- i,
 ...
 );
)

@ mpfr_3 @
@@
- mpfr_clears(NULL);

/// mpz ///////////////////////////////////////////////////

@ mpz_1 @
typedef mpz_t;
identifier i;
@@
- mpz_t i;
+ auto_mpz i;
...
- mpz_init (i);
...
(
- mpz_clear (i);
|
mpz_clears (
 ...,
- i,
 ...
 );
)

@ mpz_2 @
typedef mpz_t;
identifier i;
expression prec;
@@
- mpz_t i;
+ auto_mpz i = XXXZXXX(prec);
...
- mpz_init2 (i, prec);
...
(
- mpz_clear (i);
|
mpz_clears (
 ...,
- i,
 ...
 );
)

@ mpz_3 @
@@
- mpz_clears(NULL);

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 4d467c8c5c1..9be0949aa1d 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -11064,15 +11064,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;
+         auto_mpfr m (prec);
          tree result_lg;
 
-         mpfr_init2 (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/fold-const-call.cc b/gcc/fold-const-call.cc
index 43819c1f984..900c4069ddb 100644
--- a/gcc/fold-const-call.cc
+++ b/gcc/fold-const-call.cc
@@ -130,14 +130,13 @@ do_mpfr_arg1 (real_value *result,
 
   int prec = format->p;
   mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
-  mpfr_t m;
+  auto_mpfr m (prec);
 
-  mpfr_init2 (m, prec);
+  
   mpfr_from_real (m, arg, MPFR_RNDN);
   mpfr_clear_flags ();
   bool inexact = func (m, m, rnd);
   bool ok = do_mpfr_ckconv (result, m, inexact, format);
-  mpfr_clear (m);
 
   return ok;
 }
@@ -224,14 +223,13 @@ do_mpfr_arg2 (real_value *result,
 
   int prec = format->p;
   mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
-  mpfr_t m;
+  auto_mpfr m (prec);
 
-  mpfr_init2 (m, prec);
+  
   mpfr_from_real (m, arg1, MPFR_RNDN);
   mpfr_clear_flags ();
   bool inexact = func (m, arg0.to_shwi (), m, rnd);
   bool ok = do_mpfr_ckconv (result, m, inexact, format);
-  mpfr_clear (m);
 
   return ok;
 }
diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc
index d0d1c0b03d2..5b14a833d9a 100644
--- a/gcc/fortran/arith.cc
+++ b/gcc/fortran/arith.cc
@@ -329,13 +329,12 @@ static arith
 gfc_check_real_range (mpfr_t p, int kind)
 {
   arith retval;
-  mpfr_t q;
+  auto_mpfr q;
   int i;
 
   i = gfc_validate_kind (BT_REAL, kind, false);
 
   gfc_set_model (p);
-  mpfr_init (q);
   mpfr_abs (q, p, GFC_RND_MODE);
 
   retval = ARITH_OK;
@@ -352,7 +351,6 @@ gfc_check_real_range (mpfr_t p, int kind)
     }
   else if (mpfr_sgn (q) == 0)
     {
-      mpfr_clear (q);
       return retval;
     }
   else if (mpfr_cmp (q, gfc_real_kinds[i].huge) > 0)
@@ -405,8 +403,6 @@ gfc_check_real_range (mpfr_t p, int kind)
        mpfr_set (p, q, MPFR_RNDN);
     }
 
-  mpfr_clear (q);
-
   return retval;
 }
 
@@ -769,8 +765,8 @@ gfc_arith_divide (gfc_expr *op1, gfc_expr *op2, gfc_expr 
**resultp)
 
       if (warn_integer_division)
        {
-         mpz_t r;
-         mpz_init (r);
+         auto_mpz r;
+         
          mpz_tdiv_qr (result->value.integer, r, op1->value.integer,
                       op2->value.integer);
 
@@ -783,7 +779,6 @@ gfc_arith_divide (gfc_expr *op1, gfc_expr *op2, gfc_expr 
**resultp)
                               &op1->where);
              free (p);
            }
-         mpz_clear (r);
        }
       else
        mpz_tdiv_q (result->value.integer, op1->value.integer,
@@ -2093,12 +2088,11 @@ static bool
 wprecision_int_real (mpz_t n, mpfr_t r)
 {
   bool ret;
-  mpz_t i;
-  mpz_init (i);
+  auto_mpz i;
+  
   mpfr_get_z (i, r, GFC_RND_MODE);
   mpz_sub (i, i, n);
   ret = mpz_cmp_si (i, 0) != 0;
-  mpz_clear (i);
   return ret;
 }
 
@@ -2425,9 +2419,9 @@ gfc_complex2int (gfc_expr *src, int kind)
        }
 
       else {
-       mpfr_t f;
+       auto_mpfr f;
 
-       mpfr_init (f);
+       
        mpfr_frac (f, src->value.real, GFC_RND_MODE);
        if (mpfr_cmp_si (f, 0) != 0)
          {
@@ -2436,7 +2430,6 @@ gfc_complex2int (gfc_expr *src, int kind)
                             gfc_typename (&result->ts), &src->where);
            did_warn = true;
          }
-       mpfr_clear (f);
       }
 
       if (!did_warn && warn_conversion_extra)
diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
index be5eb8b6a0f..49bd296a6ac 100644
--- a/gcc/fortran/array.cc
+++ b/gcc/fortran/array.cc
@@ -1722,14 +1722,13 @@ expand_iterator (gfc_constructor *c)
 {
   gfc_expr *start, *end, *step;
   iterator_stack frame;
-  mpz_t trip;
+  auto_mpz trip;
   bool t;
 
   end = step = NULL;
 
   t = false;
 
-  mpz_init (trip);
   mpz_init (frame.value);
   frame.prev = NULL;
 
@@ -1787,7 +1786,6 @@ cleanup:
   gfc_free_expr (end);
   gfc_free_expr (step);
 
-  mpz_clear (trip);
   mpz_clear (frame.value);
 
   iter_stack = frame.prev;
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 8c1ae8c2f00..f07dfadbc36 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -211,7 +211,7 @@ bin2real (gfc_expr *x, int kind)
   char buf[114], *sp;
   int b, i, ie, t, w;
   bool sgn;
-  mpz_t em;
+  auto_mpz em;
 
   i = gfc_validate_kind (BT_REAL, kind, false);
   t = gfc_real_kinds[i].digits - 1;
@@ -237,7 +237,6 @@ bin2real (gfc_expr *x, int kind)
   /* Extract biased exponent. */
   memset (buf, 0, 114);
   strncpy (buf, ++sp, w);
-  mpz_init (em);
   mpz_set_str (em, buf, 2);
   ie = mpz_get_si (em);
 
@@ -284,8 +283,6 @@ bin2real (gfc_expr *x, int kind)
     }
 
    if (sgn) mpfr_neg (x->value.real, x->value.real, GFC_RND_MODE);
-
-   mpz_clear (em);
 }
 
 
@@ -388,7 +385,7 @@ gfc_boz2int (gfc_expr *x, int kind)
 {
   int i, len;
   char *buf, *str;
-  mpz_t tmp1;
+  auto_mpz tmp1;
 
   if (!is_boz_constant (x))
     return false;
@@ -437,18 +434,16 @@ gfc_boz2int (gfc_expr *x, int kind)
     }
 
   /* Convert as-if unsigned integer.  */
-  mpz_init (tmp1);
   mpz_set_str (tmp1, buf, x->boz.rdx);
 
   /* Check for wrap-around.  */
   if (mpz_cmp (tmp1, gfc_integer_kinds[i].huge) > 0)
     {
-      mpz_t tmp2;
-      mpz_init (tmp2);
+      auto_mpz tmp2;
+      
       mpz_add_ui (tmp2, gfc_integer_kinds[i].huge, 1);
       mpz_mod (tmp1, tmp1, tmp2);
       mpz_sub (tmp1, tmp1, tmp2);
-      mpz_clear (tmp2);
     }
 
   /* Clear boz info.  */
@@ -460,7 +455,6 @@ gfc_boz2int (gfc_expr *x, int kind)
   mpz_set (x->value.integer, tmp1);
   x->ts.type = BT_INTEGER;
   x->ts.kind = kind;
-  mpz_clear (tmp1);
 
   return true;
 }
diff --git a/gcc/fortran/data.cc b/gcc/fortran/data.cc
index d29eb12c1b1..5c88e34e3ff 100644
--- a/gcc/fortran/data.cc
+++ b/gcc/fortran/data.cc
@@ -49,9 +49,9 @@ get_array_index (gfc_array_ref *ar, mpz_t *offset)
   gfc_expr *e;
   int i;
   mpz_t delta;
-  mpz_t tmp;
+  auto_mpz tmp;
 
-  mpz_init (tmp);
+  
   mpz_set_si (*offset, 0);
   mpz_init_set_si (delta, 1);
   for (i = 0; i < ar->dimen; i++)
@@ -76,7 +76,6 @@ get_array_index (gfc_array_ref *ar, mpz_t *offset)
       mpz_mul (delta, tmp, delta);
     }
   mpz_clear (delta);
-  mpz_clear (tmp);
 }
 
 /* Find if there is a constructor which component is equal to COM.
@@ -638,7 +637,7 @@ gfc_advance_section (mpz_t *section_index, gfc_array_ref 
*ar,
 {
   int i;
   mpz_t delta;
-  mpz_t tmp;
+  auto_mpz tmp;
   bool forwards;
   int cmp;
   gfc_expr *start, *end, *stride;
@@ -698,7 +697,6 @@ gfc_advance_section (mpz_t *section_index, gfc_array_ref 
*ar,
 
   mpz_set_si (*offset_ret, 0);
   mpz_init_set_si (delta, 1);
-  mpz_init (tmp);
   for (i = 0; i < ar->dimen; i++)
     {
       mpz_sub (tmp, section_index[i], ar->as->lower[i]->value.integer);
@@ -710,7 +708,6 @@ gfc_advance_section (mpz_t *section_index, gfc_array_ref 
*ar,
       mpz_add_ui (tmp, tmp, 1);
       mpz_mul (delta, tmp, delta);
     }
-  mpz_clear (tmp);
   mpz_clear (delta);
 }
 
@@ -797,11 +794,10 @@ gfc_get_section_index (gfc_array_ref *ar, mpz_t 
*section_index, mpz_t *offset)
 {
   int i;
   mpz_t delta;
-  mpz_t tmp;
+  auto_mpz tmp;
   gfc_expr *start;
 
   mpz_set_si (*offset, 0);
-  mpz_init (tmp);
   mpz_init_set_si (delta, 1);
   for (i = 0; i < ar->dimen; i++)
     {
@@ -839,7 +835,6 @@ gfc_get_section_index (gfc_array_ref *ar, mpz_t 
*section_index, mpz_t *offset)
       mpz_mul (delta, tmp, delta);
     }
 
-  mpz_clear (tmp);
   mpz_clear (delta);
 }
 
diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
index 9117825ee6e..0d0d782f67a 100644
--- a/gcc/fortran/dependency.cc
+++ b/gcc/fortran/dependency.cc
@@ -1576,16 +1576,14 @@ check_section_vs_section (gfc_array_ref *l_ar, 
gfc_array_ref *r_ar, int n)
   if (IS_CONSTANT_INTEGER (l_stride) && IS_CONSTANT_INTEGER (r_stride)
       && gfc_dep_difference (l_start, r_start, &tmp))
     {
-      mpz_t gcd;
+      auto_mpz gcd;
       int result;
 
-      mpz_init (gcd);
       mpz_gcd (gcd, l_stride->value.integer, r_stride->value.integer);
 
       mpz_fdiv_r (tmp, tmp, gcd);
       result = mpz_cmp_si (tmp, 0L);
 
-      mpz_clear (gcd);
       mpz_clear (tmp);
 
       if (result != 0)
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index c295721b9d6..7695710cf6b 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -1354,10 +1354,10 @@ find_array_element (gfc_constructor_base base, 
gfc_array_ref *ar,
 {
   unsigned long nelemen;
   int i;
-  mpz_t delta;
+  auto_mpz delta;
   mpz_t offset;
   mpz_t span;
-  mpz_t tmp;
+  auto_mpz tmp;
   gfc_constructor *cons;
   gfc_expr *e;
   bool t;
@@ -1366,8 +1366,6 @@ find_array_element (gfc_constructor_base base, 
gfc_array_ref *ar,
   e = NULL;
 
   mpz_init_set_ui (offset, 0);
-  mpz_init (delta);
-  mpz_init (tmp);
   mpz_init_set_ui (span, 1);
   for (i = 0; i < ar->dimen; i++)
     {
@@ -1423,10 +1421,8 @@ find_array_element (gfc_constructor_base base, 
gfc_array_ref *ar,
     }
 
 depart:
-  mpz_clear (delta);
   mpz_clear (offset);
   mpz_clear (span);
-  mpz_clear (tmp);
   *rval = cons;
   return t;
 }
@@ -1503,9 +1499,9 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
   mpz_t delta[GFC_MAX_DIMENSIONS];
   mpz_t ctr[GFC_MAX_DIMENSIONS];
   mpz_t delta_mpz;
-  mpz_t tmp_mpz;
+  auto_mpz tmp_mpz;
   mpz_t nelts;
-  mpz_t ptr;
+  auto_mpz ptr;
   gfc_constructor_base base;
   gfc_constructor *cons, *vecsub[GFC_MAX_DIMENSIONS];
   gfc_expr *begin;
@@ -1527,7 +1523,6 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
 
   mpz_init_set_ui (delta_mpz, one);
   mpz_init_set_ui (nelts, one);
-  mpz_init (tmp_mpz);
 
   /* Do the initialization now, so that we can cleanup without
      keeping track of where we were.  */
@@ -1671,7 +1666,6 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
       mpz_mul (delta_mpz, delta_mpz, tmp_mpz);
     }
 
-  mpz_init (ptr);
   cons = gfc_constructor_first (base);
 
   /* Now clock through the array reference, calculating the index in
@@ -1739,12 +1733,9 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
                                   gfc_copy_expr (cons->expr), NULL);
     }
 
-  mpz_clear (ptr);
-
 cleanup:
 
   mpz_clear (delta_mpz);
-  mpz_clear (tmp_mpz);
   mpz_clear (nelts);
   for (d = 0; d < rank; d++)
     {
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index fb0745927ac..f18e8058b6e 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -1480,8 +1480,8 @@ resolve_structure_cons (gfc_expr *expr, int init)
          && comp->as && !comp->attr.allocatable && !comp->attr.pointer
          && !comp->attr.pdt_array)
        {
-         mpz_t len;
-         mpz_init (len);
+         auto_mpz len;
+         
          for (int n = 0; n < rank; n++)
            {
              if (comp->as->upper[n]->expr_type != EXPR_CONSTANT
@@ -1509,7 +1509,6 @@ resolve_structure_cons (gfc_expr *expr, int init)
                  t = false;
                }
            }
-         mpz_clear (len);
        }
 
       if (!comp->attr.pointer || comp->attr.proc_pointer
@@ -4628,7 +4627,7 @@ static int
 compute_last_value_for_triplet (gfc_expr *start, gfc_expr *end,
                                gfc_expr *stride, mpz_t last)
 {
-  mpz_t rem;
+  auto_mpz rem;
 
   if (start == NULL || start->expr_type != EXPR_CONSTANT
       || end == NULL || end->expr_type != EXPR_CONSTANT
@@ -4660,11 +4659,9 @@ compute_last_value_for_triplet (gfc_expr *start, 
gfc_expr *end,
        return 0;
     }
 
-  mpz_init (rem);
   mpz_sub (rem, end->value.integer, start->value.integer);
   mpz_tdiv_r (rem, rem, stride->value.integer);
   mpz_sub (last, end->value.integer, rem);
-  mpz_clear (rem);
 
   return 1;
 }
@@ -7754,9 +7751,7 @@ conformable_arrays (gfc_expr *e1, gfc_expr *e2)
   if (e1->shape)
     {
       int i;
-      mpz_t s;
-
-      mpz_init (s);
+      auto_mpz s;
 
       for (i = 0; i < e1->rank; i++)
        {
@@ -7778,12 +7773,9 @@ conformable_arrays (gfc_expr *e1, gfc_expr *e2)
            {
              gfc_error ("Source-expr at %L and allocate-object at %L must "
                         "have the same shape", &e1->where, &e2->where);
-             mpz_clear (s);
              return false;
            }
        }
-
-      mpz_clear (s);
     }
 
   return true;
@@ -16601,13 +16593,12 @@ static bool traverse_data_var (gfc_data_variable *, 
locus *);
 static bool
 traverse_data_list (gfc_data_variable *var, locus *where)
 {
-  mpz_t trip;
+  auto_mpz trip;
   iterator_stack frame;
   gfc_expr *e, *start, *end, *step;
   bool retval = true;
 
   mpz_init (frame.value);
-  mpz_init (trip);
 
   start = gfc_copy_expr (var->iter.start);
   end = gfc_copy_expr (var->iter.end);
@@ -16680,7 +16671,6 @@ traverse_data_list (gfc_data_variable *var, locus 
*where)
 
 cleanup:
   mpz_clear (frame.value);
-  mpz_clear (trip);
 
   gfc_free_expr (start);
   gfc_free_expr (end);
diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index 20ea38e0007..3a6316c00a9 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -1157,13 +1157,12 @@ gfc_simplify_asin (gfc_expr *x)
 static void
 rad2deg (mpfr_t x)
 {
-  mpfr_t tmp;
+  auto_mpfr tmp;
 
-  mpfr_init (tmp);
+  
   mpfr_const_pi (tmp, GFC_RND_MODE);
   mpfr_mul_ui (x, x, 180, GFC_RND_MODE);
   mpfr_div (x, x, tmp, GFC_RND_MODE);
-  mpfr_clear (tmp);
 }
 
 
@@ -1927,13 +1926,12 @@ gfc_simplify_cos (gfc_expr *x)
 static void
 deg2rad (mpfr_t x)
 {
-  mpfr_t d2r;
+  auto_mpfr d2r;
 
-  mpfr_init (d2r);
+  
   mpfr_const_pi (d2r, GFC_RND_MODE);
   mpfr_div_ui (d2r, d2r, 180, GFC_RND_MODE);
   mpfr_mul (x, x, d2r, GFC_RND_MODE);
-  mpfr_clear (d2r);
 }
 
 
@@ -2835,7 +2833,7 @@ static void
 asympt_erfc_scaled (mpfr_t res, mpfr_t arg)
 {
   mpfr_t sum, x, u, v, w, oldsum, sumtrunc;
-  mpz_t num;
+  auto_mpz num;
   mpfr_prec_t prec;
   unsigned i;
 
@@ -2847,7 +2845,6 @@ asympt_erfc_scaled (mpfr_t res, mpfr_t arg)
   mpfr_init (u);
   mpfr_init (v);
   mpfr_init (w);
-  mpz_init (num);
 
   mpfr_init (oldsum);
   mpfr_init (sumtrunc);
@@ -2897,7 +2894,6 @@ asympt_erfc_scaled (mpfr_t res, mpfr_t arg)
   mpfr_set_default_prec (prec);
 
   mpfr_clears (sum, x, u, v, w, oldsum, sumtrunc, NULL);
-  mpz_clear (num);
 }
 
 
@@ -3172,7 +3168,7 @@ gfc_expr *
 gfc_simplify_floor (gfc_expr *e, gfc_expr *k)
 {
   gfc_expr *result;
-  mpfr_t floor;
+  auto_mpfr floor (mpfr_get_prec(e->value.real));
   int kind;
 
   kind = get_kind (BT_INTEGER, k, "FLOOR", gfc_default_integer_kind);
@@ -3182,14 +3178,11 @@ gfc_simplify_floor (gfc_expr *e, gfc_expr *k)
   if (e->expr_type != EXPR_CONSTANT)
     return NULL;
 
-  mpfr_init2 (floor, mpfr_get_prec (e->value.real));
   mpfr_floor (floor, e->value.real);
 
   result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
   gfc_mpfr_to_mpz (result->value.integer, floor, &e->where);
 
-  mpfr_clear (floor);
-
   return range_check (result, "FLOOR");
 }
 
@@ -6199,7 +6192,7 @@ static int norm2_scale;
 static gfc_expr *
 norm2_add_squared (gfc_expr *result, gfc_expr *e)
 {
-  mpfr_t tmp;
+  auto_mpfr tmp;
 
   gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT);
   gcc_assert (result->ts.type == BT_REAL
@@ -6221,7 +6214,6 @@ norm2_add_squared (gfc_expr *result, gfc_expr *e)
        }
     }
 
-  mpfr_init (tmp);
   if (mpfr_regular_p (e->value.real))
     {
       exp = mpfr_get_exp (e->value.real);
@@ -6247,7 +6239,6 @@ norm2_add_squared (gfc_expr *result, gfc_expr *e)
   mpfr_pow_ui (tmp, tmp, 2, GFC_RND_MODE);
   mpfr_add (result->value.real, result->value.real, tmp,
            GFC_RND_MODE);
-  mpfr_clear (tmp);
 
   return result;
 }
@@ -6265,12 +6256,11 @@ norm2_do_sqrt (gfc_expr *result, gfc_expr *e)
   mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE);
   if (norm2_scale && mpfr_regular_p (result->value.real))
     {
-      mpfr_t tmp;
-      mpfr_init (tmp);
+      auto_mpfr tmp;
+      
       mpfr_set_ui (tmp, 1, GFC_RND_MODE);
       mpfr_set_exp (tmp, norm2_scale);
       mpfr_mul (result->value.real, result->value.real, tmp, GFC_RND_MODE);
-      mpfr_clear (tmp);
     }
   norm2_scale = 0;
 
@@ -6304,12 +6294,11 @@ gfc_simplify_norm2 (gfc_expr *e, gfc_expr *dim)
       mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE);
       if (norm2_scale && mpfr_regular_p (result->value.real))
        {
-         mpfr_t tmp;
-         mpfr_init (tmp);
+         auto_mpfr tmp;
+         
          mpfr_set_ui (tmp, 1, GFC_RND_MODE);
          mpfr_set_exp (tmp, norm2_scale);
          mpfr_mul (result->value.real, result->value.real, tmp, GFC_RND_MODE);
-         mpfr_clear (tmp);
        }
       norm2_scale = 0;
     }
diff --git a/gcc/fortran/target-memory.cc b/gcc/fortran/target-memory.cc
index 05b82558672..400bef20225 100644
--- a/gcc/fortran/target-memory.cc
+++ b/gcc/fortran/target-memory.cc
@@ -467,9 +467,8 @@ gfc_interpret_character (unsigned char *buffer, size_t 
buffer_size,
       result->value.character.string[i] = (gfc_char_t) buffer[i];
   else
     {
-      mpz_t integer;
+      auto_mpz integer;
       size_t bytes = size_character (1, result->ts.kind);
-      mpz_init (integer);
       gcc_assert (bytes <= sizeof (unsigned long));
 
       for (size_t i = 0; i < (size_t) result->value.character.length; i++)
@@ -480,8 +479,6 @@ gfc_interpret_character (unsigned char *buffer, size_t 
buffer_size,
          result->value.character.string[i]
            = (gfc_char_t) mpz_get_ui (integer);
        }
-
-      mpz_clear (integer);
     }
 
   result->value.character.string[result->value.character.length] = '\0';
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 63bd1ac573a..3aa5d155601 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1796,13 +1796,11 @@ gfc_get_array_constructor_size (mpz_t * size, 
gfc_constructor_base base)
 {
   gfc_constructor *c;
   gfc_iterator *i;
-  mpz_t val;
-  mpz_t len;
+  auto_mpz val;
+  auto_mpz len;
   bool dynamic;
 
   mpz_set_ui (*size, 0);
-  mpz_init (len);
-  mpz_init (val);
 
   dynamic = false;
   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
@@ -1828,8 +1826,6 @@ gfc_get_array_constructor_size (mpz_t * size, 
gfc_constructor_base base)
          mpz_add (*size, *size, len);
        }
     }
-  mpz_clear (len);
-  mpz_clear (val);
   return dynamic;
 }
 
@@ -2037,13 +2033,12 @@ gfc_trans_array_constructor_value (stmtblock_t * 
pblock, tree type,
   tree step = NULL_TREE;
   stmtblock_t body;
   gfc_se se;
-  mpz_t size;
+  auto_mpz size;
   gfc_constructor *c;
 
   tree shadow_loopvar = NULL_TREE;
   gfc_saved_var saved_loopvar;
 
-  mpz_init (size);
   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
     {
       /* If this is an iterator or an array, the offset must be a variable.  */
@@ -2292,7 +2287,6 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, 
tree type,
          gfc_restore_sym (c->iterator->var->symtree->n.sym, &saved_loopvar);
        }
     }
-  mpz_clear (size);
 }
 
 
@@ -5229,14 +5223,13 @@ set_loop_bounds (gfc_loopinfo *loop)
   gfc_ss **loopspec;
   bool dynamic[GFC_MAX_DIMENSIONS];
   mpz_t *cshape;
-  mpz_t i;
+  auto_mpz i;
   bool nonoptional_arr;
 
   gfc_loopinfo * const outer_loop = outermost_loop (loop);
 
   loopspec = loop->specloop;
 
-  mpz_init (i);
   for (n = 0; n < loop->dimen; n++)
     {
       loopspec[n] = NULL;
@@ -5452,7 +5445,6 @@ set_loop_bounds (gfc_loopinfo *loop)
          loop->from[n] = gfc_index_zero_node;
        }
     }
-  mpz_clear (i);
 
   for (loop = loop->nested; loop; loop = loop->next)
     set_loop_bounds (loop);
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index 21eeb12ca89..2d275b7fd0a 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -457,7 +457,7 @@ gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum 
rounding_mode op)
   tree tmp;
   tree cond;
   tree decl;
-  mpfr_t huge;
+  auto_mpfr huge;
   int n, nargs;
   int kind;
 
@@ -498,7 +498,6 @@ gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum 
rounding_mode op)
 
   /* Test if the value is too large to handle sensibly.  */
   gfc_set_model_kind (kind);
-  mpfr_init (huge);
   n = gfc_validate_kind (BT_INTEGER, kind, false);
   mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
   tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
@@ -517,7 +516,6 @@ gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum 
rounding_mode op)
   tmp = convert (type, tmp);
   se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond, tmp,
                              arg[0]);
-  mpfr_clear (huge);
 }
 
 
@@ -4632,15 +4630,13 @@ gfc_conv_intrinsic_cotan (gfc_se *se, gfc_expr *expr)
     {
       tree tan;
       tree tmp;
-      mpfr_t pio2;
+      auto_mpfr pio2;
 
       /* Create pi/2.  */
       gfc_set_model_kind (expr->ts.kind);
-      mpfr_init (pio2);
       mpfr_const_pi (pio2, GFC_RND_MODE);
       mpfr_div_ui (pio2, pio2, 2, GFC_RND_MODE);
       tmp = gfc_conv_mpfr_to_tree (pio2, expr->ts.kind, 0);
-      mpfr_clear (pio2);
 
       /* Find tan builtin function.  */
       m = gfc_lookup_intrinsic (GFC_ISYM_TAN);
diff --git a/gcc/real.cc b/gcc/real.cc
index 126695bf2e2..99a216051f1 100644
--- a/gcc/real.cc
+++ b/gcc/real.cc
@@ -2131,7 +2131,7 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
     {
       /* Decimal floating point.  */
       const char *cstr = str;
-      mpfr_t m;
+      auto_mpfr m (SIGNIFICAND_BITS);
       bool inexact;
 
       while (*cstr == '0')
@@ -2148,19 +2148,16 @@ 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);
       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;
        }
       else if (mpfr_get_exp (m) > MAX_EXP - 4)
        {
-         mpfr_clear (m);
          goto overflow;
        }
       else
@@ -2173,7 +2170,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 +2470,11 @@ 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 +2512,10 @@ 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/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index d58e2258947..a3b56fb6252 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -2117,10 +2117,9 @@ CompileExpr::compile_integer_literal (const 
HIR::LiteralExpr &expr,
       return error_mark_node;
     }
 
-  mpz_t type_min;
-  mpz_t type_max;
-  mpz_init (type_min);
-  mpz_init (type_max);
+  auto_mpz type_min;
+  auto_mpz type_max;
+  
   get_type_static_bounds (type, type_min, type_max);
 
   if (mpz_cmp (ival, type_min) < 0 || mpz_cmp (ival, type_max) > 0)
@@ -2133,8 +2132,6 @@ CompileExpr::compile_integer_literal (const 
HIR::LiteralExpr &expr,
 
   tree result = wide_int_to_tree (type, wi::from_mpz (type, ival, true));
 
-  mpz_clear (type_min);
-  mpz_clear (type_max);
   mpz_clear (ival);
 
   return result;
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 581bf5d067b..f1515a62494 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -159,17 +159,15 @@ refine_value_range_using_guard (tree type, tree var,
 
       if (operand_equal_p (var, c0, 0))
        {
-         mpz_t valc1;
+         auto_mpz valc1;
 
          /* Case of comparing VAR with its below/up bounds.  */
-         mpz_init (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 +504,7 @@ 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;
+  auto_mpz m;
 
   /* If X == Y, then the expressions are always equal.
      If X > Y, there are the following possibilities:
@@ -529,7 +527,6 @@ bound_difference_of_offsetted_base (tree type, mpz_t x, 
mpz_t y,
       return;
     }
 
-  mpz_init (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 +539,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
@@ -983,7 +978,7 @@ 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;
+  auto_mpz max;
 
   niter->control = *iv;
   niter->bound = final;
@@ -1011,12 +1006,10 @@ number_of_iterations_ne (class loop *loop, tree type, 
affine_iv *iv,
                       fold_convert (niter_type, iv->base));
     }
 
-  mpz_init (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:
@@ -1163,7 +1156,7 @@ 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;
+  auto_mpz mmod;
   tree assumption = boolean_true_node, bound, noloop;
   bool ret = false, fv_comp_no_overflow;
   tree type1 = type;
@@ -1176,7 +1169,6 @@ 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);
   wi::to_mpz (wi::to_wide (mod), mmod, UNSIGNED);
   mpz_neg (mmod, mmod);
 
@@ -1264,7 +1256,6 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, 
affine_iv *iv1,
 
   ret = true;
 end:
-  mpz_clear (mmod);
   return ret;
 }
 
diff --git a/gcc/ubsan.cc b/gcc/ubsan.cc
index c2f2e75b300..0256d4eb8ad 100644
--- a/gcc/ubsan.cc
+++ b/gcc/ubsan.cc
@@ -1877,14 +1877,13 @@ 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;
+      auto_mpfr m (prec + 2);
       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);
       mpfr_set_ui_2exp (m, 1, prec - !uns_p, MPFR_RNDN);
       mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
       decimal_real_from_string (&maxval, buf);
@@ -1904,7 +1903,6 @@ ubsan_instrument_float_cast (location_t loc, tree type, 
tree expr)
          decimal_real_from_string (&minval, buf);
          min = build_real (expr_type, minval);
        }
-      mpfr_clear (m);
     }
   else
     return NULL_TREE;

Reply via email to