See below. The output at -O0 looks good. At -O3 the wrong result is printed
and valgrind reports a read of uninitialized memory.
reg...@john-home:~/volatile/tmp160$ current-gcc -O0 -Wall small.c -o small
reg...@john-home:~/volatile/tmp160$ valgrind ./small
==26152== Memcheck, a memory error detector.
==26152== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==26152== Using LibVEX rev 1804, a library for dynamic binary translation.
==26152== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==26152== Using valgrind-3.3.0, a dynamic binary instrumentation framework.
==26152== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==26152== For more details, rerun with: -v
==26152==
checksum = 0
==26152==
==26152== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1)
==26152== malloc/free: in use at exit: 0 bytes in 0 blocks.
==26152== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
==26152== For counts of detected errors, rerun with: -v
==26152== All heap blocks were freed -- no leaks are possible.
reg...@john-home:~/volatile/tmp160$ current-gcc -O3 -Wall small.c -o small
reg...@john-home:~/volatile/tmp160$ valgrind ./small
==26158== Memcheck, a memory error detector.
==26158== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==26158== Using LibVEX rev 1804, a library for dynamic binary translation.
==26158== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==26158== Using valgrind-3.3.0, a dynamic binary instrumentation framework.
==26158== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==26158== For more details, rerun with: -v
==26158==
==26158== Use of uninitialised value of size 4
==26158== at 0x8048553: main (in /home/regehr/volatile/tmp160/small)
checksum = E9
==26158==
==26158== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1)
==26158== malloc/free: in use at exit: 0 bytes in 0 blocks.
==26158== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
==26158== For counts of detected errors, rerun with: -v
==26158== All heap blocks were freed -- no leaks are possible.
reg...@john-home:~/volatile/tmp160$ current-gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --prefix=/home/regehr/z/tmp/gcc-r147052-install
--program-prefix=r147052- --enable-languages=c,c++
Thread model: posix
gcc version 4.5.0 20090502 (experimental) (GCC)
reg...@john-home:~/volatile/tmp160$ cat small.c
#include <stdint.h>
#include <stdio.h>
uint8_t crc32_tab[256];
uint32_t crc32_context;
#define safe_mod_macro_int16_t_s_s(si1,si2) \
(((((int16_t)(si2)) == ((int16_t)0)) || ((((int16_t)(si1)) == (INT16_MIN)) &&
(((int16_t)(si2)) == ((int16_t)-1)))) \
? ((int16_t)(si1)) \
: (((int16_t)(si1)) % ((int16_t)(si2))))
static int16_t
safe_mod_func_int16_t_s_s (int16_t _si1, int16_t _si2)
{
return safe_mod_macro_int16_t_s_s(_si1,_si2);
}
#define safe_mod_macro_int64_t_s_s(si1,si2) \
(((((int64_t)(si2)) == ((int64_t)0)) || ((((int64_t)(si1)) == (INT64_MIN)) &&
(((int64_t)(si2)) == ((int64_t)-1)))) \
? ((int64_t)(si1)) \
: (((int64_t)(si1)) % ((int64_t)(si2))))
static int64_t
safe_mod_func_int64_t_s_s (int64_t _si1, int64_t _si2)
{
return safe_mod_macro_int64_t_s_s(_si1,_si2);
}
static void
crc32_gentab (void)
{
uint32_t crc;
const uint32_t poly = 0xEDB88320UL;
int i, j;
for (i = 0; i < 256; i++) {
crc = i;
for (j = 8; j > 0; j--) {
if (crc & 1) {
crc = (crc >> 1) ^ poly;
} else {
crc >>= 1;
}
}
crc32_tab[i] = crc;
}
}
static void
crc32_byte (uint8_t b) {
crc32_context =
((crc32_context >> 8) & 0x00FFFFFF) ^
crc32_tab[(crc32_context ^ b) & 0xFF];
}
static void
crc32_8bytes (uint64_t val)
{
crc32_byte ((val>>0) & 0xff);
crc32_byte ((val>>8) & 0xff);
crc32_byte ((val>>16) & 0xff);
crc32_byte ((val>>24) & 0xff);
crc32_byte ((val>>32) & 0xff);
crc32_byte ((val>>40) & 0xff);
crc32_byte ((val>>48) & 0xff);
crc32_byte ((val>>56) & 0xff);
}
static inline void
platform_main_end(uint32_t crc)
{
printf ("checksum = %X\n", crc);
}
int8_t g_3 = 1;
volatile uint8_t g_98;
uint8_t g_99;
int32_t func_10 (int32_t p_11);
int32_t func_10 (int32_t p_11)
{
return g_99;
}
int64_t func_4 (void);
int64_t func_4 (void)
{
if (safe_mod_func_int16_t_s_s
(((safe_mod_func_int64_t_s_s (1, g_3)) == g_3), func_10 (1)))
g_98;
else
return g_98;
return 1;
}
int main (void)
{
crc32_gentab ();
func_4 ();
crc32_8bytes (g_99);
platform_main_end (crc32_context);
return 0;
}
--
Summary: apparent spurious uninitialized read from r147052 on
integer code
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: regehr at cs dot utah dot edu
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40003