With this program I get a runtime error message Fortran runtime error: Attempt to allocate a negative amount of memory. The error occurs at line 33. I suspect the "allocation" is the constant array actual argument (/name/). This program is a little longer than I like my bug reports to be, but any attempt to shorten it changes the error to a segmentation fault, except for removing the print statement in the main program which results in the program running correctly. mitchell@speedy> gfortran --version GNU Fortran (GCC) 4.3.0 20071023 (experimental) [trunk revision 129569] Copyright (C) 2007 Free Software Foundation, Inc. mitchell@speedy> gfortran bug071024.f90 mitchell@speedy> a.out something Fortran runtime error: Attempt to allocate a negative amount of memory.
Created attachment 14405 [details] this is the program
> Fortran runtime error: Attempt to allocate a negative amount of memory. This error usually means that you allocate that much memory that an integer(4) variable overflows. I cannot reproduce the error here with -m32 or -m64 on x86_64/Linux (20071016 (experimental) [trunk revision 129378]). (Using valgrind I get a lot of unintialized-variable warnings which are due to the fact that create_watch_actual is only a stub.) Which platform are you using (CPU + operating system; "gfortran -v" shows this in the "Target:" line.)
(In reply to comment #2) Sorry I forgot to give the computer information. This is a 32 bit CentOS 5 Linux distribution on an Intel Core 2 Duo T7700 mitchell@speedy> gfortran -v Using built-in specs. Target: i386-pc-linux-gnu Configured with: /home/fx/gfortran_nightbuild/trunk/configure --prefix=/home/fx/gfortran_nightbuild/irun-20071023 --enable-languages=c,fortran --build=i386-pc-linux-gnu --enable-checking=release --with-gmp=/home/fx/gfortran_nightbuild/software Thread model: posix gcc version 4.3.0 20071023 (experimental) [trunk revision 129569] (GCC) mitchell@speedy> uname -a Linux speedy.cam.nist.gov 2.6.18-8.1.10.el5 #1 SMP Thu Sep 13 12:17:54 EDT 2007 i686 i686 i386 GNU/Linux
In order to make the testcase valid, subroutine option_stopwatch_a needs to be replaced by: subroutine option_stopwatch_a(default_clock) character(len=*), intent(in), dimension(:) :: default_clock allocate(default_clocks(size(default_clock))) end subroutine option_stopwatch_a In that case it segfaults with gfortran and runs fine .e.g. with g95 and NAG, also the g95 run is clean within valgrind, but gives several errors with gfortran: ==16592== Conditional jump or move depends on uninitialised value(s) ==16592== at 0x4011EE: __stopwatch_MOD_create_watch_ss (test.f90:33) ==16592== by 0x401A71: MAIN__ (test.f90:59) ==16592== by 0x401AAB: main (fmain.c:21) ==16592== ==16592== Conditional jump or move depends on uninitialised value(s) ==16592== at 0x401207: __stopwatch_MOD_create_watch_ss (test.f90:33) ==16592== by 0x401A71: MAIN__ (test.f90:59) ==16592== by 0x401AAB: main (fmain.c:21) ==16592== ==16592== Conditional jump or move depends on uninitialised value(s) ==16592== at 0x4A225FA: memcpy (mc_replace_strmem.c:406) ==16592== by 0x401271: __stopwatch_MOD_create_watch_ss (test.f90:33) ==16592== by 0x401A71: MAIN__ (test.f90:59) ==16592== by 0x401AAB: main (fmain.c:21) ==16592== ==16592== Conditional jump or move depends on uninitialised value(s) ==16592== at 0x4012D5: __stopwatch_MOD_create_watch_ss (test.f90:33) ==16592== by 0x401A71: MAIN__ (test.f90:59) ==16592== by 0x401AAB: main (fmain.c:21) ==16592== ==16592== Conditional jump or move depends on uninitialised value(s) ==16592== at 0x4012EE: __stopwatch_MOD_create_watch_ss (test.f90:33) ==16592== by 0x401A71: MAIN__ (test.f90:59) ==16592== by 0x401AAB: main (fmain.c:21) ==16592== ==16592== Conditional jump or move depends on uninitialised value(s) ==16592== at 0x4A225FA: memcpy (mc_replace_strmem.c:406) ==16592== by 0x4013A0: __stopwatch_MOD_create_watch_ss (test.f90:33) ==16592== by 0x401A71: MAIN__ (test.f90:59) ==16592== by 0x401AAB: main (fmain.c:21) which look as if they could be related to the optional character arguments.
I'm guess-changing the summary
reduced testcase still failing with valgrind character(len=4), dimension(4) :: default_clocks="" call create_watch_ss('total') contains subroutine create_watch_actual(clock,name) character(len=*), dimension(:) :: clock character(len=*), dimension(:) :: name end subroutine create_watch_actual subroutine create_watch_ss(name,clock) character(len=*), optional :: clock character(len=*) :: name if (present(clock)) then call create_watch_actual((/clock/),(/name/)) else call create_watch_actual(default_clocks,(/name/)) end if end subroutine create_watch_ss end
Works: 2007-07-13-r126613 Fails: 2007-07-16-r126671
Reduced-reduced testcase which still triggers valgrind: call create_watch_ss(" ") contains subroutine create_watch_actual(name) character(len=1) :: name(1) end subroutine create_watch_actual subroutine create_watch_ss(name,clock) character(len=*) :: name integer, optional :: clock if (present(clock)) then call create_watch_actual((/name/)) else call create_watch_actual((/name/)) end if end subroutine create_watch_ss end It's apparent form the dump that, in the second branch of the IF, we use variables declared in the first branch.
And the smaller testcase with invalid dump: subroutine create_watch_ss (name,l) character(len=*) :: name logical l if (l) then call create_watch_actual([name]) else call create_watch_actual([name]) end if end
FX, I believe that the fix is something like: Index: gcc/fortran/trans-array.c =================================================================== *** gcc/fortran/trans-array.c (revision 129505) --- gcc/fortran/trans-array.c (working copy) *************** gfc_conv_array_parameter (gfc_se * se, g *** 4965,4972 **** if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER) { get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp); ! expr->ts.cl->backend_decl = gfc_evaluate_now (tmp, &se->pre); ! se->string_length = expr->ts.cl->backend_decl; } /* Is this the result of the enclosing procedure? */ --- 4972,4979 ---- if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER) { get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp); ! expr->ts.cl->backend_decl = tmp; ! se->string_length = gfc_evaluate_now (tmp, &se->pre); } /* Is this the result of the enclosing procedure? */ Fixing the value of a cl->backend_decl has the observed consequences because, in some cases like this one, the expr->ts.cl is a copy of a variable cl. This survives dg.expr=gfortran.dg/char* but beyond that I am not in a position to go. Please make use of it as you will. Cheers Paul PS It's my fault!
Subject: Bug 33881 Author: fxcoudert Date: Sat Nov 3 22:12:03 2007 New Revision: 129874 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129874 Log: PR fortran/33881 * trans-array.c (gfc_conv_array_parameter): Evaluate se->string_length instead of the expr->ts.cl->backend_decl. * gfortran.dg/assumed_charlen_arg_1.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/assumed_charlen_arg_1.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-array.c trunk/gcc/testsuite/ChangeLog
Fixed. Thanks Paul!