This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
- From: Jerry DeLisle <jvdelisle at charter dot net>
- To: Dominique d'Humières <dominiq at lps dot ens dot fr>
- Cc: FX Coudert <fxcoudert at gmail dot com>, fortran at gcc dot gnu dot org, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 17 Jul 2016 17:02:58 -0700
- Subject: Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
- Authentication-results: sourceware.org; auth=none
- References: <050050EA-5726-4383-B256-A8C2B6F64730@lps.ens.fr>
On 07/12/2016 06:26 AM, Dominique d'Humières wrote:
>>> 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.
>>
>> OK, thanks
> Please hold on. I still see several problem with the patch applied. One is
>
> program p
> character :: z = 'z'
> print *, repeat(z, huge(1)-2**9)
> end
Please test this revised patch. See my comments in the PR.
I think we should commit this one.
Jerry
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 77831ab..dcacae8 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -59,6 +59,8 @@ not after.
#define MAX_SUBRECORD_LENGTH 2147483639 /* 2**31-9 */
+/* Practical limit on size of character constants. */
+#define MAX_CHAR_LENGTH 268435455 /* 2**28-1 */
#define gfc_is_whitespace(c) ((c==' ') || (c=='\t'))
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 8096a92..4010753 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -5085,24 +5085,29 @@ 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);
i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
+ /* Set the limit on size to avoid unsigned integer
+ wrapping and resource limits. */
+ mpz_init_set_si (limit, MAX_CHAR_LENGTH);
+
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);
}
+ mpz_clear (limit);
/* The check itself. */
if (mpz_cmp (ncopies, max) > 0)
diff --git a/gcc/testsuite/gfortran.dg/repeat_4.f90 b/gcc/testsuite/gfortran.dg/repeat_4.f90
index e5b5acc..a6ee75b 100644
--- a/gcc/testsuite/gfortran.dg/repeat_4.f90
+++ b/gcc/testsuite/gfortran.dg/repeat_4.f90
@@ -22,17 +22,17 @@ 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(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 " }
- print *, repeat(t0, huge(0)/2)
- print *, repeat(t1, huge(0)/2)
- print *, repeat(t2, huge(0)/2)
+ print *, repeat(t0, huge(0)/8)
+ print *, repeat(t1, huge(0)/8)
+ print *, repeat(t2, huge(0)/16)
print *, repeat(t0, huge(0)/2+1)
- print *, repeat(t1, huge(0)/2+1)
- print *, repeat(t2, huge(0)/2+1) ! { dg-error "Argument NCOPIES of REPEAT intrinsic is too large " }
- print *, repeat(s2, huge(0)/2+1) ! { dg-error "Argument NCOPIES of REPEAT intrinsic is too large " }
+ print *, repeat(t1, huge(0)/8+1) ! { dg-error "Argument NCOPIES of REPEAT intrinsic is too large " }
+ print *, repeat(t2, huge(0)/16+1)! { dg-error "Argument NCOPIES of REPEAT intrinsic is too large " }
+ print *, repeat(s2, huge(0)/16+1)! { dg-error "Argument NCOPIES of REPEAT intrinsic is too large " }
end program test