Date: Sat, 10 Dec 2011 03:21:24 +0200 From: Gleb Kurtsou <gleb.kurtsou@gmail.com> To: Ryan Stone <rysto32@gmail.com> Cc: mdf@freebsd.org, freebsd-hackers@freebsd.org, Piotr Nowak <pn@semihalf.com>, Rafal Jaworowski <raj@semihalf.com>, Nathan Whitehorn <nwhitehorn@freebsd.org>, Arnaud Lacombe <lacombar@gmail.com> Subject: Re: gcc 4.2 miscompilation with -O2 -fno-omit-frame-pointer on amd64 Message-ID: <20111210012124.GA95149@reks> In-Reply-To: <CAFMmRNwt62NDhan72%2BMVFw1iYswP2ixpKMyKnMCnd_KNK0zVbw@mail.gmail.com> References: <20111119100150.GA1560@reks> <CACqU3MXf%2BsbTpZMbqugmMKKb1BEbp6sNzeTkXfvnQtZ1E4ukEA@mail.gmail.com> <BA73AB23-650A-4241-BBAC-BA01BD372AA3@semihalf.com> <20111208090159.GA1924@cq1> <4EE0EB8C.7050800@freebsd.org> <6D023449-EDEA-4B1C-975D-54AA2F4328CE@semihalf.com> <20111209181550.GA3555@reks> <CAFMmRNwt62NDhan72%2BMVFw1iYswP2ixpKMyKnMCnd_KNK0zVbw@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--FCuugMFkClbJLl1L Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Please find test case and test results attached. (gcc-test1.shar.txt) The long story short: only gcc-4.2 is affected, gcc 3.4, 4.4 and 4.6 are ok. clang is ok. (test-cc.txt) Nearly all of the workarounds I used in original test doesn't work in this test case (see #ifdef BAD_FIX in sources). gcc 4.2 fails even with -O1, it has nothing to do with -fno-omit-frame-pointer, finline-functions, etc. (test-cflags.txt) Compile with -DFIX1 to work around problem (replace struct assignment with memcpy): % make test XFLAGS="-O2 -DFIX1" rm -f gcc-test1 src1.o src2.o src3.o cc -O2 -DFIX1 -g -std=gnu99 -c src1.c cc -O2 -DFIX1 -g -std=gnu99 -c src2.c cc -O2 -DFIX1 -g -std=gnu99 -c src3.c cc -O2 -DFIX1 -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /home/gleb/projects/gcc-test1/gcc-test1 ok Happy hacking! --FCuugMFkClbJLl1L Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename="gcc-test1.shar.txt" # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # Makefile # array.h # debug.h # hdr1.h # src1.c # src2.c # src3.c # echo x - Makefile sed 's/^X//' >Makefile << 'b67911656ef5d18c4ae36cb6741b7965' XPROG= gcc-test1 XSRCS= src1.c src2.c src3.c hdr1.h XNO_MAN= X XXFLAGS?=-O2 -fno-omit-frame-pointer X X#WARNS=6 X#NO_WERROR= X XSSP_CFLAGS= XDEBUG_FLAGS= -g XCSTD= gnu99 X XCFLAGS= ${XFLAGS} X X.PHONY: test Xtest: clean ${PROG} X ${.OBJDIR}/${PROG} X X.include <bsd.prog.mk> b67911656ef5d18c4ae36cb6741b7965 echo x - array.h sed 's/^X//' >array.h << '3ff8e27b821109f0551768c5e1b6bc0d' X#include "debug.h" X X#define ARRAY_HEAD(name, type, capacity) \ X struct name { \ X size_t arr_count; \ X struct type arr_items[capacity]; \ X } X X#define ARRAY_INIT(head) do { \ X (head)->arr_count = 0; \ X} while (0) X X#define ARRAY_CAPACITY(head) \ X (sizeof((head)->arr_items) / sizeof((head)->arr_items[0])) X X#define ARRAY_COUNT(head) (head)->arr_count X X#ifdef FIX1 X X#define ARRAY_INSERT_TAIL(head, elm) do { \ X ASSERT(ARRAY_COUNT((head)) < ARRAY_CAPACITY((head))); \ X memcpy(&(head)->arr_items[(head)->arr_count++], &(elm), sizeof(elm)); \ X} while (0) X X#else X X#define ARRAY_INSERT_TAIL(head, elm) do { \ X ASSERT(ARRAY_COUNT((head)) < ARRAY_CAPACITY((head))); \ X (head)->arr_items[(head)->arr_count++] = (elm); \ X} while (0) X X#endif X X#define ARRAY_FOREACH(var, head) \ X for ((var) = &(head)->arr_items[0]; \ X (var) < &(head)->arr_items[0] + (head)->arr_count; \ X (var)++) 3ff8e27b821109f0551768c5e1b6bc0d echo x - debug.h sed 's/^X//' >debug.h << '0483bb2079adc3936e07b79b224930aa' X#ifndef XXX_DEBUG_H X#define XXX_DEBUG_H X X#include <stdarg.h> X X#define ASSERT(cond) \ X (__predict_false(cond) ? (void)0 : \ X debug_assert(#cond, __FILE__, __LINE__, __func__)) X Xvoid debug_assert(const char *msg, const char *file, int line, X const char *func); X X#endif 0483bb2079adc3936e07b79b224930aa echo x - hdr1.h sed 's/^X//' >hdr1.h << '023696bd679b9970bb745000978348c8' X#include <stdbool.h> X X#include "array.h" X#include "debug.h" X Xtypedef union { X struct { X bool flag1:1; X bool flag2:1; X bool flag3:1; X bool flag4:1; X bool flag5:1; X bool flag6:1; X bool flag7:1; X bool flag8:1; X bool flag9:1; X bool flag10:1; X }; X uint32_t bits; X} xflags_t; X Xstruct session { X xflags_t flags; X struct sockaddr_in addr; X}; X Xstruct dummy1 { X int a, b, c; X void *ptr; X}; X XARRAY_HEAD(addr_list, sockaddr_in, 2); X Xstruct addr_list; X Xvoid test_fail(void *arg1, void *arg2, X void *arg3, const void *arg4, X const struct addr_list *addr_list, X const void *arg5); X Xbool test_run(struct session *sess); 023696bd679b9970bb745000978348c8 echo x - src1.c sed 's/^X//' >src1.c << 'd76eceed15fcbc6c2cf5da795270acb3' X#include <sys/param.h> X#include <sys/socket.h> X#include <netinet/in.h> X X#include <stdio.h> X#include <stdlib.h> X#include <string.h> X X#include "hdr1.h" X Xstatic void test_set_dummy(struct dummy1 *arg1, void *arg2); X Xbool Xtest_run(struct session *sess) X{ X struct dummy1 d1 __unused; X struct addr_list tmp_addr_list; X struct sockaddr_in tmp_addr; X bool rv = true; X X#ifdef BAD_FIX X // Removing assertions fixes original test case X ASSERT(sess->flags.flag5); X ASSERT(sess->flags.flag4); X ASSERT(sess->flags.flag7); X ASSERT(sess->flags.flag9); X#endif X X // Replacing assignment with memcpy fixes original test case X tmp_addr = sess->addr; X tmp_addr.sin_port = 0; X ARRAY_INIT(&tmp_addr_list); X ARRAY_INSERT_TAIL(&tmp_addr_list, tmp_addr); X X#ifdef BAD_FIX X // Removing function call fixes original test case X test_set_dummy(&d1, sess); X#endif X X test_fail(NULL, NULL, X NULL, NULL, &tmp_addr_list, NULL); X X return rv; X} X Xstruct dummy1 d1_template = { X .a = 1, X .b = 2, X}; X Xstatic void Xtest_set_dummy(struct dummy1 *arg1, void *arg2 __unused) X{ X *arg1 = d1_template; X} d76eceed15fcbc6c2cf5da795270acb3 echo x - src2.c sed 's/^X//' >src2.c << '84fb2eee7bfbf3aefc26348a2ac4dc34' X#include <sys/types.h> X#include <sys/socket.h> X#include <netinet/in.h> X X#include "hdr1.h" X Xvoid Xtest_fail(void *arg1 __unused, void *arg2 __unused, X void *arg3 __unused, const void *arg4 __unused, X const struct addr_list *addr_list, X const void *arg6 __unused) X{ X const struct sockaddr_in *addr; X X ARRAY_FOREACH(addr, addr_list) { X ASSERT(addr->sin_addr.s_addr == ntohl(INADDR_ANY)); X } X} 84fb2eee7bfbf3aefc26348a2ac4dc34 echo x - src3.c sed 's/^X//' >src3.c << 'e773224103ed63e54dbf72915ff448a8' X#include <sys/types.h> X#include <sys/socket.h> X#include <netinet/in.h> X X#include <stdbool.h> X#include <stdio.h> X#include <stdlib.h> X X#include "hdr1.h" X Xint Xmain(int argc __unused, char **argv __unused) X{ X struct session *sess; X X sess = calloc(sizeof(*sess), 1); X sess->flags.flag1 = true; X sess->flags.flag4 = true; X sess->flags.flag5 = true; X sess->flags.flag6 = true; X sess->flags.flag7 = true; X sess->flags.flag9 = true; X X sess->addr.sin_addr.s_addr = ntohl(INADDR_ANY); X X test_run(sess); X X puts("ok"); X X return 0; X} X Xvoid Xdebug_assert(const char *msg, const char *file, int line, const char *func) X{ X if (func == NULL) X fprintf(stderr, "%s:%d: Assertion failed: %s\n", X file, line, msg); X else X fprintf(stderr, "%s:%d:%s: Assertion failed: %s\n", X file, line, func, msg); X abort(); X} e773224103ed63e54dbf72915ff448a8 exit --FCuugMFkClbJLl1L Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename="test-cc.txt" % for CC in cc gcc42 gcc34 gcc44 gcc46 clang; do ${CC} -v; make test CC=${CC}; done Using built-in specs. Target: amd64-undermydesk-freebsd Configured with: FreeBSD/amd64 system compiler Thread model: posix gcc version 4.2.1 20070831 patched [FreeBSD] rm -f gcc-test1 src1.o src2.o src3.o cc -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src1.c cc -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src2.c cc -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src3.c cc -O2 -fno-omit-frame-pointer -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /home/gleb/projects/gcc-test1/gcc-test1 src2.c:16:test_fail: Assertion failed: addr->sin_addr.s_addr == ntohl(INADDR_ANY) *** Signal 6 Stop in /home/gleb/projects/gcc-test1. zsh: exit 1 make test CC=${CC} Using built-in specs. Target: x86_64-portbld-freebsd9.0 Configured with: ./../gcc-4.2-20090325/configure --disable-nls --libdir=/usr/local/lib/gcc42 --libexecdir=/usr/local/libexec/gcc42 --program-suffix=42 --with-as=/usr/bin/as --with-gmp=/usr/local --with-gxx-include-dir=/usr/local/lib/gcc42/include/c++/ --with-ld=/usr/bin/ld --with-libiconv-prefix=/usr/local --with-system-zlib --prefix=/usr/local --mandir=/usr/local/man --infodir=/usr/local/info/gcc42 x86_64-portbld-freebsd9.0 Thread model: posix gcc version 4.2.5 20090325 (prerelease) [FreeBSD Ports Collection] rm -f gcc-test1 src1.o src2.o src3.o gcc42 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src1.c gcc42 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src2.c gcc42 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src3.c gcc42 -O2 -fno-omit-frame-pointer -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /home/gleb/projects/gcc-test1/gcc-test1 src2.c:16:test_fail: Assertion failed: addr->sin_addr.s_addr == ntohl(INADDR_ANY) *** Signal 6 Stop in /home/gleb/projects/gcc-test1. zsh: exit 1 make test CC=${CC} Reading specs from /usr/local/lib/gcc/x86_64-portbld-freebsd9.0/3.4.6/gcc/x86_64-portbld-freebsd9.0/3.4.6/specs Configured with: ./..//gcc-3.4.6/configure --disable-nls --with-system-zlib --with-libiconv-prefix=/usr/local --program-suffix=34 --libdir=/usr/local/lib/gcc/x86_64-portbld-freebsd9.0/3.4.6 --with-gxx-include-dir=/usr/local/lib/gcc/x86_64-portbld-freebsd9.0/3.4.6/include/c++/ --prefix=/usr/local --mandir=/usr/local/man --infodir=/usr/local/info/gcc34 x86_64-portbld-freebsd9.0 Thread model: posix gcc version 3.4.6 [FreeBSD] rm -f gcc-test1 src1.o src2.o src3.o gcc34 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src1.c gcc34 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src2.c gcc34 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src3.c gcc34 -O2 -fno-omit-frame-pointer -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /usr/bin/ld: error in /usr/local/lib/gcc/x86_64-portbld-freebsd9.0/3.4.6/gcc/x86_64-portbld-freebsd9.0/3.4.6/crtend.o(.eh_frame); no .eh_frame_hdr table will be created. /home/gleb/projects/gcc-test1/gcc-test1 ok Using built-in specs. Target: x86_64-portbld-freebsd9.0 Configured with: ./../gcc-4.4-20111108/configure --disable-nls --enable-languages=c,c++,fortran --libdir=/usr/local/lib/gcc44 --libexecdir=/usr/local/libexec/gcc44 --program-suffix=44 --with-as=/usr/local/bin/as --with-gmp=/usr/local --with-gxx-include-dir=/usr/local/lib/gcc44/include/c++/ --with-ld=/usr/local/bin/ld --with-libiconv-prefix=/usr/local --with-pkgversion='FreeBSD Ports Collection' --with-system-zlib --prefix=/usr/local --mandir=/usr/local/man --infodir=/usr/local/info/gcc44 --build=x86_64-portbld-freebsd9.0 Thread model: posix gcc version 4.4.7 20111108 (prerelease) (FreeBSD Ports Collection) rm -f gcc-test1 src1.o src2.o src3.o gcc44 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src1.c gcc44 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src2.c gcc44 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src3.c gcc44 -O2 -fno-omit-frame-pointer -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /home/gleb/projects/gcc-test1/gcc-test1 ok Using built-in specs. COLLECT_GCC=gcc46 COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc46/gcc/x86_64-portbld-freebsd9.0/4.6.2/lto-wrapper Target: x86_64-portbld-freebsd9.0 Configured with: ./../gcc-4.6.2/configure --disable-nls --enable-languages=c,c++,fortran --libdir=/usr/local/lib/gcc46 --libexecdir=/usr/local/libexec/gcc46 --program-suffix=46 --with-as=/usr/local/bin/as --with-gmp=/usr/local --with-gxx-include-dir=/usr/local/lib/gcc46/include/c++/ --with-ld=/usr/local/bin/ld --with-libiconv-prefix=/usr/local --with-pkgversion='FreeBSD Ports Collection' --with-system-zlib --enable-languages=c,c++,fortran,java --prefix=/usr/local --mandir=/usr/local/man --infodir=/usr/local/info/gcc46 --build=x86_64-portbld-freebsd9.0 Thread model: posix gcc version 4.6.2 (FreeBSD Ports Collection) rm -f gcc-test1 src1.o src2.o src3.o gcc46 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src1.c gcc46 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src2.c gcc46 -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src3.c gcc46 -O2 -fno-omit-frame-pointer -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /home/gleb/projects/gcc-test1/gcc-test1 ok clang version 3.0 (trunk) Target: amd64-portbld-freebsd9.0 Thread model: posix rm -f gcc-test1 src1.o src2.o src3.o clang -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src1.c clang -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src2.c clang -O2 -fno-omit-frame-pointer -g -std=gnu99 -c src3.c clang -O2 -fno-omit-frame-pointer -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o clang: warning: argument unused during compilation: '-g' clang: warning: argument unused during compilation: '-std=gnu99' /home/gleb/projects/gcc-test1/gcc-test1 ok ~/projects/gcc-test1 % --FCuugMFkClbJLl1L Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename="test-cflags.txt" % for XFLAGS in -O0 -O1 -O2 -O3; do make test XFLAGS=${XFLAGS}; done rm -f gcc-test1 src1.o src2.o src3.o cc -O0 -g -std=gnu99 -c src1.c cc -O0 -g -std=gnu99 -c src2.c cc -O0 -g -std=gnu99 -c src3.c cc -O0 -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /home/gleb/projects/gcc-test1/gcc-test1 ok rm -f gcc-test1 src1.o src2.o src3.o cc -O1 -g -std=gnu99 -c src1.c cc -O1 -g -std=gnu99 -c src2.c cc -O1 -g -std=gnu99 -c src3.c cc -O1 -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /home/gleb/projects/gcc-test1/gcc-test1 src2.c:16:test_fail: Assertion failed: addr->sin_addr.s_addr == ntohl(INADDR_ANY) *** Signal 6 Stop in /home/gleb/projects/gcc-test1. zsh: exit 1 make test XFLAGS=${XFLAGS} rm -f gcc-test1 src1.o src2.o src3.o cc -O2 -g -std=gnu99 -c src1.c cc -O2 -g -std=gnu99 -c src2.c cc -O2 -g -std=gnu99 -c src3.c cc -O2 -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /home/gleb/projects/gcc-test1/gcc-test1 src2.c:16:test_fail: Assertion failed: addr->sin_addr.s_addr == ntohl(INADDR_ANY) *** Signal 6 Stop in /home/gleb/projects/gcc-test1. zsh: exit 1 make test XFLAGS=${XFLAGS} rm -f gcc-test1 src1.o src2.o src3.o cc -O3 -g -std=gnu99 -c src1.c cc -O3 -g -std=gnu99 -c src2.c cc -O3 -g -std=gnu99 -c src3.c cc -O3 -g -std=gnu99 -o gcc-test1 src1.o src2.o src3.o /home/gleb/projects/gcc-test1/gcc-test1 src2.c:16:test_fail: Assertion failed: addr->sin_addr.s_addr == ntohl(INADDR_ANY) *** Signal 6 --FCuugMFkClbJLl1L--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20111210012124.GA95149>