gcc information:

    Using built-in specs.
    Target: i686-linux
    Configured with: ../gcc-4.1.1/configure
--prefix=/build/toolchain/lin32/gcc-4.1.1 --disable-nls --enable-shared
--enable-threads=posix --enable-languages=c,c++ --with-gnu-as --with-gnu-ld
--target=i686-linux
--with-as=/build/toolchain/lin32/binutils-2.16.1-vt/bin/i686-linux-as
--with-ld=/build/toolchain/lin32/binutils-2.16.1-vt/bin/i686-linux-ld
--enable-__cxa_atexit --with-sysroot=/build/toolchain/lin32/glibc-2.2.5-44
--disable-tls
    Thread model: posix
    gcc version 4.1.1

When using the following script (which is probably only suitable for
my work environment):

    #!/bin/bash

    SRCDIR="/tmp/gcc4-error";
    GCC4="/build/toolchain/lin32/gcc-4.1.1/bin/i686-linux-gcc
--sysroot=/build/toolchain/lin32/glibc-2.2.5-44";

    ${GCC4} -v

    for OPT in $(seq 0 3) ; do
        OUTPUT="${SRCDIR}/error-O${OPT}";
        GCC_OPT="-Wall -Werror -O${OPT} -g3 --save-temps";
        echo "Executing with optimization -O${OPT}"
        rm -f ${OUTPUT};
        ${GCC4} ${GCC_OPT} -o ${OUTPUT} ${SRCDIR}/error.c
        ${OUTPUT}
    done;

to compile the following source:

    #include <stdio.h>

    static const int loop_start = 118;
    static const int loop_end   = 127;

    void fails_0_at_O1_O2(char *arr, int l)
    {
       int i;
       for (i = loop_start; i < loop_end; ++i) {
          printf("%s: arr[%3d] = %4d\t(char)(i + 5) = %3d\n",
                 __PRETTY_FUNCTION__, i, arr[i], (char)(i + 5));
       }
       printf("\n");
    }

    void fails_1_at_O1_O2(char *arr, int l)
    {
       int  i;
       for (i = loop_start; i < loop_end; ++i) {
          char v = i + 5;
          printf("%s: arr[%3d] = %4d\tv = %3d\n",
                 __PRETTY_FUNCTION__, i, arr[i], v);
       }
       printf("\n");
    }

    void works_at_all_O_levels(char *arr, int l)
    {
       int i;
       for (i = loop_start; i < loop_end; ++i) {
          volatile char v = i + 5;
          printf("%s: arr[%3d] = %4d\tv = %3d\n",
                 __PRETTY_FUNCTION__, i, arr[i], v);
       }
       printf("\n");
    }

    int main(void)
    {
       const int l = 190;
       char      arr[256];
       int       i;

       for (i = 0; i < l; ++i) {
          arr[i] = (char)(i + 5);
       }

       fails_0_at_O1_O2(arr, l);
       fails_1_at_O1_O2(arr, l);
       works_at_all_O_levels(arr, l);
       return 0;
    }

At optimization levels {0..3}, the compiler does not honor the cast of
the 'i + 5' at levels O1 and O2.

The output for all optimization levels, around the boundary case, is
shown below.  Notice how the value based on the induction variable
does not wrap to -128 in O1 and O2.

      Executing with optimization -O0
      fails_0_at_O1_O2: arr[118] =  123 (char)(i + 5) = 123
      fails_0_at_O1_O2: arr[119] =  124 (char)(i + 5) = 124
      fails_0_at_O1_O2: arr[120] =  125 (char)(i + 5) = 125
      fails_0_at_O1_O2: arr[121] =  126 (char)(i + 5) = 126
      fails_0_at_O1_O2: arr[122] =  127 (char)(i + 5) = 127
      fails_0_at_O1_O2: arr[123] = -128 (char)(i + 5) = -128
      fails_0_at_O1_O2: arr[124] = -127 (char)(i + 5) = -127
      fails_0_at_O1_O2: arr[125] = -126 (char)(i + 5) = -126
      fails_0_at_O1_O2: arr[126] = -125 (char)(i + 5) = -125

      fails_1_at_O1_O2: arr[118] =  123 v = 123
      fails_1_at_O1_O2: arr[119] =  124 v = 124
      fails_1_at_O1_O2: arr[120] =  125 v = 125
      fails_1_at_O1_O2: arr[121] =  126 v = 126
      fails_1_at_O1_O2: arr[122] =  127 v = 127
      fails_1_at_O1_O2: arr[123] = -128 v = -128
      fails_1_at_O1_O2: arr[124] = -127 v = -127
      fails_1_at_O1_O2: arr[125] = -126 v = -126
      fails_1_at_O1_O2: arr[126] = -125 v = -125

      works_at_all_O_levels: arr[118] =  123    v = 123
      works_at_all_O_levels: arr[119] =  124    v = 124
      works_at_all_O_levels: arr[120] =  125    v = 125
      works_at_all_O_levels: arr[121] =  126    v = 126
      works_at_all_O_levels: arr[122] =  127    v = 127
      works_at_all_O_levels: arr[123] = -128    v = -128
      works_at_all_O_levels: arr[124] = -127    v = -127
      works_at_all_O_levels: arr[125] = -126    v = -126
      works_at_all_O_levels: arr[126] = -125    v = -125

      Executing with optimization -O1
      fails_0_at_O1_O2: arr[118] =  123 (char)(i + 5) = 123
      fails_0_at_O1_O2: arr[119] =  124 (char)(i + 5) = 124
      fails_0_at_O1_O2: arr[120] =  125 (char)(i + 5) = 125
      fails_0_at_O1_O2: arr[121] =  126 (char)(i + 5) = 126
      fails_0_at_O1_O2: arr[122] =  127 (char)(i + 5) = 127
      fails_0_at_O1_O2: arr[123] = -128 (char)(i + 5) = 128
      fails_0_at_O1_O2: arr[124] = -127 (char)(i + 5) = 129
      fails_0_at_O1_O2: arr[125] = -126 (char)(i + 5) = 130
      fails_0_at_O1_O2: arr[126] = -125 (char)(i + 5) = 131

      fails_1_at_O1_O2: arr[118] =  123 v = 123
      fails_1_at_O1_O2: arr[119] =  124 v = 124
      fails_1_at_O1_O2: arr[120] =  125 v = 125
      fails_1_at_O1_O2: arr[121] =  126 v = 126
      fails_1_at_O1_O2: arr[122] =  127 v = 127
      fails_1_at_O1_O2: arr[123] = -128 v = 128
      fails_1_at_O1_O2: arr[124] = -127 v = 129
      fails_1_at_O1_O2: arr[125] = -126 v = 130
      fails_1_at_O1_O2: arr[126] = -125 v = 131

      works_at_all_O_levels: arr[118] =  123    v = 123
      works_at_all_O_levels: arr[119] =  124    v = 124
      works_at_all_O_levels: arr[120] =  125    v = 125
      works_at_all_O_levels: arr[121] =  126    v = 126
      works_at_all_O_levels: arr[122] =  127    v = 127
      works_at_all_O_levels: arr[123] = -128    v = -128
      works_at_all_O_levels: arr[124] = -127    v = -127
      works_at_all_O_levels: arr[125] = -126    v = -126
      works_at_all_O_levels: arr[126] = -125    v = -125

      Executing with optimization -O2
      fails_0_at_O1_O2: arr[118] =  123 (char)(i + 5) = 123
      fails_0_at_O1_O2: arr[119] =  124 (char)(i + 5) = 124
      fails_0_at_O1_O2: arr[120] =  125 (char)(i + 5) = 125
      fails_0_at_O1_O2: arr[121] =  126 (char)(i + 5) = 126
      fails_0_at_O1_O2: arr[122] =  127 (char)(i + 5) = 127
      fails_0_at_O1_O2: arr[123] = -128 (char)(i + 5) = 128
      fails_0_at_O1_O2: arr[124] = -127 (char)(i + 5) = 129
      fails_0_at_O1_O2: arr[125] = -126 (char)(i + 5) = 130
      fails_0_at_O1_O2: arr[126] = -125 (char)(i + 5) = 131

      fails_1_at_O1_O2: arr[118] =  123 v = 123
      fails_1_at_O1_O2: arr[119] =  124 v = 124
      fails_1_at_O1_O2: arr[120] =  125 v = 125
      fails_1_at_O1_O2: arr[121] =  126 v = 126
      fails_1_at_O1_O2: arr[122] =  127 v = 127
      fails_1_at_O1_O2: arr[123] = -128 v = 128
      fails_1_at_O1_O2: arr[124] = -127 v = 129
      fails_1_at_O1_O2: arr[125] = -126 v = 130
      fails_1_at_O1_O2: arr[126] = -125 v = 131

      works_at_all_O_levels: arr[118] =  123    v = 123
      works_at_all_O_levels: arr[119] =  124    v = 124
      works_at_all_O_levels: arr[120] =  125    v = 125
      works_at_all_O_levels: arr[121] =  126    v = 126
      works_at_all_O_levels: arr[122] =  127    v = 127
      works_at_all_O_levels: arr[123] = -128    v = -128
      works_at_all_O_levels: arr[124] = -127    v = -127
      works_at_all_O_levels: arr[125] = -126    v = -126
      works_at_all_O_levels: arr[126] = -125    v = -125

      Executing with optimization -O3
      fails_0_at_O1_O2: arr[118] =  123 (char)(i + 5) = 123
      fails_0_at_O1_O2: arr[119] =  124 (char)(i + 5) = 124
      fails_0_at_O1_O2: arr[120] =  125 (char)(i + 5) = 125
      fails_0_at_O1_O2: arr[121] =  126 (char)(i + 5) = 126
      fails_0_at_O1_O2: arr[122] =  127 (char)(i + 5) = 127
      fails_0_at_O1_O2: arr[123] = -128 (char)(i + 5) = -128
      fails_0_at_O1_O2: arr[124] = -127 (char)(i + 5) = -127
      fails_0_at_O1_O2: arr[125] = -126 (char)(i + 5) = -126
      fails_0_at_O1_O2: arr[126] = -125 (char)(i + 5) = -125

      fails_1_at_O1_O2: arr[118] =  123 v = 123
      fails_1_at_O1_O2: arr[119] =  124 v = 124
      fails_1_at_O1_O2: arr[120] =  125 v = 125
      fails_1_at_O1_O2: arr[121] =  126 v = 126
      fails_1_at_O1_O2: arr[122] =  127 v = 127
      fails_1_at_O1_O2: arr[123] = -128 v = -128
      fails_1_at_O1_O2: arr[124] = -127 v = -127
      fails_1_at_O1_O2: arr[125] = -126 v = -126
      fails_1_at_O1_O2: arr[126] = -125 v = -125

      works_at_all_O_levels: arr[118] =  123    v = 123
      works_at_all_O_levels: arr[119] =  124    v = 124
      works_at_all_O_levels: arr[120] =  125    v = 125
      works_at_all_O_levels: arr[121] =  126    v = 126
      works_at_all_O_levels: arr[122] =  127    v = 127
      works_at_all_O_levels: arr[123] = -128    v = -128
      works_at_all_O_levels: arr[124] = -127    v = -127
      works_at_all_O_levels: arr[125] = -126    v = -126
      works_at_all_O_levels: arr[126] = -125    v = -125


-- 
           Summary: Cast on expression using induction variable not honored
                    at O1 and O2
           Product: gcc
           Version: 4.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: thutt at vmware dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31327

Reply via email to