On Wed, Jul 29, 2015 at 3:57 PM, Ulrich Weigand <uweig...@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.weig...@de.ibm.com
>

Reply via email to