Hi, In my application a wrong CASE is occationally selected in a SELECT statement. I've not been able to reduce the code to do the wrong jump. However, the following simple code run through valgrind gives uninitialized variable warnings, which i think might be the source of the problem: PROGRAM test REAL :: x = 0 SELECT CASE( getstring() ) CASE('a') x = 1 CASE('b') x = 2 END SELECT PRINT*,x CONTAINS FUNCTION getstring() RESULT(s) CHARACTER(LEN=1) :: s s = 'c' END FUNCTION getstring END PROGRAM test Driving: gfortran -v -O0 -g -o a a.f90 -lgfortranbegin -lgfortran -lm -shared-libgcc Using built-in specs. Target: i386-pc-linux-gnu Configured with: /home/fx/gfortran_nightbuild/trunk/configure --prefix=/home/fx/gfortran_nightbuild/irun-20070910 --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 20070910 (experimental) [trunk revision 128320] (GCC) COLLECT_GCC_OPTIONS='-v' '-O0' '-g' '-o' 'a' '-shared-libgcc' '-mtune=i386' /home/wrk/jpr/irun/bin/../libexec/gcc/i386-pc-linux-gnu/4.3.0/f951 a.f90 -quiet -dumpbase a.f90 -mtune=i386 -auxbase a -g -O0 -version -fintrinsic-modules-path /home/wrk/jpr/irun/bin/../lib/gcc/i386-pc-linux-gnu/4.3.0/finclude -o /tmp/ccouIARh.s GNU F95 (GCC) version 4.3.0 20070910 (experimental) [trunk revision 128320] (i386-pc-linux-gnu) compiled by GNU C version 4.3.0 20070910 (experimental) [trunk revision 128320], GMP version 4.2.1, MPFR version 2.2.1. GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=64211 COLLECT_GCC_OPTIONS='-v' '-O0' '-g' '-o' 'a' '-shared-libgcc' '-mtune=i386' as -V -Qy -o /tmp/ccGk0ias.o /tmp/ccouIARh.s GNU assembler version 2.15.92.0.2 (i386-redhat-linux) using BFD version 2.15.92.0.2 20040927 COMPILER_PATH=/home/wrk/jpr/irun/bin/../libexec/gcc/i386-pc-linux-gnu/4.3.0/:/home/wrk/jpr/irun/bin/../libexec/gcc/ LIBRARY_PATH=/home/wrk/jpr/irun/bin/../lib/gcc/i386-pc-linux-gnu/4.3.0/:/home/wrk/jpr/irun/bin/../lib/gcc/:/home/wrk/jpr/irun/bin/../lib/gcc/i386-pc-linux-gnu/4.3.0/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-O0' '-g' '-o' 'a' '-shared-libgcc' '-mtune=i386' /home/wrk/jpr/irun/bin/../libexec/gcc/i386-pc-linux-gnu/4.3.0/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o a /usr/lib/crt1.o /usr/lib/crti.o /home/wrk/jpr/irun/bin/../lib/gcc/i386-pc-linux-gnu/4.3.0/crtbegin.o -L/home/wrk/jpr/irun/bin/../lib/gcc/i386-pc-linux-gnu/4.3.0 -L/home/wrk/jpr/irun/bin/../lib/gcc -L/home/wrk/jpr/irun/bin/../lib/gcc/i386-pc-linux-gnu/4.3.0/../../.. /tmp/ccGk0ias.o -lgfortranbegin -lgfortran -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /home/wrk/jpr/irun/bin/../lib/gcc/i386-pc-linux-gnu/4.3.0/crtend.o /usr/lib/crtn.o valgrind ./a ==4319== Memcheck, a memory error detector. ==4319== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==4319== Using LibVEX rev 1575, a library for dynamic binary translation. ==4319== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP. ==4319== Using valgrind-3.1.1, a dynamic binary instrumentation framework. ==4319== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==4319== For more details, rerun with: -v ==4319== ==4319== Conditional jump or move depends on uninitialised value(s) ==4319== at 0x80485CE: MAIN__ (a.f90:4) ==4319== by 0x8048690: main (fmain.c:21) ==4319== ==4319== Conditional jump or move depends on uninitialised value(s) ==4319== at 0x80485D7: MAIN__ (a.f90:4) ==4319== by 0x8048690: main (fmain.c:21) 0.000000 ==4319== ==4319== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 17 from 1) ==4319== malloc/free: in use at exit: 0 bytes in 0 blocks. ==4319== malloc/free: 11 allocs, 11 frees, 25,425 bytes allocated. ==4319== For counts of detected errors, rerun with: -v ==4319== All heap blocks were freed -- no leaks are possible. Adding a default case gets rid of the problems, also for my real application code. Regards, Juha
I'll work on that, I've re-written CHARACTER SELECT recently. However, I can't reproduce this on x86_64-linux. Could you run "gfortran -fdump-tree-original a.f90" and post the a.f90.003t.original file produced?
int select_string (select_struct *table, int table_len, const char *selector, int selector_len) { select_struct *t; int i, low, high, mid; int default_jump; The issue is default_jump is used uninitialized.
(In reply to comment #1) > I'll work on that, I've re-written CHARACTER SELECT recently. However, I can't > reproduce this on x86_64-linux. Could you run "gfortran -fdump-tree-original > a.f90" and post the a.f90.003t.original file produced? > Hi, OK thanks. The .original file below is for this code: PROGRAM test CHARACTER :: c='c' REAL :: x = 0 SELECT CASE(c) CASE('a') x = 1 CASE('b') x = 2 END SELECT PRINT*,x END PROGRAM test with the same valgrind warnings: MAIN__ () { static real4 x = 0.0; static char c[1:1] = "c"; static int4 options.0[7] = {68, 127, 0, 0, 0, 1, 0}; _gfortran_set_options (7, (void *) &options.0); { int4 case_num.2; static struct _jump_struct jumptable.1[2] = {{.string1=&"a"[1]{lb: 1 sz: 1}, .string1_len=1, .string2=&"a"[1]{lb: 1 sz: 1}, .string2_len=1, .target=0}, {.string1=&"b"[1]{lb: 1 sz: 1}, .string1_len=1, .string2=&"b"[1]{lb: 1 sz: 1}, .string2_len=1, .target=1}}; case_num.2 = _gfortran_select_string ((void *) &jumptable.1, 2, &c[1]{lb: 1 sz: 1}, 1); switch (case_num.2) { case 0 ... 0:; x = 1.0e+0; goto L.1; case 1 ... 1:; x = 2.0e+0; goto L.1; } L.1:; } { struct __st_parameter_dt dt_parm.3; dt_parm.3.common.filename = &"a.f90"[1]{lb: 1 sz: 1}; dt_parm.3.common.line = 11; dt_parm.3.common.flags = 128; dt_parm.3.common.unit = 6; _gfortran_st_write (&dt_parm.3); _gfortran_transfer_real (&dt_parm.3, &x, 4); _gfortran_st_write_done (&dt_parm.3); } }
> Adding a default case gets rid of the problems, also for my real application > code. If you're in a position to build the compiler yourself, could you try the following patch? I think it should fix the problem (thanks Andrew for spotting the initialized variable). Index: libgfortran/runtime/select.c =================================================================== --- libgfortran/runtime/select.c (revision 127830) +++ libgfortran/runtime/select.c (working copy) @@ -53,7 +53,7 @@ select_string (select_struct *table, int { select_struct *t; int i, low, high, mid; - int default_jump; + int default_jump = -1; if (table_len == 0) return -1;
Subject: Re: Fortran SELECT statement miscompiles Yes, this seems to do the trick. Thanx, Juha > > > ------- Comment #4 from fxcoudert at gcc dot gnu dot org 2007-09-11 10:48 ------- >> Adding a default case gets rid of the problems, also for my real application >> code. > > If you're in a position to build the compiler yourself, could you try the > following patch? I think it should fix the problem (thanks Andrew for spotting > the initialized variable). > > > Index: libgfortran/runtime/select.c > =================================================================== > --- libgfortran/runtime/select.c (revision 127830) > +++ libgfortran/runtime/select.c (working copy) > @@ -53,7 +53,7 @@ select_string (select_struct *table, int > { > select_struct *t; > int i, low, high, mid; > - int default_jump; > + int default_jump = -1; > > if (table_len == 0) > return -1; > > > -- > > fxcoudert at gcc dot gnu dot org changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Keywords| |patch > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33386 > > ------- You are receiving this mail because: ------- > You reported the bug, or are watching the reporter. >
Subject: Bug 33386 Author: fxcoudert Date: Tue Sep 11 14:53:02 2007 New Revision: 128379 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128379 Log: PR libfortran/33386 * runtime/select.c (select_string): Initialize default_jump. Modified: trunk/libgfortran/ChangeLog trunk/libgfortran/runtime/select.c
Fixed. Thanks for the bug report.