Bug 33386 - Fortran SELECT statement miscompiles
Summary: Fortran SELECT statement miscompiles
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: 4.3.0
Assignee: Francois-Xavier Coudert
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2007-09-11 09:42 UTC by jpr
Modified: 2007-09-11 14:54 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-09-11 10:27:39


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jpr 2007-09-11 09:42:06 UTC
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
Comment 1 Francois-Xavier Coudert 2007-09-11 10:27:39 UTC
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?
Comment 2 Andrew Pinski 2007-09-11 10:38:08 UTC
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.
Comment 3 jpr 2007-09-11 10:42:53 UTC
(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);
  }
}
Comment 4 Francois-Xavier Coudert 2007-09-11 10:48:56 UTC
> 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;
Comment 5 jpr 2007-09-11 12:49:28 UTC
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.
>
Comment 6 Francois-Xavier Coudert 2007-09-11 14:53:13 UTC
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

Comment 7 Francois-Xavier Coudert 2007-09-11 14:54:06 UTC
Fixed. Thanks for the bug report.