https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83705

            Bug ID: 83705
           Summary: [8 Regression] ICE with large values of REPEAT after
                    revision r256284
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dominiq at lps dot ens.fr
                CC: jb at gcc dot gnu.org
  Target Milestone: ---

The following variant of the second test at
https://gcc.gnu.org/ml/fortran/2017-12/msg00132.html

program main
  integer(8), parameter :: n=2_8**28 - 1_8
  character(len=*), parameter :: a1 = repeat('x',n)
end program main

compiles with gfortran 7.2.0 and trunk before r256284.

If I replace 2_8**28 - 1_8 with 2_8**28, I get the following ICE

f951(30823,0x7fff9211a340) 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

If I compile the test with an instrumented compiler (r256049), I get

../../p_work/gcc/fortran/trans-const.c:100:17: runtime error: signed integer
overflow: 8 * 268435456 cannot be represented in type 'int'

(with an earlier revision I also got

../../p_work/gcc/fortran/target-memory.c:71:17: runtime error: signed integer
overflow: 1073741824 * 8 cannot be represented in type ‘int’
)

With an instrumented version of r256284 I got

../../work/gcc/fortran/decl.c:1748:37: runtime error: member access within null
pointer of type 'struct gfc_expr'

for 'n' as small as 2_8**23 + 1_8. I think it is due to the patch

-  nlen = ncop * len;
+  gfc_charlen_t nlen = ncop * len;
+
+  /* Here's a semi-arbitrary limit. If the string is longer than 32 MB
+     (8 * 2**20 elements * 4 bytes (wide chars) per element) defer to
+     runtime instead of consuming (unbounded) memory and CPU at
+     compile time.  */
+  if (nlen > 8388608)
+    return NULL;

which makes sense for variables, but IMO not for parameters.

If I revert this patch, the following test

program main
  integer(8), parameter :: n=2_8**32
  character(len=n) :: a1 = repeat('x',n)
  character(len=3) :: a2, a3
  print *, len(a1, kind=8)
  a2 = a1(1:3)
  a3 = a1(n-2:n)
  print *, "'", a2, "', '", a3, "'"
end program main
! https://gcc.gnu.org/ml/fortran/2017-12/msg00132.html

compiles and gives at run time

           4294967296
 '', ''

Note the empty strings a2 and a3.

With the patch reverted the test gfortran.dg/repeat_7.f90 gives

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

as well as the first test in this comment with n=2_8**28 (while it compiles
with n=2_8**32).

For n=2_8**28, my instrumented compiler reports

../../work/gcc/fortran/trans-const.c:100:17: runtime error: signed integer
overflow: 8 * 268435456 cannot be represented in type 'int'

Reply via email to