This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Work around host compiler placement new aliasing bug
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: richard dot guenther at gmail dot com, mliska at suse dot cz
- Date: Wed, 29 Jul 2015 15:57:30 +0200 (CEST)
- Subject: [PATCH] Work around host compiler placement new aliasing bug
- Authentication-results: sourceware.org; auth=none
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.Weigand@de.ibm.com