bpo-30104: Only use -fno-strict-aliasing on dtoa.c (#1340)
authorVictor Stinner <victor.stinner@gmail.com>
Fri, 28 Apr 2017 13:07:10 +0000 (15:07 +0200)
committerGitHub <noreply@github.com>
Fri, 28 Apr 2017 13:07:10 +0000 (15:07 +0200)
On clang, only compile dtoa.c with -fno-strict-aliasing, use strict
aliasing to compile all other C files.

Makefile.pre.in
configure
configure.ac

index 4145634c032d543d02295bd2c28a0c6ce839fa86..e5141f11dade2db62c6d5dfb2fe79528f948b6ab 100644 (file)
@@ -107,6 +107,8 @@ ARFLAGS=    @ARFLAGS@
 CFLAGSFORSHARED=@CFLAGSFORSHARED@
 # C flags used for building the interpreter object files
 PY_CORE_CFLAGS=        $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE
+# Strict or non-strict aliasing flags used to compile dtoa.c, see above
+CFLAGS_ALIASING=@CFLAGS_ALIASING@
 
 
 # Machine-dependent subdirectories
@@ -1536,6 +1538,13 @@ config.status:   $(srcdir)/configure
 .c.o:
        $(CC) -c $(PY_CORE_CFLAGS) -o $@ $<
 
+# bpo-30104: dtoa.c uses union to cast double to unsigned long[2]. clang 4.0
+# with -O2 or higher and strict aliasing miscompiles the ratio() function
+# causing rounding issues. Compile dtoa.c using -fno-strict-aliasing on clang.
+# https://bugs.llvm.org//show_bug.cgi?id=31928
+Python/dtoa.o: Python/dtoa.c
+       $(CC) -c $(PY_CORE_CFLAGS) $(CFLAGS_ALIASING) -o $@ $<
+
 # Run reindent on the library
 reindent:
        ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib
index 1c90d3101c897743a29610c4269a2f902dde90c9..3e89bfabc3a519ae13a83e35eed97e7322b2b6e2 100755 (executable)
--- a/configure
+++ b/configure
@@ -668,6 +668,7 @@ OTHER_LIBTOOL_OPT
 UNIVERSAL_ARCH_FLAGS
 CFLAGS_NODIST
 BASECFLAGS
+CFLAGS_ALIASING
 OPT
 LLVM_PROF_FOUND
 target_os
@@ -6829,13 +6830,7 @@ then
         then
             # Clang also needs -fwrapv
             WRAP="-fwrapv"
-
-            # bpo-30104: Python/dtoa.c requires to be build with
-            # -fno-strict-aliasing to fix compiler issue on the
-            # double/ULong[2] union using clang 4.0 and optimization level
-            # -O2 or higher
-            # https://bugs.llvm.org//show_bug.cgi?id=31928
-            ALIASING="-fno-strict-aliasing"
+            CFLAGS_ALIASING="-fno-strict-aliasing"
         fi
 
        case $ac_cv_prog_cc_g in
@@ -6857,7 +6852,7 @@ then
            ;;
        esac
 
-       OPT="$OPT $STRICT_PROTO $ALIASING"
+       OPT="$OPT $STRICT_PROTO"
 
        case $ac_sys_system in
            SCO_SV*) OPT="$OPT -m486 -DSCO5"
index e5b725795ad2c02ee08b391392c803fc1caa0bfd..c58322dc8c7c07c0e38ca3c98e8ed89e108e2dfa 100644 (file)
@@ -1440,6 +1440,7 @@ esac
 # tweak OPT based on compiler and platform, only if the user didn't set
 # it on the command line
 AC_SUBST(OPT)
+AC_SUBST(CFLAGS_ALIASING)
 if test "${OPT-unset}" = "unset"
 then
     case $GCC in
@@ -1469,13 +1470,9 @@ then
         then
             # Clang also needs -fwrapv
             WRAP="-fwrapv"
-
-            # bpo-30104: Python/dtoa.c requires to be build with
-            # -fno-strict-aliasing to fix compiler issue on the
-            # double/ULong[2] union using clang 4.0 and optimization level
-            # -O2 or higher
-            # https://bugs.llvm.org//show_bug.cgi?id=31928
-            ALIASING="-fno-strict-aliasing"
+            # bpo-30104: disable strict aliasing to compile correctly dtoa.c,
+            # see Makefile.pre.in for more information
+            CFLAGS_ALIASING="-fno-strict-aliasing"
         fi
 
        case $ac_cv_prog_cc_g in
@@ -1497,7 +1494,7 @@ then
            ;;
        esac
 
-       OPT="$OPT $STRICT_PROTO $ALIASING"
+       OPT="$OPT $STRICT_PROTO"
 
        case $ac_sys_system in
            SCO_SV*) OPT="$OPT -m486 -DSCO5"