]> granicus.if.org Git - python/commitdiff
bpo-30104: Use -fno-strict-aliasing on clang (#1376)
authorVictor Stinner <victor.stinner@gmail.com>
Tue, 2 May 2017 08:47:37 +0000 (10:47 +0200)
committerGitHub <noreply@github.com>
Tue, 2 May 2017 08:47:37 +0000 (10:47 +0200)
Python/dtoa.c is not compiled correctly with clang 4.0 and
optimization level -O2 or higher, because of an aliasing issue on the
double/ULong[2] union. Only compile dtoa.c with -fno-strict-aliasing.

LLVM bug report:
https://bugs.llvm.org//show_bug.cgi?id=31928

Makefile.pre.in
configure
configure.ac

index 8f27d7320c1d69d4fd559b99b50cfec5494faec6..3eef424b303cfea875931f500f5dce083cba4dc3 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
@@ -1535,6 +1537,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 6a1b9e4edc2c235aa13b5d32f5c647f31ed08d42..227d1d24b379db23592550ec6b452008a87b3f77 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
@@ -6851,6 +6852,7 @@ esac
 # tweak OPT based on compiler and platform, only if the user didn't set
 # it on the command line
 
+
 if test "${OPT-unset}" = "unset"
 then
     case $GCC in
@@ -6863,30 +6865,49 @@ then
            WRAP="-fwrapv"
         fi
 
-        # Clang also needs -fwrapv
         case $CC in
-            *clang*) WRAP="-fwrapv"
-            ;;
+            *clang*)
+                cc_is_clang=1
+                ;;
+            *)
+                if $CC --version 2>&1 | grep -q clang
+                then
+                    cc_is_clang=1
+                else
+                    cc_is_clang=
+                fi
         esac
 
+        if test -n "${cc_is_clang}"
+        then
+            # Clang also needs -fwrapv
+            WRAP="-fwrapv"
+            # 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
        yes)
            if test "$Py_DEBUG" = 'true' ; then
                # Optimization messes up debuggers, so turn it off for
                # debug builds.
                 if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then
-                    OPT="-g -Og -Wall $STRICT_PROTO"
+                    OPT="-g -Og -Wall"
                 else
-                    OPT="-g -O0 -Wall $STRICT_PROTO"
+                    OPT="-g -O0 -Wall"
                 fi
            else
-               OPT="-g $WRAP -O3 -Wall $STRICT_PROTO"
+               OPT="-g $WRAP -O3 -Wall"
            fi
            ;;
        *)
-           OPT="-O3 -Wall $STRICT_PROTO"
+           OPT="-O3 -Wall"
            ;;
        esac
+
+       OPT="$OPT $STRICT_PROTO"
+
        case $ac_sys_system in
            SCO_SV*) OPT="$OPT -m486 -DSCO5"
            ;;
index 2c8e246f22f53eda16467026ed72cd940a24d604..6978b9090de9f6105923249d3001b90a1aa2560c 100644 (file)
@@ -1447,6 +1447,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
@@ -1459,30 +1460,49 @@ then
            WRAP="-fwrapv"
         fi
 
-        # Clang also needs -fwrapv
         case $CC in
-            *clang*) WRAP="-fwrapv"
-            ;;
+            *clang*)
+                cc_is_clang=1
+                ;;
+            *)
+                if $CC --version 2>&1 | grep -q clang
+                then
+                    cc_is_clang=1
+                else
+                    cc_is_clang=
+                fi
         esac
 
+        if test -n "${cc_is_clang}"
+        then
+            # Clang also needs -fwrapv
+            WRAP="-fwrapv"
+            # 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
        yes)
            if test "$Py_DEBUG" = 'true' ; then
                # Optimization messes up debuggers, so turn it off for
                # debug builds.
                 if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then
-                    OPT="-g -Og -Wall $STRICT_PROTO"
+                    OPT="-g -Og -Wall"
                 else
-                    OPT="-g -O0 -Wall $STRICT_PROTO"
+                    OPT="-g -O0 -Wall"
                 fi
            else
-               OPT="-g $WRAP -O3 -Wall $STRICT_PROTO"
+               OPT="-g $WRAP -O3 -Wall"
            fi
            ;;
        *)
-           OPT="-O3 -Wall $STRICT_PROTO"
+           OPT="-O3 -Wall"
            ;;
        esac
+
+       OPT="$OPT $STRICT_PROTO"
+
        case $ac_sys_system in
            SCO_SV*) OPT="$OPT -m486 -DSCO5"
            ;;