Skip to content

Commit 978515d

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 591d0ac commit 978515d

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

configure

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5158,6 +5158,66 @@ fi
51585158
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
51595159
fi
51605160

5161+
# Defend against clang being used on x86-32 without SSE2 enabled. As current
5162+
# versions of clang do not understand -fexcess-precision=standard, the use of
5163+
# x87 floating point operations leads to problems like isinf possibly returning
5164+
# false for a value that is infinite when converted from the 80bit register to
5165+
# the 8byte memory representation.
5166+
#
5167+
# Only perform the test if the compiler doesn't understand
5168+
# -fexcess-precision=standard, that way a potentially fixed compiler will work
5169+
# automatically.
5170+
if test "$pgac_cv_prog_cc_cflags__fexcess_precision_standard" = no; then
5171+
cat >conftest.$ac_ext <<_ACEOF
5172+
/* confdefs.h. */
5173+
_ACEOF
5174+
cat confdefs.h >>conftest.$ac_ext
5175+
cat >>conftest.$ac_ext <<_ACEOF
5176+
/* end confdefs.h. */
5177+
5178+
int
5179+
main ()
5180+
{
5181+
5182+
#if defined(__clang__) && defined(__i386__) && !defined(__SSE2_MATH__)
5183+
choke me
5184+
#endif
5185+
5186+
;
5187+
return 0;
5188+
}
5189+
_ACEOF
5190+
rm -f conftest.$ac_objext
5191+
if { (ac_try="$ac_compile"
5192+
case "(($ac_try" in
5193+
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
5194+
*) ac_try_echo=$ac_try;;
5195+
esac
5196+
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
5197+
$as_echo "$ac_try_echo") >&5
5198+
(eval "$ac_compile") 2>conftest.er1
5199+
ac_status=$?
5200+
grep -v '^ *+' conftest.er1 >conftest.err
5201+
rm -f conftest.er1
5202+
cat conftest.err >&5
5203+
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
5204+
(exit $ac_status); } && {
5205+
test -z "$ac_c_werror_flag" ||
5206+
test ! -s conftest.err
5207+
} && test -s conftest.$ac_objext; then
5208+
:
5209+
else
5210+
$as_echo "$as_me: failed program was:" >&5
5211+
sed 's/^/| /' conftest.$ac_ext >&5
5212+
5213+
{ { $as_echo "$as_me:$LINENO: error: Compiling PostgreSQL with clang, on 32bit x86, requires SSE2 support. Use -msse2 or use gcc." >&5
5214+
$as_echo "$as_me: error: Compiling PostgreSQL with clang, on 32bit x86, requires SSE2 support. Use -msse2 or use gcc." >&2;}
5215+
{ (exit 1); exit 1; }; }
5216+
fi
5217+
5218+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
5219+
fi
5220+
51615221
ac_ext=c
51625222
ac_cpp='$CPP $CPPFLAGS'
51635223
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
@@ -508,6 +508,24 @@ choke me
508508
@%:@endif], [], [AC_MSG_ERROR([do not put -ffast-math in CFLAGS])])
509509
fi
510510

511+
# Defend against clang being used on x86-32 without SSE2 enabled. As current
512+
# versions of clang do not understand -fexcess-precision=standard, the use of
513+
# x87 floating point operations leads to problems like isinf possibly returning
514+
# false for a value that is infinite when converted from the 80bit register to
515+
# the 8byte memory representation.
516+
#
517+
# Only perform the test if the compiler doesn't understand
518+
# -fexcess-precision=standard, that way a potentially fixed compiler will work
519+
# automatically.
520+
if test "$pgac_cv_prog_cc_cflags__fexcess_precision_standard" = no; then
521+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
522+
@%:@if defined(__clang__) && defined(__i386__) && !defined(__SSE2_MATH__)
523+
choke me
524+
@%:@endif
525+
])], [],
526+
[AC_MSG_ERROR([Compiling PostgreSQL with clang, on 32bit x86, requires SSE2 support. Use -msse2 or use gcc.])])
527+
fi
528+
511529
AC_PROG_CPP
512530
AC_SUBST(GCC)
513531

0 commit comments

Comments
 (0)