public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
@ 2016-07-12 13:26 Dominique d'Humières
  2016-07-12 18:34 ` Jerry DeLisle
  2016-07-18  0:03 ` Jerry DeLisle
  0 siblings, 2 replies; 9+ messages in thread
From: Dominique d'Humières @ 2016-07-12 13:26 UTC (permalink / raw)
  To: jvdelisle; +Cc: FX Coudert, fortran, gcc-patches

> > 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

a.out(67209,0x7fff77e0b000) malloc: *** mach_vm_map(size=18446744071562067968) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Operating system error: Cannot allocate memory
Memory allocation failure in realloc

on x86_64-apple-darwin15.5 with/without the patch. print *, repeat(z, huge(1)-2**9-1) "works".

I’ll try to report the other problems in the PR later today.

Dominique


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
  2016-07-12 13:26 [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies Dominique d'Humières
@ 2016-07-12 18:34 ` Jerry DeLisle
  2016-07-18  0:03 ` Jerry DeLisle
  1 sibling, 0 replies; 9+ messages in thread
From: Jerry DeLisle @ 2016-07-12 18:34 UTC (permalink / raw)
  To: Dominique d'Humières; +Cc: FX Coudert, fortran, gcc-patches

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
> 
> a.out(67209,0x7fff77e0b000) malloc: *** mach_vm_map(size=18446744071562067968) failed (error code=3)
> *** error: can't allocate region
> *** set a breakpoint in malloc_error_break to debug
> Operating system error: Cannot allocate memory
> Memory allocation failure in realloc
> 
> on x86_64-apple-darwin15.5 with/without the patch. print *, repeat(z, huge(1)-2**9-1) "works".
> 
> I’ll try to report the other problems in the PR later today.
> 
> Dominique
> 
> 

I am holding. On my system I get:

Operating system error: Cannot allocate memory
Memory allocation failure in xrealloc

Which is what I expect.  The error is in trying to allocate the buffer in
write_blockm which it simply can not do.  If you think about it, the numbers are
hugely ridiculous.

Can you try ncopies = (huge(1)-1)/4 and see what you get?

Jerry

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
  2016-07-12 13:26 [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies Dominique d'Humières
  2016-07-12 18:34 ` Jerry DeLisle
@ 2016-07-18  0:03 ` Jerry DeLisle
  2016-07-19  9:56   ` Dominique d'Humières
  1 sibling, 1 reply; 9+ messages in thread
From: Jerry DeLisle @ 2016-07-18  0:03 UTC (permalink / raw)
  To: Dominique d'Humières; +Cc: FX Coudert, fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 573 bytes --]

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

[-- Attachment #2: pr66310-a.diff --]
[-- Type: text/x-patch, Size: 3113 bytes --]

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
  2016-07-18  0:03 ` Jerry DeLisle
@ 2016-07-19  9:56   ` Dominique d'Humières
  2016-07-19 16:43     ` Jerry DeLisle
  0 siblings, 1 reply; 9+ messages in thread
From: Dominique d'Humières @ 2016-07-19  9:56 UTC (permalink / raw)
  To: jvdelisle; +Cc: FX Coudert, fortran, gcc-patches


> Le 18 juil. 2016 à 02:02, Jerry DeLisle <jvdelisle@charter.net> a écrit :
> 
> Please test this revised patch. See my comments in the PR.
> 
> I think we should commit this one.
> 
> Jerry

Jerry,

As said on IRC I think the limit should be documented and a TODO comment added to gcc/fortran/gfortran.h.

While trying to bootstrap with the patch I got

/opt/gcc/build_w/./prev-gcc/xg++ -B/opt/gcc/build_w/./prev-gcc/ -B/opt/gcc/gcc7w/x86_64-apple-darwin15.5.0/bin/ -nostdinc++ -B/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/src/.libs -B/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/libsupc++/.libs  -I/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/include/x86_64-apple-darwin15.5.0  -I/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/include  -I/opt/gcc/work/libstdc++-v3/libsupc++ -L/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/src/.libs -L/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/libsupc++/.libs -fno-PIE -c  -DIN_GCC_FRONTEND -g -O2   -gtoggle -DIN_GCC     -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -fno-common  -DHAVE_CONFIG_H -I. -Ifortran -I../../work/gcc -I../../work/gcc/fortran -I../../work/gcc/../include -I./../intl -I../../work/gcc/../libcpp/include -I/opt/mp-new/include  -I../../work/gcc/../libdecnumber -I../../work/gcc/../libdecnumber/dpd -I../libdecnumber -I../../work/gcc/../libbacktrace -I/opt/mp-new/include  -o fortran/simplify.o -MT fortran/simplify.o -MMD -MP -MF fortran/.deps/simplify.TPo ../../work/gcc/fortran/simplify.c
../../work/gcc/fortran/simplify.c: In function 'gfc_expr* gfc_simplify_repeat(gfc_expr*, gfc_expr*)':
../../work/gcc/fortran/simplify.c:5089:11: error: variable 'i' set but not used [-Werror=unused-but-set-variable]
       int i;
           ^
cc1plus: all warnings being treated as errors

i.e., the lines

       int i;

and

       i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);

must be deleted. also the comment

      /* Compute the maximum value allowed for NCOPIES:
	    huge(cl) - 1 / len.  */

should be updated.

Last point I have found, the limit does not seem to take into account CHARACTER(KIND=4):

[Book15] f90/bug% cat pr66310_par_4.f90
   program p
      character(len=2,kind=4), parameter :: z = 'yz'
      print *, repeat(z, 2**25)
   end
[Book15] f90/bug% gfc pr66310_par_4.f90
f951(3881,0x7fff74e38000) malloc: *** mach_vm_map(size=18446744073441116160) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug

f951: out of memory allocating 18446744073441116160 bytes after a total of 0 bytes

Thanks for working on this PR.

Dominique

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
  2016-07-19  9:56   ` Dominique d'Humières
@ 2016-07-19 16:43     ` Jerry DeLisle
  0 siblings, 0 replies; 9+ messages in thread
From: Jerry DeLisle @ 2016-07-19 16:43 UTC (permalink / raw)
  To: Dominique d'Humières; +Cc: FX Coudert, fortran

[-- Attachment #1: Type: text/plain, Size: 3155 bytes --]

On 07/19/2016 02:56 AM, Dominique d'Humières wrote:
> 
>> Le 18 juil. 2016 à 02:02, Jerry DeLisle <jvdelisle@charter.net> a écrit :
>>
>> Please test this revised patch. See my comments in the PR.
>>
>> I think we should commit this one.
>>
>> Jerry
> 
> Jerry,
> 

See latest patch attached. Fixes a few things and documents a TODO

Jerry

> As said on IRC I think the limit should be documented and a TODO comment added to gcc/fortran/gfortran.h.
> 
> While trying to bootstrap with the patch I got
> 
> /opt/gcc/build_w/./prev-gcc/xg++ -B/opt/gcc/build_w/./prev-gcc/ -B/opt/gcc/gcc7w/x86_64-apple-darwin15.5.0/bin/ -nostdinc++ -B/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/src/.libs -B/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/libsupc++/.libs  -I/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/include/x86_64-apple-darwin15.5.0  -I/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/include  -I/opt/gcc/work/libstdc++-v3/libsupc++ -L/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/src/.libs -L/opt/gcc/build_w/prev-x86_64-apple-darwin15.5.0/libstdc++-v3/libsupc++/.libs -fno-PIE -c  -DIN_GCC_FRONTEND -g -O2   -gtoggle -DIN_GCC     -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -fno-common  -DHAVE_CONFIG_H -I. -Ifortran -I../../work/gcc -I../../work/gcc/fortran -I../../work/gcc/../include -I./../intl -I../../work/gcc/../libcpp/include -I/opt/mp-new/include  -I../../work/gcc/../libdecnumber -I../../work/gcc/../libdecnumber/dpd -I../libdecnumber -I../../work/gcc/../libbacktrace -I/opt/mp-new/include  -o fortran/simplify.o -MT fortran/simplify.o -MMD -MP -MF fortran/.deps/simplify.TPo ../../work/gcc/fortran/simplify.c
> ../../work/gcc/fortran/simplify.c: In function 'gfc_expr* gfc_simplify_repeat(gfc_expr*, gfc_expr*)':
> ../../work/gcc/fortran/simplify.c:5089:11: error: variable 'i' set but not used [-Werror=unused-but-set-variable]
>        int i;
>            ^
> cc1plus: all warnings being treated as errors
> 
> i.e., the lines
> 
>        int i;
> 
> and
> 
>        i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
> 
> must be deleted. also the comment
> 
>       /* Compute the maximum value allowed for NCOPIES:
> 	    huge(cl) - 1 / len.  */
> 
> should be updated.
> 
> Last point I have found, the limit does not seem to take into account CHARACTER(KIND=4):
> 
> [Book15] f90/bug% cat pr66310_par_4.f90
>    program p
>       character(len=2,kind=4), parameter :: z = 'yz'
>       print *, repeat(z, 2**25)
>    end
> [Book15] f90/bug% gfc pr66310_par_4.f90
> f951(3881,0x7fff74e38000) malloc: *** mach_vm_map(size=18446744073441116160) failed (error code=3)
> *** error: can't allocate region
> *** set a breakpoint in malloc_error_break to debug
> 
> f951: out of memory allocating 18446744073441116160 bytes after a total of 0 bytes
> 
> Thanks for working on this PR.
> 
> Dominique
> 

[-- Attachment #2: pr66310-b.diff --]
[-- Type: text/x-patch, Size: 3374 bytes --]

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 77831ab..c0b73c7 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -59,6 +59,11 @@ not after.
 
 #define MAX_SUBRECORD_LENGTH 2147483639   /* 2**31-9 */
 
+/* TODO: Why does the compilation fail with the following set >= 2**28 when
+   the repeat source is a character constant (aka parameter)? See PR66310.  */
+
+/* Practical limit on size of character constants in gfc_simplify_repeat.  */
+#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..348bccc 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -5085,24 +5085,33 @@ 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 avoid unsigned integer
+	 wrapping and resource limits.  */
+      if (e->expr_type != EXPR_CONSTANT)
+	mpz_sub_ui (limit, gfc_integer_kinds[i].huge, 1);
+      else
+	mpz_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..771e7f0 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(t0, huge(0)-1)
+  print *, repeat(t1, huge(0)-1)
   print *, repeat(t2, huge(0)/2)
 
   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)) ! { 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)/16+1)! { dg-error "Argument NCOPIES of REPEAT intrinsic is too large " }
 
 end program test

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
  2016-07-13  1:54 ` William Clodius
@ 2016-07-13  3:22   ` Jerry DeLisle
  0 siblings, 0 replies; 9+ messages in thread
From: Jerry DeLisle @ 2016-07-13  3:22 UTC (permalink / raw)
  To: fortran

On 07/12/2016 06:54 PM, William Clodius wrote:
> A minor question. Why with Fortran’s counted strings are you appending a null character?
>

gfortran is written in C. We NULL terminate some strings for convenience 
during compilation and sometimes as a precaution. One example where it 
is helpful is when using the gdb debugger to debug the actual compiler 
and you want to print values stored at addresses. It avoids garbage 
while looking at it.  Also during compilation we may want to scan or 
search a string using a for loop that terminates on the NULL.

As far as Fortran is concerned, its not there. And in the case of this 
bug I could choose to eliminate it, I'm just being conservative in case 
it is used somewhere I am not aware of.

Jerry



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
  2016-07-12  0:54 Jerry DeLisle
  2016-07-12 12:57 ` FX
@ 2016-07-13  1:54 ` William Clodius
  2016-07-13  3:22   ` Jerry DeLisle
  1 sibling, 1 reply; 9+ messages in thread
From: William Clodius @ 2016-07-13  1:54 UTC (permalink / raw)
  To: gfortran, gcc patches

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 " }
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
  2016-07-12  0:54 Jerry DeLisle
@ 2016-07-12 12:57 ` FX
  2016-07-13  1:54 ` William Clodius
  1 sibling, 0 replies; 9+ messages in thread
From: FX @ 2016-07-12 12:57 UTC (permalink / raw)
  To: Jerry DeLisle; +Cc: gfortran, gcc patches

> 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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies
@ 2016-07-12  0:54 Jerry DeLisle
  2016-07-12 12:57 ` FX
  2016-07-13  1:54 ` William Clodius
  0 siblings, 2 replies; 9+ messages in thread
From: Jerry DeLisle @ 2016-07-12  0:54 UTC (permalink / raw)
  To: gfortran, gcc patches

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 " }

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-07-19 16:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-12 13:26 [patch, fortran] PR66310 Problems with intrinsic repeat for large number of copies Dominique d'Humières
2016-07-12 18:34 ` Jerry DeLisle
2016-07-18  0:03 ` Jerry DeLisle
2016-07-19  9:56   ` Dominique d'Humières
2016-07-19 16:43     ` Jerry DeLisle
  -- strict thread matches above, loose matches on Subject: below --
2016-07-12  0:54 Jerry DeLisle
2016-07-12 12:57 ` FX
2016-07-13  1:54 ` William Clodius
2016-07-13  3:22   ` Jerry DeLisle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).