[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #27 from Jerry DeLisle --- (In reply to Dominique d'Humieres from comment #26) > > I concur. Closing accordingly. > > I disagree: if there is a limit, gfortran should emit an error. Well you are hitting on an OS limit, we could put a check in the runtime but how do we test that -m32 was used? The error message I get now is from our memory.c: if (p == NULL) os_error ("Memory allocation failed");
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #26 from Dominique d'Humieres --- > I concur. Closing accordingly. I disagree: if there is a limit, gfortran should emit an error.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 Thomas Koenig changed: What|Removed |Added Status|ASSIGNED|RESOLVED CC||tkoenig at gcc dot gnu.org Resolution|--- |FIXED --- Comment #25 from Thomas Koenig --- (In reply to Jerry DeLisle from comment #24) > (In reply to Jerry DeLisle from comment #23) > > Ok I see it. > > > > In fbuf.c (fbuf_alloc): > > > > /* Round up to nearest multiple of the current buffer length. */ > > newlen = ((u->fbuf->pos + len) / u->fbuf->len + 1) *u->fbuf->len; > > u->fbuf->buf = xrealloc (u->fbuf->buf, newlen); > > u->fbuf->len = newlen; > > > > We are rounding up to make sure we have enough buffer. The size newlen is > > calculated to 2147484160 which exceeds the limit of 2147483647 and xrealloc > > fails. > > There is a 2 GB limit on 32 bit processes, so this is not a bug. I suggest > this be closed. I concur. Closing accordingly.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #24 from Jerry DeLisle --- (In reply to Jerry DeLisle from comment #23) > Ok I see it. > > In fbuf.c (fbuf_alloc): > > /* Round up to nearest multiple of the current buffer length. */ > newlen = ((u->fbuf->pos + len) / u->fbuf->len + 1) *u->fbuf->len; > u->fbuf->buf = xrealloc (u->fbuf->buf, newlen); > u->fbuf->len = newlen; > > We are rounding up to make sure we have enough buffer. The size newlen is > calculated to 2147484160 which exceeds the limit of 2147483647 and xrealloc > fails. There is a 2 GB limit on 32 bit processes, so this is not a bug. I suggest this be closed.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #23 from Jerry DeLisle --- Ok I see it. In fbuf.c (fbuf_alloc): /* Round up to nearest multiple of the current buffer length. */ newlen = ((u->fbuf->pos + len) / u->fbuf->len + 1) *u->fbuf->len; u->fbuf->buf = xrealloc (u->fbuf->buf, newlen); u->fbuf->len = newlen; We are rounding up to make sure we have enough buffer. The size newlen is calculated to 2147484160 which exceeds the limit of 2147483647 and xrealloc fails.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #22 from Dominique d'Humieres --- For the original test program p character :: z = 'z' print *, repeat(z, huge(1_4)) end I get % gfc pr66310.f90 -m32 % ./a.out > zzz a.out(22882,0xa9b3c1c0) malloc: *** mach_vm_map(size=2147483648) failed (error code=3) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #21 from Harald Anlauf --- (In reply to Jerry DeLisle from comment #20) >program p > character(kind=1), parameter :: z = 'z' > integer, parameter :: big = 536870911 > !print *, repeat(z, huge(1_4)/4) > !print *, (huge(1)-1)/4, huge(1) - 1 > print *, repeat(z, big) >end Works for me on i686-pc-linux-gnu.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #20 from Jerry DeLisle --- (In reply to Dominique d'Humieres from comment #19) > > Can this be closed. > > The problem is not fixed in 32-bit mode. Dominique, what are you seeing? This is working fine with my system with -m32. program p character(kind=1), parameter :: z = 'z' integer, parameter :: big = 536870911 !print *, repeat(z, huge(1_4)/4) !print *, (huge(1)-1)/4, huge(1) - 1 print *, repeat(z, big) end
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 Dominique d'Humieres changed: What|Removed |Added Status|NEW |ASSIGNED
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #19 from Dominique d'Humieres --- > Can this be closed. The problem is not fixed in 32-bit mode.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #18 from Jerry DeLisle --- Can this be closed.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #17 from Janne Blomqvist --- Author: jb Date: Fri Jan 5 19:01:12 2018 New Revision: 256284 URL: https://gcc.gnu.org/viewcvs?rev=256284=gcc=rev Log: PR 78534 Change character length from int to size_t In order to handle large character lengths on (L)LP64 targets, switch the GFortran character length from an int to a size_t. This is an ABI change, as procedures with character arguments take hidden arguments with the character length. I also changed the _size member in vtables from int to size_t, as there were some cases where character lengths and sizes were apparently mixed up and caused regressions otherwise. Although I haven't tested, this might enable very large derived types as well. Also, as there are some places in the frontend were negative character lengths are used as special flag values, in the frontend the character length is handled as a signed variable of the same size as a size_t, although in the runtime library it really is size_t. I haven't changed the character length variables for the co-array intrinsics, as this is something that may need to be synchronized with OpenCoarrays. This is v5 of the patch. v4 was applied but caused breakage on big endian targets. These have been fixed and tested, thanks to access to the GCC compile farm. Overview of v4 of the patch: v3 was applied but had to reverted due to breaking bootstrap. The fix is in resolve.c:resolve_charlen, where it's necessary to check that an expression is constant before using mpz_sgn. Overview of v3 of the patch: All the issues pointed out by FX's review of v2 have been fixed. In particular, there are now new functions gfc_mpz_get_hwi and gfc_mpz_set_hwi, similar to the GMP functions mpz_get_si and mpz_set_si, except that they get/set a HOST_WIDE_INT instead of a long value. Similarly, gfc_get_int_expr now takes a HOST_WIDE_INT instead of a long, gfc_extract_long is replaced by gfc_extract_hwi. Also, the preliminary work to handle gfc_charlen_type_node being unsigned has been removed. Regtested on x86_64-pc-linux-gnu, i686-pc-linux-gnu and powerpc64-unknown-linux-gnu. Also regtested all three targets by modifying gfortran-dg.exp to also test with "-g -flto", no new failures observed. frontend: 2018-01-05 Janne BlomqvistPR fortran/78534 PR fortran/66310 * array.c (got_charlen): Use gfc_charlen_int_kind. * class.c (gfc_find_derived_vtab): Use gfc_size_kind instead of hardcoded kind. (find_intrinsic_vtab): Likewise. * decl.c (match_char_length): Use gfc_charlen_int_kind. (add_init_expr_to_sym): Use gfc_charlen_t and gfc_charlen_int_kind. (gfc_match_implicit): Use gfc_charlen_int_kind. * dump-parse-tree.c (show_char_const): Use gfc_charlen_t and size_t. (show_expr): Use HOST_WIDE_INT_PRINT_DEC. * expr.c (gfc_get_character_expr): Length parameter of type gfc_charlen_t. (gfc_get_int_expr): Value argument of type HOST_WIDE_INT. (gfc_extract_hwi): New function. (simplify_const_ref): Make string_len of type gfc_charlen_t. (gfc_simplify_expr): Use HOST_WIDE_INT for substring refs. * frontend-passes.c (optimize_trim): Use gfc_charlen_int_kind. * gfortran.h (gfc_mpz_get_hwi): New prototype. (gfc_mpz_set_hwi): Likewise. (gfc_charlen_t): New typedef. (gfc_expr): Use gfc_charlen_t for character lengths. (gfc_size_kind): New extern variable. (gfc_extract_hwi): New prototype. (gfc_get_character_expr): Use gfc_charlen_t for character length. (gfc_get_int_expr): Use HOST_WIDE_INT type for value argument. * gfortran.texi: Update description of hidden string length argument. * iresolve.c (check_charlen_present): Use gfc_charlen_int_kind. (gfc_resolve_char_achar): Likewise. (gfc_resolve_repeat): Pass string length directly without temporary, use gfc_charlen_int_kind. (gfc_resolve_transfer): Use gfc_charlen_int_kind. * match.c (select_intrinsic_set_tmp): Use HOST_WIDE_INT for charlen. * misc.c (gfc_mpz_get_hwi): New function. (gfc_mpz_set_hwi): New function. * module.c (atom_int): Change type from int to HOST_WIDE_INT. (parse_integer): Don't complain about large integers. (write_atom): Use HOST_WIDE_INT for integers. (mio_integer): Handle integer type mismatch. (mio_hwi): New function. (mio_intrinsic_op): Use HOST_WIDE_INT. (mio_array_ref): Likewise. (mio_expr): Likewise. * primary.c (match_substring): Use gfc_charlen_int_kind. * resolve.c (resolve_substring_charlen): Use gfc_charlen_int_kind. (resolve_character_operator): Likewise. (resolve_assoc_var): Likewise. (resolve_select_type): Use HOST_WIDE_INT for charlen, use snprintf. (resolve_charlen): Use mpz_sgn to
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #16 from Janne Blomqvist --- Author: jb Date: Fri Jan 13 17:05:48 2017 New Revision: 28 URL: https://gcc.gnu.org/viewcvs?rev=28=gcc=rev Log: PR 78534 Change character length from int to size_t In order to handle large character lengths on (L)LP64 targets, switch the GFortran character length from an int to a size_t. This is an ABI change, as procedures with character arguments take hidden arguments with the character length. I also changed the _size member in vtables from int to size_t, as there were some cases where character lengths and sizes were apparently mixed up and caused regressions otherwise. Although I haven't tested, this might enable very large derived types as well. Also, as there are some places in the frontend were negative character lengths are used as special flag values, in the frontend the character length is handled as a signed variable of the same size as a size_t, although in the runtime library it really is size_t. I haven't changed the character length variables for the co-array intrinsics, as this is something that may need to be synchronized with OpenCoarrays. This is v4 of the patch. v3 was applied but had to reverted due to breaking bootstrap. The fix is in resolve.c:resolve_charlen, where it's necessary to check that an expression is constant before using mpz_sgn. Overview of v3 of the patch: All the issues pointed out by FX's review of v2 have been fixed. In particular, there are now new functions gfc_mpz_get_hwi and gfc_mpz_set_hwi, similar to the GMP functions mpz_get_si and mpz_set_si, except that they get/set a HOST_WIDE_INT instead of a long value. Similarly, gfc_get_int_expr now takes a HOST_WIDE_INT instead of a long, gfc_extract_long is replaced by gfc_extract_hwi. Also, the preliminary work to handle gfc_charlen_type_node being unsigned has been removed. Regtested on x86_64-pc-linux-gnu and i686-pc-linux-gnu. frontend: 2017-01-13 Janne BlomqvistPR fortran/78534 PR fortran/66310 * class.c (gfc_find_derived_vtab): Use gfc_size_kind instead of hardcoded kind. (find_intrinsic_vtab): Likewise. * expr.c (gfc_get_character_expr): Length parameter of type gfc_charlen_t. (gfc_get_int_expr): Value argument of type HOST_WIDE_INT. (gfc_extract_hwi): New function. (simplify_const_ref): Make string_len of type gfc_charlen_t. (gfc_simplify_expr): Use HOST_WIDE_INT for substring refs. * gfortran.h (gfc_mpz_get_hwi): New prototype. (gfc_mpz_set_hwi): Likewise. (gfc_charlen_t): New typedef. (gfc_expr): Use gfc_charlen_t for character lengths. (gfc_size_kind): New extern variable. (gfc_extract_hwi): New prototype. (gfc_get_character_expr): Use gfc_charlen_t for character length. (gfc_get_int_expr): Use HOST_WIDE_INT type for value argument. * iresolve.c (gfc_resolve_repeat): Pass string length directly without temporary, use gfc_charlen_int_kind. * match.c (select_intrinsic_set_tmp): Use HOST_WIDE_INT for charlen. * misc.c (gfc_mpz_get_hwi): New function. (gfc_mpz_set_hwi): New function. * module.c (atom_int): Change type from int to HOST_WIDE_INT. (parse_integer): Don't complain about large integers. (write_atom): Use HOST_WIDE_INT for integers. (mio_integer): Handle integer type mismatch. (mio_hwi): New function. (mio_intrinsic_op): Use HOST_WIDE_INT. (mio_array_ref): Likewise. (mio_expr): Likewise. * resolve.c (resolve_select_type): Use HOST_WIDE_INT for charlen, use snprintf. (resolve_substring_charlen): Use gfc_charlen_int_kind. (resolve_charlen): Use mpz_sgn to determine sign. * simplify.c (gfc_simplify_repeat): Use HOST_WIDE_INT/gfc_charlen_t instead of long. * target-memory.c (size_character): Length argument of type gfc_charlen_t. (gfc_encode_character): Likewise. (gfc_interpret_character): Use gfc_charlen_t. * target-memory.h (gfc_encode_character): Modify prototype. * trans-array.c (get_array_ctor_var_strlen): Use gfc_conv_mpz_to_tree_type. * trans-const.c (gfc_conv_mpz_to_tree_type): New function. * trans-const.h (gfc_conv_mpz_to_tree_type): New prototype. * trans-expr.c (gfc_class_len_or_zero_get): Build const of type gfc_charlen_type_node. (gfc_conv_intrinsic_to_class): Use gfc_charlen_int_kind instead of 4, fold_convert to correct type. (gfc_conv_class_to_class): Build const of type size_type_node for size. (gfc_copy_class_to_class): Likewise. (gfc_conv_string_length): Use same type in expression. (gfc_conv_substring): Likewise, use HOST_WIDE_INT for charlen. (gfc_conv_string_tmp): Make sure len is of the right type.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #14 from Dominique d'Humieres --- On x86_64-apple-darwin15 with 16Gb of RAM and ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 256 pipe size(512 bytes, -p) 1 stack size (kbytes, -s) 65532 cpu time (seconds, -t) unlimited max user processes (-u) 709 virtual memory (kbytes, -v) unlimited with the patch at https://gcc.gnu.org/ml/fortran/2016-07/msg00097.html compiling the test program p character(len=2,kind=4), parameter :: z = 'yz' print *, repeat(z, 2**25) end fails at compile time with f951(36102,0x7fff74e38000) malloc: *** mach_vm_map(size=18446744073441116160) failed (error code=3) Compiling the following tests with -m64 (z is no longer a parameter) program p character :: z = 'z' print *, repeat(z, huge(1)-2**9) end gives a.out(92056,0x7fff74e38000) malloc: *** mach_vm_map(size=18446744071562067968) failed (error code=3) *** error: can't allocate region program p character(len=2,kind=4) :: z = 'yz' print *, repeat(z, huge(1)/8+2) end and Program received signal SIGSEGV: Segmentation fault - invalid memory reference. The codes execute without any problem if the repeat counts are decremented by one (tested 1024 times for the first case). Compiling the following code with -m32 program p character :: z = 'z' print *, repeat(z, 2**30-2**21+2**12-1) end gave an executable failing 7 times over 2048 runs with ... real0m5.318s user0m1.058s sys 0m1.860s a.out(49086,0xa37d2000) malloc: *** mach_vm_map(size=1071652864) 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 xrealloc Error termination. Backtrace: #0 0x758f #1 0x824d #2 0x845f #3 0x6dbb #4 0xbd1a4 #5 0xafcfc #6 0xb7832 #7 0xbcda5 #8 0xafb26 #9 0x2dff #10 0x2e5f real0m1.197s user0m0.787s sys 0m0.373s ... while decrementing the repeat count by one runs 2048 times without failure. Also program p character :: z = 'z' print *, repeat(z, 2**30-2**20) end fails at run time with a.out(35477,0xa37d2000) malloc: *** mach_vm_map(size=1072697344) failed (error code=3)
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #13 from Jerry DeLisle --- (In reply to Jerry DeLisle from comment #12) --- snip --- > > f951: out of memory allocating 18446744073441116160 bytes after a total of > 569344 bytes > I should mention there is really nothing wrong with this error message, it just confuses people. My latest patch will give: Error: Argument NCOPIES of REPEAT intrinsic is too large at (1)
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #12 from Jerry DeLisle --- I have found that there is a practical limit of 2**28-1 on the size. The test case: program p character, parameter :: z = 'z' print *, repeat(z, (268435456)) ! 2**28 end gives when compiled: f951: out of memory allocating 18446744073441116160 bytes after a total of 569344 bytes The binary representation of the large number is: The memory is exceeded during some allocation during the resolution phase in resolve.c. For now I propose setting the limit in gfc_simplify_repeat to 2**28-1 which then catches the error condition and is more than adequate. I would then like to open a new PR regarding the above error message. It may be that we need to set a limit in gfc_get_character_expr to catch this more globally. In many places we are using signed int rather than size_t and we can get all kinds of problems from this.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #11 from Jerry DeLisle --- Latest patch posted here. https://gcc.gnu.org/ml/fortran/2016-07/msg00046.html Still testing.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 Jerry DeLisle changed: What|Removed |Added Attachment #37811|0 |1 is obsolete|| --- Comment #10 from Jerry DeLisle --- Created attachment 38723 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38723=edit A better patch This patch sets a hard limit on the maximum number of copies in a repeat. I picked a somewhat arbitrary a limit of 1 since this worked on my machine with out consuming all memory and crippling the system.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #9 from Jerry DeLisle --- (In reply to Dominique d'Humieres from comment #8) ... snip ... > before the patch and with > > pr66310_1.f90:3:0: > >print *, repeat(z, huge(1_4)) > > internal compiler error: Segmentation fault: 11 > > after the patch. The patch fixes two places where the signed integer wrapped giving the 18446744065119617024 message. The Segfault you have noted is in yet another place where some address is getting exceeded. I also found this problem and it will require further tracking.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #8 from Dominique d'Humieres --- > Created attachment 37811 > --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37811=edit > Proposed patch > > This patch fixes some signed integer problems in a few places and allows the > test case to compile on my machine up to a size of 2**26 or so before I run > out > of memory. After having applied the patch, the only change I see is for a variant of the test in comment 3 program p character, parameter :: z = 'z' print *, repeat(z, huge(1_4)) end which fails at compile time with f951: out of memory allocating 18446744065119617024 bytes after a total of 0 bytes before the patch and with pr66310_1.f90:3:0: print *, repeat(z, huge(1_4)) internal compiler error: Segmentation fault: 11 after the patch.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #7 from Jerry DeLisle --- Created attachment 37811 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37811=edit Proposed patch This patch fixes some signed integer problems in a few places and allows the test case to compile on my machine up to a size of 2**26 or so before I run out of memory.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #6 from Jerry DeLisle --- When using the REPEAT intrinsic as a parameter, the frontend is simplifying this to an actual string constant of the requested length. In this process it is attempting to allocate length + 1 in order to internally NULL terminate the string. The NULL termination is not strictly needed and when I remove it on my system I get the expected results: f951: out of memory allocating 8589934588 bytes after a total of 569344 bytes Each character is a wide character to accommodate different encodings and in this case is 4 bytes. When trying to allocate len + 1 where len is huge, the result is wrapped, signed vs unsigned integers. I am tempted to put in an arbitrary limit on the size of string constants and issue a warning when it happens and truncate the result to the allowed limit. This would give a more useful message. If I were to do this, what would be a reasonable limit for string constants? How about 2^30 = 1073741824? The other choice we have here is do nothing and close this as WON'T FIX. Although the error message we get from the OS: "f951: out of memory allocating 18446744065119617024 " is confusing. I can cast the signed integer length to uint32_t and avoid the big number. Any opinions?
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 Jerry DeLisle changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |jvdelisle at gcc dot gnu.org --- Comment #5 from Jerry DeLisle --- Taking this so it shows up on my search.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #4 from Jerry DeLisle jvdelisle at gcc dot gnu.org --- (In reply to Gerhard Steinmetz from comment #3) I do agree, that some extra temporary data is necessary and there should be a practical (high) limit for something like that. Let the helper buffers be five or ten times the amount of the effectively written data. That's OK. But it's not a billion times as suggested by the huge number 18446744065119617024. Something IS going wrong here. I agree, I don't understand this either.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 Dominique d'Humieres dominiq at lps dot ens.fr changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2015-05-28 Ever confirmed|0 |1 --- Comment #2 from Dominique d'Humieres dominiq at lps dot ens.fr --- If I replace the line print *, repeat(z, huge(1_4)) with print *, repeat(z, 26250) in the second code of comment 0, the code compiles, not with print *, repeat(z, 27500) f951(2361,0x7fff72381300) malloc: *** mach_vm_map(size=18446744073447682048) failed (error code=3) Note that 27500 is well below the 16Gb of memory I have on my machine and I don't understand why gfortran needs to allocate 18446744073447682048 bytes.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 --- Comment #3 from Gerhard Steinmetz gerhard.steinmetz.fort...@t-online.de --- I do agree, that some extra temporary data is necessary and there should be a practical (high) limit for something like that. Let the helper buffers be five or ten times the amount of the effectively written data. That's OK. But it's not a billion times as suggested by the huge number 18446744065119617024. Something IS going wrong here. --- Indeed, there is an actual limit at about 2^28 = 268435456 for the second case. That's plenty enough. But the point is (sorry for being late) : $ cat zlim_hd8m.f90 program p character, parameter :: z = 'z' print *, repeat(z, 268435450) end $ gfortran zlim_hd8m.f90 $ a.out l $ wc l 1 1 268435452 l $ cat zlim_hd8p.f90 program p character, parameter :: z = 'z' print *, repeat(z, 268435460) end $ gfortran zlim_hd8p.f90 f951: out of memory allocating 18446744073441116164 bytes after a total of 430080 bytes --- For the first test case the limit is just below 2^31. This is really enough. No code change is needed, IMO. Only the message invalid memory reference was misleading the first time, therefore a reduction and investigation of some variations. Thank you.
[Bug fortran/66310] Problems with intrinsic repeat for large number of copies
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66310 Jerry DeLisle jvdelisle at gcc dot gnu.org changed: What|Removed |Added CC||jvdelisle at gcc dot gnu.org --- Comment #1 from Jerry DeLisle jvdelisle at gcc dot gnu.org --- I do not think this is a bug. First the function repeat is evaluated and the result must allocate a large amount of memory to hold the constant z. Then when writing the constant out, a buffer is created which requires another allocation, and finally since this is formatted output, though list directed, the routines have to account for things like positioning of the formatted result and thus we have another buffer to support all the unanticipated things that may have to be done to the output. The fbuf is dynamically sized as needed and in this case gets large also. So there is a practical limit you are hitting with this obscure case. I would lean toward a don't fix on this one. Putting it another way, why should we develop special code just to handle this case? Yes we could turn it into a big do loop rather than a large constant, it's just not worth the effort.