Message ID | 20150729135730.568AAB045@oc7340732750.ibm.com |
---|---|
State | New |
Headers | show |
On Wed, Jul 29, 2015 at 3:57 PM, Ulrich Weigand <uweigand@de.ibm.com> wrote: > 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? Ok if nobody objects. Thanks, Richard. > 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.Weigand@de.ibm.com >
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