Skip to content

Commit 84f14fb

Browse files
committed
Error out for clang on x86-32 without SSE2 support, no -fexcess-precision.
As clang currently doesn't support -fexcess-precision=standard, compiling x86-32 code with SSE2 disabled, can lead to problems with floating point overflow checks and the like. This issue was noticed because clang, on at least some BSDs, defaults to i386 compatibility, whereas it defaults to pentium4 on Linux. Our forced usage of __builtin_isinf() lead to some overflow checks not triggering when compiling for i386, e.g. when the result of the calculation didn't overflow in 80bit registers, but did so in 64bit. While we could just fall back to a non-builtin isinf, it seems likely that the use of 80bit registers leads to other problems (which is why we force the flag for GCC already). Therefore error out when detecting clang in that situation. Reported-By: Victor Wagner Analyzed-By: Andrew Gierth and Andres Freund Author: Andres Freund Discussion: https://postgr.es/m/20180905005130.ewk4xcs5dgyzcy45@alap3.anarazel.de Backpatch: 9.3-, all supported versions are affected
1 parent 8ffc3be commit 84f14fb

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

configure

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6797,6 +6797,39 @@ fi
67976797
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
67986798
fi
67996799

6800+
# Defend against clang being used on x86-32 without SSE2 enabled. As current
6801+
# versions of clang do not understand -fexcess-precision=standard, the use of
6802+
# x87 floating point operations leads to problems like isinf possibly returning
6803+
# false for a value that is infinite when converted from the 80bit register to
6804+
# the 8byte memory representation.
6805+
#
6806+
# Only perform the test if the compiler doesn't understand
6807+
# -fexcess-precision=standard, that way a potentially fixed compiler will work
6808+
# automatically.
6809+
if test "$pgac_cv_prog_CC_cflags__fexcess_precision_standard" = no; then
6810+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
6811+
/* end confdefs.h. */
6812+
6813+
int
6814+
main ()
6815+
{
6816+
6817+
#if defined(__clang__) && defined(__i386__) && !defined(__SSE2_MATH__)
6818+
choke me
6819+
#endif
6820+
6821+
;
6822+
return 0;
6823+
}
6824+
_ACEOF
6825+
if ac_fn_c_try_compile "$LINENO"; then :
6826+
6827+
else
6828+
as_fn_error $? "Compiling PostgreSQL with clang, on 32bit x86, requires SSE2 support. Use -msse2 or use gcc." "$LINENO" 5
6829+
fi
6830+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
6831+
fi
6832+
68006833
ac_ext=c
68016834
ac_cpp='$CPP $CPPFLAGS'
68026835
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'

configure.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,24 @@ choke me
613613
@%:@endif])], [], [AC_MSG_ERROR([do not put -ffast-math in CFLAGS])])
614614
fi
615615

616+
# Defend against clang being used on x86-32 without SSE2 enabled. As current
617+
# versions of clang do not understand -fexcess-precision=standard, the use of
618+
# x87 floating point operations leads to problems like isinf possibly returning
619+
# false for a value that is infinite when converted from the 80bit register to
620+
# the 8byte memory representation.
621+
#
622+
# Only perform the test if the compiler doesn't understand
623+
# -fexcess-precision=standard, that way a potentially fixed compiler will work
624+
# automatically.
625+
if test "$pgac_cv_prog_CC_cflags__fexcess_precision_standard" = no; then
626+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
627+
@%:@if defined(__clang__) && defined(__i386__) && !defined(__SSE2_MATH__)
628+
choke me
629+
@%:@endif
630+
])], [],
631+
[AC_MSG_ERROR([Compiling PostgreSQL with clang, on 32bit x86, requires SSE2 support. Use -msse2 or use gcc.])])
632+
fi
633+
616634
AC_PROG_CPP
617635
AC_SUBST(GCC)
618636

0 commit comments

Comments
 (0)