Hello, this patch is a workaround for the problem discussed here: https://gcc.gnu.org/ml/gcc-patches/2015-07/msg01597.html
The problem is that the new pool allocator code relies on C++ aliasing rules related to placement new (basically, that placement new changes the dynamic type of the referenced memory). GCC compilers prior to version 4.3 did not implement this rule correctly (PR 29286). When building current GCC with a host compiler that is affected by this bug, and we build with optimization enabled (this typically only happens when building a cross-compiler), the resulting compiler binary may be miscompiled. The patch below attempts to detect this situation by checking whether the host compiler is a version of GCC prior to 4.3 (but stil accepts the -fno-strict-aliasing flag). If so, -fno-strict-aliasing is added to the flags when building the compiler binary. Tested on i686-linux, and when building an SPU cross-compiler using a gcc 4.1 powerpc64-linux host compiler. OK for mainline? Bye, Ulrich gcc/ChangeLog: * configure.ac: Set aliasing_flags to -fno-strict-aliasing if the host compiler is affected by placement new aliasing bug. * configure: Regenerate. * Makefile.in (ALIASING_FLAGS): New variable. (ALL_CXXFLAGS): Add $(ALIASING_FLAGS). Index: gcc/configure =================================================================== --- gcc/configure (revision 226312) +++ gcc/configure (working copy) @@ -789,6 +789,7 @@ c_strict_warn strict_warn c_loose_warn loose_warn +aliasing_flags CPP EGREP GREP @@ -6526,6 +6527,42 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi +# Check whether compiler is affected by placement new aliasing bug (PR 29286). +# If the host compiler is affected by the bug, and we build with optimization +# enabled (which happens e.g. when cross-compiling), the pool allocator may +# get miscompiled. Use -fno-strict-aliasing to work around this problem. +# Since there is no reliable feature check for the presence of this bug, +# we simply use a GCC version number check. (This should never trigger for +# stages 2 or 3 of a native bootstrap.) +aliasing_flags= +if test "$GCC" = yes; then + saved_CXXFLAGS="$CXXFLAGS" + + # The following test compilation will succeed if and only if $CXX accepts + # -fno-strict-aliasing *and* is older than GCC 4.3. + CXXFLAGS="$CXXFLAGS -fno-strict-aliasing" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX is affected by placement new aliasing bug" >&5 +$as_echo_n "checking whether $CXX is affected by placement new aliasing bug... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +#error compiler not affected by placement new aliasing bug +#endif + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; aliasing_flags='-fno-strict-aliasing' +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + CXXFLAGS="$saved_CXXFLAGS" +fi + @@ -18301,7 +18338,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 18304 "configure" +#line 18341 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -18407,7 +18444,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 18410 "configure" +#line 18447 "configure" #include "confdefs.h" #if HAVE_DLFCN_H Index: gcc/configure.ac =================================================================== --- gcc/configure.ac (revision 226312) +++ gcc/configure.ac (working copy) @@ -416,6 +416,32 @@ struct X<long long> { typedef long long ]], [[X<int64_t>::t x;]])],[],[AC_MSG_ERROR([error verifying int64_t uses long long])]) fi +# Check whether compiler is affected by placement new aliasing bug (PR 29286). +# If the host compiler is affected by the bug, and we build with optimization +# enabled (which happens e.g. when cross-compiling), the pool allocator may +# get miscompiled. Use -fno-strict-aliasing to work around this problem. +# Since there is no reliable feature check for the presence of this bug, +# we simply use a GCC version number check. (This should never trigger for +# stages 2 or 3 of a native bootstrap.) +aliasing_flags= +if test "$GCC" = yes; then + saved_CXXFLAGS="$CXXFLAGS" + + # The following test compilation will succeed if and only if $CXX accepts + # -fno-strict-aliasing *and* is older than GCC 4.3. + CXXFLAGS="$CXXFLAGS -fno-strict-aliasing" + AC_MSG_CHECKING([whether $CXX is affected by placement new aliasing bug]) + AC_COMPILE_IFELSE([ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +#error compiler not affected by placement new aliasing bug +#endif +], + [AC_MSG_RESULT([yes]); aliasing_flags='-fno-strict-aliasing'], + [AC_MSG_RESULT([no])]) + + CXXFLAGS="$saved_CXXFLAGS" +fi +AC_SUBST(aliasing_flags) Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in (revision 226312) +++ gcc/Makefile.in (working copy) @@ -180,6 +180,8 @@ NOCOMMON_FLAG = @nocommon_flag@ NOEXCEPTION_FLAGS = @noexception_flags@ +ALIASING_FLAGS = @aliasing_flags@ + # This is set by --disable-maintainer-mode (default) to "#" # FIXME: 'MAINT' will always be set to an empty string, no matter if # --disable-maintainer-mode is used or not. This is because the @@ -986,7 +988,8 @@ ALL_CFLAGS = $(T_CFLAGS) $(CFLAGS-$@) \ # The C++ version. ALL_CXXFLAGS = $(T_CFLAGS) $(CFLAGS-$@) $(CXXFLAGS) $(INTERNAL_CFLAGS) \ - $(COVERAGE_FLAGS) $(NOEXCEPTION_FLAGS) $(WARN_CXXFLAGS) @DEFS@ + $(COVERAGE_FLAGS) $(ALIASING_FLAGS) $(NOEXCEPTION_FLAGS) \ + $(WARN_CXXFLAGS) @DEFS@ # Likewise. Put INCLUDES at the beginning: this way, if some autoconf macro # puts -I options in CPPFLAGS, our include files in the srcdir will always -- Dr. Ulrich Weigand GNU/Linux compilers and toolchain ulrich.weig...@de.ibm.com