This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
- From: William Clodius <williamclodius at gmail dot com>
- To: gfortran <fortran at gcc dot gnu dot org>, gcc patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 12 Jul 2016 19:54:28 -0600
- Subject: Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
- Authentication-results: sourceware.org; auth=none
- References: <2ea5e1c6-a6cb-f3eb-074d-34584d5e6dfe@charter.net>
A minor question. Why with Fortran’s counted strings are you appending a null character?
> On Jul 11, 2016, at 6:54 PM, Jerry DeLisle <jvdelisle@charter.net> wrote:
>
> Attached patch sets a limit of huge-1 on the character count to avoid the
> integer wrap.
>
> Regression tested with adjustment to test case.
>
> OK for trunk?
>
> Regards,
>
> Jerry
>
> 2016-07-11 Jerry DeLisle <jvdelisle@gcc.gnu.org>
>
> PR fortran/66310
> * simplify.c (gfc_simplify_repeat): Set max repeat to huge - 1 to allow
> one byte for null terminating the resulting string constant.
>
> diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
> index 95a8d10..03257ec 100644
> --- a/gcc/fortran/simplify.c
> +++ b/gcc/fortran/simplify.c
> @@ -5081,22 +5081,27 @@ gfc_simplify_repeat (gfc_expr *e, gfc_expr *n)
> /* Check that NCOPIES isn't too large. */
> if (len)
> {
> - mpz_t max, mlen;
> + mpz_t max, mlen, limit;
> int i;
>
> - /* Compute the maximum value allowed for NCOPIES: huge(cl) / len. */
> + /* Compute the maximum value allowed for NCOPIES:
> + huge(cl) - 1 / len. */
> mpz_init (max);
> + mpz_init (limit);
> i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
>
> + /* Set the limit on size to huge-1 to avoid unsigned integer
> + wrapping in gfc_get_character_expr. */
> + mpz_sub_ui (limit, gfc_integer_kinds[i].huge, 1);
> +
> if (have_length)
> {
> - mpz_tdiv_q (max, gfc_integer_kinds[i].huge,
> - e->ts.u.cl->length->value.integer);
> + mpz_tdiv_q (max, limit, e->ts.u.cl->length->value.integer);
> }
> else
> {
> mpz_init_set_si (mlen, len);
> - mpz_tdiv_q (max, gfc_integer_kinds[i].huge, mlen);
> + mpz_tdiv_q (max, limit, mlen);
> mpz_clear (mlen);
> }
>
> @@ -5104,6 +5109,7 @@ gfc_simplify_repeat (gfc_expr *e, gfc_expr *n)
> if (mpz_cmp (ncopies, max) > 0)
> {
> mpz_clear (max);
> + mpz_clear (limit);
> mpz_clear (ncopies);
> gfc_error ("Argument NCOPIES of REPEAT intrinsic is too large at %L",
> &n->where);
> @@ -5111,6 +5117,7 @@ gfc_simplify_repeat (gfc_expr *e, gfc_expr *n)
> }
>
> mpz_clear (max);
> + mpz_clear (limit);
> }
> mpz_clear (ncopies);
>
> diff --git a/gcc/testsuite/gfortran.dg/repeat_4.f90
> b/gcc/testsuite/gfortran.dg/repeat_4.f90
> index e5b5acc..77483a1 100644
> --- a/gcc/testsuite/gfortran.dg/repeat_4.f90
> +++ b/gcc/testsuite/gfortran.dg/repeat_4.f90
> @@ -22,7 +22,8 @@ program test
>
> ! Check for too large NCOPIES argument and limit cases
> print *, repeat(t0, huge(0))
> - print *, repeat(t1, huge(0))
> + print *, repeat(t1, huge(0)) ! { dg-error "Argument NCOPIES of REPEAT
> intrinsic is too large " }
> + print *, repeat(t1, huge(0) - 1)
> print *, repeat(t2, huge(0)) ! { dg-error "Argument NCOPIES of REPEAT
> intrinsic is too large " }
> print *, repeat(s2, huge(0)) ! { dg-error "Argument NCOPIES of REPEAT
> intrinsic is too large " }
>