>Submitter-Id: net >Originator: >Organization: >Confidential: no >Synopsis: parameter passing bug >Severity: serious >Priority: medium >Category: c >Class: wrong-code >Release: gcc-4.1 (GCC) 4.1.2 20060901 (prerelease) (Debian 4.1.1-13) >Environment: System: Linux kubrick 2.6.16-2-amd64-k8-smp #1 SMP Fri Aug 18 21:10:33 CEST 2006 x86_64 GNU/Linux Architecture: x86_64
host: x86_64-pc-linux-gnu build: x86_64-pc-linux-gnu target: x86_64-pc-linux-gnu configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release x86_64-linux-gnu >Description: The following code tests that values are passed correctly from a call to a function. This fails, when the followign code is compiled with -O2 and executed: foo: foo.c:65: callee_b0f: Assertion `b14.b3 == b20.b3' failed. The code below is automatically generated explicitly to test for parameter-passing bugs. Since the pre-processed code below might be hard to understand, here is the orginal code as well. /* These macros are defined in Lua string Quest.header, which may be * re-defined from the quest command line or in file quest.lua. */ #ifndef QUEST_FAILED #include <assert.h> #define QUEST_ASSERT(x) assert(x) #else #define QUEST_ASSERT(x) if (!(x)) failed(__LINE__) #endif #include <stdarg.h> extern int printf(char *, ...); static int errors = 0; static void failed(int line) { printf("failed in %s: %d\n", __FILE__, line); errors++; } static union bt7 { unsigned long int b10; double *b11; } b12 = {1989374529UL}; static struct bt5 { unsigned int *b7; unsigned int b8; signed b9:10; } b17 = {(unsigned int *) 229073790U, 777271108U, 408}; static union bt6 { } b18 = {}; static union bt0 { } b13 = {}; static struct bt3 { float b3; struct bt1 { short int b0; signed b1:2; } b4; struct bt2 { float b2; } b5; } b14 = {10569.23, {17187, 1}, {45076.89}}; static union bt4 { double b6; } b15 = {92314.64}; static double b16 = 89201.46; union bt7 callee_b0f(struct bt5 bp2, union bt6 bp3, ...) { va_list ap; typedef union bt0 bd0; typedef struct bt3 bd1; typedef union bt4 bd2; typedef double bd3; bd0 b19; bd1 b20; bd2 b21; bd3 b22; /* seed: 4346181125667919790 */ va_start(ap, bp3); QUEST_ASSERT(b17.b7 == bp2.b7); QUEST_ASSERT(b17.b8 == bp2.b8); QUEST_ASSERT(b17.b9 == bp2.b9); b19 = va_arg(ap, bd0); b20 = va_arg(ap, bd1); b21 = va_arg(ap, bd2); b22 = va_arg(ap, bd3); QUEST_ASSERT(b14.b3 == b20.b3); QUEST_ASSERT(b14.b4.b0 == b20.b4.b0); QUEST_ASSERT(b14.b4.b1 == b20.b4.b1); QUEST_ASSERT(b14.b5.b2 == b20.b5.b2); QUEST_ASSERT(b15.b6 == b21.b6); QUEST_ASSERT(b16 == b22); va_end(ap); return b12; } static void caller_b1f() { union bt7 b23; /* seed: 4346181125667919790 */ b23 = callee_b0f(b17, b18, b13, b14, b15, b16); QUEST_ASSERT(b12.b10 == b23.b10); } int main(int argc, char **argv) { caller_b1f(); return errors; } Below is the pre-processed code: # 1 "foo.c" # 1 "<built-in>" # 1 "<command line>" # 1 "foo.c" # 15 "foo.c" # 1 "/usr/include/assert.h" 1 3 4 # 36 "/usr/include/assert.h" 3 4 # 1 "/usr/include/features.h" 1 3 4 # 308 "/usr/include/features.h" 3 4 # 1 "/usr/include/sys/cdefs.h" 1 3 4 # 309 "/usr/include/features.h" 2 3 4 # 331 "/usr/include/features.h" 3 4 # 1 "/usr/include/gnu/stubs.h" 1 3 4 # 332 "/usr/include/features.h" 2 3 4 # 37 "/usr/include/assert.h" 2 3 4 # 67 "/usr/include/assert.h" 3 4 extern void __assert_fail (__const char *__assertion, __const char *__file, unsigned int __line, __const char *__function) __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__)); extern void __assert_perror_fail (int __errnum, __const char *__file, unsigned int __line, __const char *__function) __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__)); extern void __assert (const char *__assertion, const char *__file, int __line) __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__)); # 16 "foo.c" 2 # 1 "/usr/lib/gcc/x86_64-linux-gnu/4.1.2/include/stdarg.h" 1 3 4 # 43 "/usr/lib/gcc/x86_64-linux-gnu/4.1.2/include/stdarg.h" 3 4 typedef __builtin_va_list __gnuc_va_list; # 105 "/usr/lib/gcc/x86_64-linux-gnu/4.1.2/include/stdarg.h" 3 4 typedef __gnuc_va_list va_list; # 22 "foo.c" 2 extern int printf(char *, ...); static int errors = 0; static void failed(int line) { printf("failed in %s: %d\n", "foo.c", line); errors++; } static union bt7 { unsigned long int b10; double *b11; } b12 = {1989374529UL}; static struct bt5 { unsigned int *b7; unsigned int b8; signed b9:10; } b17 = {(unsigned int *) 229073790U, 777271108U, 408}; static union bt6 { } b18 = {}; static union bt0 { } b13 = {}; static struct bt3 { float b3; struct bt1 { short int b0; signed b1:2; } b4; struct bt2 { float b2; } b5; } b14 = {10569.23, {17187, 1}, {45076.89}}; static union bt4 { double b6; } b15 = {92314.64}; static double b16 = 89201.46; union bt7 callee_b0f(struct bt5 bp2, union bt6 bp3, ...) { va_list ap; typedef union bt0 bd0; typedef struct bt3 bd1; typedef union bt4 bd2; typedef double bd3; bd0 b19; bd1 b20; bd2 b21; bd3 b22; __builtin_va_start(ap,bp3); ((void) ((b17.b7 == bp2.b7) ? 0 : (__assert_fail ("b17.b7 == bp2.b7", "foo.c", 58, __PRETTY_FUNCTION__), 0))); ((void) ((b17.b8 == bp2.b8) ? 0 : (__assert_fail ("b17.b8 == bp2.b8", "foo.c", 59, __PRETTY_FUNCTION__), 0))); ((void) ((b17.b9 == bp2.b9) ? 0 : (__assert_fail ("b17.b9 == bp2.b9", "foo.c", 60, __PRETTY_FUNCTION__), 0))); b19 = __builtin_va_arg(ap,bd0); b20 = __builtin_va_arg(ap,bd1); b21 = __builtin_va_arg(ap,bd2); b22 = __builtin_va_arg(ap,bd3); ((void) ((b14.b3 == b20.b3) ? 0 : (__assert_fail ("b14.b3 == b20.b3", "foo.c", 65, __PRETTY_FUNCTION__), 0))); ((void) ((b14.b4.b0 == b20.b4.b0) ? 0 : (__assert_fail ("b14.b4.b0 == b20.b4.b0", "foo.c", 66, __PRETTY_FUNCTION__), 0))); ((void) ((b14.b4.b1 == b20.b4.b1) ? 0 : (__assert_fail ("b14.b4.b1 == b20.b4.b1", "foo.c", 67, __PRETTY_FUNCTION__), 0))); ((void) ((b14.b5.b2 == b20.b5.b2) ? 0 : (__assert_fail ("b14.b5.b2 == b20.b5.b2", "foo.c", 68, __PRETTY_FUNCTION__), 0))); ((void) ((b15.b6 == b21.b6) ? 0 : (__assert_fail ("b15.b6 == b21.b6", "foo.c", 69, __PRETTY_FUNCTION__), 0))); ((void) ((b16 == b22) ? 0 : (__assert_fail ("b16 == b22", "foo.c", 70, __PRETTY_FUNCTION__), 0))); __builtin_va_end(ap); return b12; } static void caller_b1f() { union bt7 b23; b23 = callee_b0f(b17, b18, b13, b14, b15, b16); ((void) ((b12.b10 == b23.b10) ? 0 : (__assert_fail ("b12.b10 == b23.b10", "foo.c", 79, __PRETTY_FUNCTION__), 0))); } int main(int argc, char **argv) { caller_b1f(); return errors; } >How-To-Repeat: Compile the code above with -O2 and run it; this should result in an assertion failure. >Fix: No fix known. -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]