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!
# 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

% 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 % 

% 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
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to