Patchwork fix libquadmath build regression

login
register
mail settings
Submitter Alexandre Oliva
Date Dec. 30, 2012, 12:17 a.m.
Message ID <or38yo4cmm.fsf@livre.localdomain>
Download mbox | patch
Permalink /patch/208687/
State New
Headers show

Comments

Alexandre Oliva - Dec. 30, 2012, 12:17 a.m.
On Dec 21, 2012, Tobias Burnus <burnus@net-b.de> wrote:

> Otherwise, it looks okay to me.

Thanks, I'd fixed all the problems you caught in the review, but then
Paolo's suggestion to use fixincludes came in and I sat on it for a
while.  I'm now leaning towards fixincludes, but I figured I'd post the
latest version of the patch for libquadmath just in case the library
maintainers wish to have an internal fix for this particular bug.  What
do you say, should I put it in?

Patch

Deal with SSE-requiring extern inline in bits/fenv.h

From: Alexandre Oliva <aoliva@redhat.com>

for  libquadmath/ChangeLog

	* configure.ac: Check that calling feraiseexcept compiles when
	fenv.h is included.  Define QUADMATH_FERAISEEXCEPT cpp macro
	and LIBQUAD_FERAISEEXCEPT conditional otherwise.
	* Makefile.am (libquadmath_la_SOURCES): Add
	math/feraiseexcept.c, conditional on LIBQUAD_FERAISEEXCEPT.
	* aclocal.m4: Rebuilt.
	* configure: Rebuilt.
	* config.h.in: Rebuilt.
	* Makefile.in: Rebuilt.
	* math/feraiseexcept.c: New file.
	* math/quadmath-imp.h (__quadmath_feraiseexcept): Declare.
	* math/ccoshq.c: Use QUADMATH_FERAISEEXCEPT macro to call, and
	to decide whether to call, feraiseexcept.
	* math/cexpq.c: Likewise.
	* math/csinhq.c: Likewise.
	* math/csinq.c: Likewise.
	* math/ctanhq.c: Likewise.
	* math/ctanq.c: Likewise.
	* math/ilogbq.c: Likewise.  Include fenv.h if HAVE_FENV_H.
---

 libquadmath/Makefile.am          |    3 +
 libquadmath/Makefile.in          |   90 ++++++++++++++++++++++++++------------
 libquadmath/config.h.in          |    3 +
 libquadmath/configure            |   59 ++++++++++++++++++++++++-
 libquadmath/configure.ac         |   28 ++++++++++++
 libquadmath/math/ccoshq.c        |    8 ++-
 libquadmath/math/cexpq.c         |   12 +++--
 libquadmath/math/csinhq.c        |   12 +++--
 libquadmath/math/csinq.c         |   12 +++--
 libquadmath/math/ctanhq.c        |    4 +-
 libquadmath/math/ctanq.c         |    4 +-
 libquadmath/math/feraiseexcept.c |   12 +++++
 libquadmath/math/ilogbq.c        |   16 ++++---
 libquadmath/quadmath-imp.h       |    5 +-
 14 files changed, 204 insertions(+), 64 deletions(-)
 create mode 100644 libquadmath/math/feraiseexcept.c


diff --git a/libquadmath/Makefile.am b/libquadmath/Makefile.am
index 6c97ee8..9acf619 100644
--- a/libquadmath/Makefile.am
+++ b/libquadmath/Makefile.am
@@ -69,6 +69,9 @@  libquadmath_la_SOURCES = \
   printf/quadmath-printf.c printf/rshift.c printf/submul_1.c printf/sub_n.c \
   strtod/strtoflt128.c strtod/mpn2flt128.c strtod/tens_in_limb.c
 
+if LIBQUAD_FERAISEEXCEPT
+libquadmath_la_SOURCES += math/feraiseexcept.c
+endif
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
 # values defined in terms of make variables, as is the case for CC and
diff --git a/libquadmath/Makefile.in b/libquadmath/Makefile.in
index 92c5d25..395e236 100644
--- a/libquadmath/Makefile.in
+++ b/libquadmath/Makefile.in
@@ -37,6 +37,7 @@  build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @BUILD_LIBQUADMATH_FALSE@libquadmath_la_DEPENDENCIES =
+@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_FERAISEEXCEPT_TRUE@am__append_1 = math/feraiseexcept.c
 subdir = .
 DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/configure $(am__configure_deps) \
@@ -87,6 +88,7 @@  am__installdirs = "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(infodir)" \
 	"$(DESTDIR)$(libsubincludedir)"
 LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
 am__dirstamp = $(am__leading_dot)dirstamp
+@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_FERAISEEXCEPT_TRUE@am__objects_1 = math/feraiseexcept.lo
 @BUILD_LIBQUADMATH_TRUE@am_libquadmath_la_OBJECTS = math/x2y2m1q.lo \
 @BUILD_LIBQUADMATH_TRUE@	math/isinf_nsq.lo math/acoshq.lo \
 @BUILD_LIBQUADMATH_TRUE@	math/fmodq.lo math/acosq.lo \
@@ -142,7 +144,8 @@  am__dirstamp = $(am__leading_dot)dirstamp
 @BUILD_LIBQUADMATH_TRUE@	printf/rshift.lo printf/submul_1.lo \
 @BUILD_LIBQUADMATH_TRUE@	printf/sub_n.lo strtod/strtoflt128.lo \
 @BUILD_LIBQUADMATH_TRUE@	strtod/mpn2flt128.lo \
-@BUILD_LIBQUADMATH_TRUE@	strtod/tens_in_limb.lo
+@BUILD_LIBQUADMATH_TRUE@	strtod/tens_in_limb.lo \
+@BUILD_LIBQUADMATH_TRUE@	$(am__objects_1)
 libquadmath_la_OBJECTS = $(am_libquadmath_la_OBJECTS)
 libquadmath_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -325,33 +328,59 @@  AUTOMAKE_OPTIONS = 1.8 foreign
 @BUILD_LIBQUADMATH_TRUE@libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD)
 @BUILD_LIBQUADMATH_TRUE@nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h
 @BUILD_LIBQUADMATH_TRUE@libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
-@BUILD_LIBQUADMATH_TRUE@libquadmath_la_SOURCES = \
-@BUILD_LIBQUADMATH_TRUE@  math/x2y2m1q.c math/isinf_nsq.c math/acoshq.c math/fmodq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/acosq.c math/frexpq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/rem_pio2q.c math/asinhq.c math/hypotq.c math/remainderq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/asinq.c math/rintq.c math/atan2q.c math/isinfq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/roundq.c math/atanhq.c math/isnanq.c math/scalblnq.c math/atanq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/j0q.c math/scalbnq.c math/cbrtq.c math/j1q.c math/signbitq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/ceilq.c math/jnq.c math/sincos_table.c math/complex.c math/ldexpq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/sincosq.c math/copysignq.c math/lgammaq.c math/sincosq_kernel.c \
-@BUILD_LIBQUADMATH_TRUE@  math/coshq.c math/llroundq.c math/sinhq.c math/cosq.c math/log10q.c \
-@BUILD_LIBQUADMATH_TRUE@  math/sinq.c math/cosq_kernel.c math/log1pq.c math/sinq_kernel.c \
-@BUILD_LIBQUADMATH_TRUE@  math/erfq.c math/logq.c math/sqrtq.c math/expm1q.c math/lroundq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/tanhq.c math/expq.c math/modfq.c math/tanq.c math/fabsq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/nanq.c math/tgammaq.c math/finiteq.c math/nextafterq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/truncq.c math/floorq.c math/powq.c math/fmaq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/cacoshq.c math/cacosq.c math/casinhq.c math/casinq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/catanhq.c math/catanq.c math/cimagq.c math/conjq.c math/cprojq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/crealq.c math/fdimq.c math/fmaxq.c math/fminq.c math/ilogbq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/ccoshq.c math/cexpq.c math/clog10q.c math/clogq.c math/csinq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/csinhq.c math/csqrtq.c math/ctanq.c math/ctanhq.c \
-@BUILD_LIBQUADMATH_TRUE@  printf/addmul_1.c printf/add_n.c printf/cmp.c printf/divrem.c \
-@BUILD_LIBQUADMATH_TRUE@  printf/flt1282mpn.c printf/fpioconst.c printf/lshift.c printf/mul_1.c \
-@BUILD_LIBQUADMATH_TRUE@  printf/mul_n.c printf/mul.c printf/printf_fphex.c printf/printf_fp.c \
-@BUILD_LIBQUADMATH_TRUE@  printf/quadmath-printf.c printf/rshift.c printf/submul_1.c printf/sub_n.c \
-@BUILD_LIBQUADMATH_TRUE@  strtod/strtoflt128.c strtod/mpn2flt128.c strtod/tens_in_limb.c
-
+@BUILD_LIBQUADMATH_TRUE@libquadmath_la_SOURCES = math/x2y2m1q.c \
+@BUILD_LIBQUADMATH_TRUE@	math/isinf_nsq.c math/acoshq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/fmodq.c math/acosq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/frexpq.c math/rem_pio2q.c \
+@BUILD_LIBQUADMATH_TRUE@	math/asinhq.c math/hypotq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/remainderq.c math/asinq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/rintq.c math/atan2q.c \
+@BUILD_LIBQUADMATH_TRUE@	math/isinfq.c math/roundq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/atanhq.c math/isnanq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/scalblnq.c math/atanq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/j0q.c math/scalbnq.c math/cbrtq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/j1q.c math/signbitq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/ceilq.c math/jnq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/sincos_table.c math/complex.c \
+@BUILD_LIBQUADMATH_TRUE@	math/ldexpq.c math/sincosq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/copysignq.c math/lgammaq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/sincosq_kernel.c math/coshq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/llroundq.c math/sinhq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/cosq.c math/log10q.c math/sinq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/cosq_kernel.c math/log1pq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/sinq_kernel.c math/erfq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/logq.c math/sqrtq.c math/expm1q.c \
+@BUILD_LIBQUADMATH_TRUE@	math/lroundq.c math/tanhq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/expq.c math/modfq.c math/tanq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/fabsq.c math/nanq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/tgammaq.c math/finiteq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/nextafterq.c math/truncq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/floorq.c math/powq.c math/fmaq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/cacoshq.c math/cacosq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/casinhq.c math/casinq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/catanhq.c math/catanq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/cimagq.c math/conjq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/cprojq.c math/crealq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/fdimq.c math/fmaxq.c math/fminq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/ilogbq.c math/llrintq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/log2q.c math/lrintq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/nearbyintq.c math/remquoq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/ccoshq.c math/cexpq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/clog10q.c math/clogq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/csinq.c math/csinhq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/csqrtq.c math/ctanq.c \
+@BUILD_LIBQUADMATH_TRUE@	math/ctanhq.c printf/addmul_1.c \
+@BUILD_LIBQUADMATH_TRUE@	printf/add_n.c printf/cmp.c \
+@BUILD_LIBQUADMATH_TRUE@	printf/divrem.c printf/flt1282mpn.c \
+@BUILD_LIBQUADMATH_TRUE@	printf/fpioconst.c printf/lshift.c \
+@BUILD_LIBQUADMATH_TRUE@	printf/mul_1.c printf/mul_n.c \
+@BUILD_LIBQUADMATH_TRUE@	printf/mul.c printf/printf_fphex.c \
+@BUILD_LIBQUADMATH_TRUE@	printf/printf_fp.c \
+@BUILD_LIBQUADMATH_TRUE@	printf/quadmath-printf.c \
+@BUILD_LIBQUADMATH_TRUE@	printf/rshift.c printf/submul_1.c \
+@BUILD_LIBQUADMATH_TRUE@	printf/sub_n.c strtod/strtoflt128.c \
+@BUILD_LIBQUADMATH_TRUE@	strtod/mpn2flt128.c \
+@BUILD_LIBQUADMATH_TRUE@	strtod/tens_in_limb.c $(am__append_1)
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
 # values defined in terms of make variables, as is the case for CC and
@@ -655,6 +684,8 @@  strtod/mpn2flt128.lo: strtod/$(am__dirstamp) \
 	strtod/$(DEPDIR)/$(am__dirstamp)
 strtod/tens_in_limb.lo: strtod/$(am__dirstamp) \
 	strtod/$(DEPDIR)/$(am__dirstamp)
+math/feraiseexcept.lo: math/$(am__dirstamp) \
+	math/$(DEPDIR)/$(am__dirstamp)
 libquadmath.la: $(libquadmath_la_OBJECTS) $(libquadmath_la_DEPENDENCIES) 
 	$(libquadmath_la_LINK) $(am_libquadmath_la_rpath) $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD) $(LIBS)
 
@@ -736,6 +767,8 @@  mostlyclean-compile:
 	-rm -f math/fabsq.lo
 	-rm -f math/fdimq.$(OBJEXT)
 	-rm -f math/fdimq.lo
+	-rm -f math/feraiseexcept.$(OBJEXT)
+	-rm -f math/feraiseexcept.lo
 	-rm -f math/finiteq.$(OBJEXT)
 	-rm -f math/finiteq.lo
 	-rm -f math/floorq.$(OBJEXT)
@@ -916,6 +949,7 @@  distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/expq.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/fabsq.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/fdimq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/feraiseexcept.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/finiteq.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/floorq.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/fmaq.Plo@am__quote@
diff --git a/libquadmath/config.h.in b/libquadmath/config.h.in
index 9d18cc3..66ce693 100644
--- a/libquadmath/config.h.in
+++ b/libquadmath/config.h.in
@@ -118,6 +118,9 @@ 
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
+/* Function to call to get the effects of feraiseexcept. */
+#undef QUADMATH_FERAISEEXCEPT
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
diff --git a/libquadmath/configure b/libquadmath/configure
index 0ea6e07..e8aa317 100755
--- a/libquadmath/configure
+++ b/libquadmath/configure
@@ -611,6 +611,8 @@  LIBQUAD_USE_SYMVER_GNU_FALSE
 LIBQUAD_USE_SYMVER_GNU_TRUE
 LIBQUAD_USE_SYMVER_FALSE
 LIBQUAD_USE_SYMVER_TRUE
+LIBQUAD_FERAISEEXCEPT_FALSE
+LIBQUAD_FERAISEEXCEPT_TRUE
 toolexeclibdir
 toolexecdir
 multi_basedir
@@ -10521,7 +10523,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10524 "configure"
+#line 10526 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10627,7 +10629,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10630 "configure"
+#line 10632 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12351,6 +12353,55 @@  $as_echo "#define HAVE_FETESTEXCEPT 1" >>confdefs.h
   fi
 fi
 
+if test "x$ac_cv_header_fenv_h" = "xyes"; then
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether feraiseexcept is broken in fenv.h" >&5
+$as_echo_n "checking whether feraiseexcept is broken in fenv.h... " >&6; }
+if test "${quadmath_cv_feraiseexcept_fenv_broken+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <fenv.h>
+int
+main ()
+{
+feraiseexcept (FE_INVALID);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  quadmath_cv_feraiseexcept_fenv_broken=no
+else
+  quadmath_cv_feraiseexcept_fenv_broken=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $quadmath_cv_feraiseexcept_fenv_broken" >&5
+$as_echo "$quadmath_cv_feraiseexcept_fenv_broken" >&6; }
+  if test "x$quadmath_cv_feraiseexcept_fenv_broken" = "xyes"; then
+    feraiseexcept=__quadmath_feraiseexcept
+  else
+    feraiseexcept=feraiseexcept
+  fi
+
+cat >>confdefs.h <<_ACEOF
+#define QUADMATH_FERAISEEXCEPT $feraiseexcept
+_ACEOF
+
+fi
+ if test "x$ac_cv_header_fenv_h$quadmath_cv_feraiseexcept_fenv_broken" \
+        = "xyesyes"; then
+  LIBQUAD_FERAISEEXCEPT_TRUE=
+  LIBQUAD_FERAISEEXCEPT_FALSE='#'
+else
+  LIBQUAD_FERAISEEXCEPT_TRUE='#'
+  LIBQUAD_FERAISEEXCEPT_FALSE=
+fi
+
+
 # Check for hidden visibility (copied from libssp).
 saved_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -Werror"
@@ -13035,6 +13086,10 @@  if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
   as_fn_error "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${LIBQUAD_FERAISEEXCEPT_TRUE}" && test -z "${LIBQUAD_FERAISEEXCEPT_FALSE}"; then
+  as_fn_error "conditional \"LIBQUAD_FERAISEEXCEPT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${LIBQUAD_USE_SYMVER_TRUE}" && test -z "${LIBQUAD_USE_SYMVER_FALSE}"; then
   as_fn_error "conditional \"LIBQUAD_USE_SYMVER\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/libquadmath/configure.ac b/libquadmath/configure.ac
index c547da8..7df8c37 100644
--- a/libquadmath/configure.ac
+++ b/libquadmath/configure.ac
@@ -150,6 +150,34 @@  else
   fi
 fi
 
+if test "x$ac_cv_header_fenv_h" = "xyes"; then
+  dnl Some versions of libc 2.16 for x86_64 have an extern inline
+  dnl definition of feraiseexcept in bits/fenv.h that requires SSE
+  dnl support, and they fail to compile with -m32 when targeting
+  dnl pre-x86_64 32-bit architectures.
+
+  dnl This wrapper enables us to bypass the inline definition and call
+  dnl the out-of-line feraiseexcept definition, because it does not
+  dnl include fenv.h itself.
+
+  AC_CACHE_CHECK([whether feraiseexcept is broken in fenv.h],
+    [quadmath_cv_feraiseexcept_fenv_broken],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <fenv.h>]],
+        [feraiseexcept (FE_INVALID);])],
+      [quadmath_cv_feraiseexcept_fenv_broken=no],
+      [quadmath_cv_feraiseexcept_fenv_broken=yes])])
+  if test "x$quadmath_cv_feraiseexcept_fenv_broken" = "xyes"; then
+    feraiseexcept=__quadmath_feraiseexcept
+  else
+    feraiseexcept=feraiseexcept
+  fi
+  AC_DEFINE_UNQUOTED([QUADMATH_FERAISEEXCEPT], [$feraiseexcept],
+    [Function to call to get the effects of feraiseexcept.])
+fi
+AM_CONDITIONAL([LIBQUAD_FERAISEEXCEPT],
+  [test "x$ac_cv_header_fenv_h$quadmath_cv_feraiseexcept_fenv_broken" \
+        = "xyesyes"])
+
 # Check for hidden visibility (copied from libssp).
 saved_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -Werror"
diff --git a/libquadmath/math/ccoshq.c b/libquadmath/math/ccoshq.c
index 8d55ad3..c1b24ac 100644
--- a/libquadmath/math/ccoshq.c
+++ b/libquadmath/math/ccoshq.c
@@ -89,9 +89,9 @@  ccoshq (__complex128 x)
 	  __imag__ retval = __real__ x == 0.0Q ? 0.0Q : nanq ("");
 	  __real__ retval = nanq ("") + nanq ("");
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
 	  if (icls == QUADFP_INFINITE)
-	    feraiseexcept (FE_INVALID);
+	    QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
         }
     }
@@ -129,9 +129,9 @@  ccoshq (__complex128 x)
 	  __real__ retval = HUGE_VALQ;
 	  __imag__ retval = nanq ("") + nanq ("");
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
 	  if (icls == QUADFP_INFINITE)
-	    feraiseexcept (FE_INVALID);
+	    QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	 }
     }
diff --git a/libquadmath/math/cexpq.c b/libquadmath/math/cexpq.c
index bd4be1e..a7f42bf 100644
--- a/libquadmath/math/cexpq.c
+++ b/libquadmath/math/cexpq.c
@@ -83,8 +83,8 @@  cexpq (__complex128 x)
 	  __real__ retval = nanq ("");
 	  __imag__ retval = nanq ("");
 
-#ifdef HAVE_FENV_H
-	  feraiseexcept (FE_INVALID);
+#ifdef QUADMATH_FERAISEEXCEPT
+	  QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	}
     }
@@ -125,9 +125,9 @@  cexpq (__complex128 x)
 	  __real__ retval = HUGE_VALQ;
 	  __imag__ retval = nanq ("");
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
 	  if (icls == QUADFP_INFINITE)
-	    feraiseexcept (FE_INVALID);
+	    QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	}
       else
@@ -142,9 +142,9 @@  cexpq (__complex128 x)
       __real__ retval = nanq ("");
       __imag__ retval = nanq ("");
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
       if (rcls != QUADFP_NAN || icls != QUADFP_NAN)
-	feraiseexcept (FE_INVALID);
+	QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
     }
 
diff --git a/libquadmath/math/csinhq.c b/libquadmath/math/csinhq.c
index c16d576..5f1d8df 100644
--- a/libquadmath/math/csinhq.c
+++ b/libquadmath/math/csinhq.c
@@ -98,9 +98,9 @@  csinhq (__complex128 x)
 	      __real__ retval = copysignq (0.0Q, negate ? -1.0Q : 1.0Q);
 	      __imag__ retval = nanq ("") + nanq ("");
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
 	      if (icls == QUADFP_INFINITE)
-		feraiseexcept (FE_INVALID);
+		QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	    }
 	  else
@@ -108,8 +108,8 @@  csinhq (__complex128 x)
 	      __real__ retval = nanq ("");
 	      __imag__ retval = nanq ("");
 
-#ifdef HAVE_FENV_H
-	      feraiseexcept (FE_INVALID);
+#ifdef QUADMATH_FERAISEEXCEPT
+	      QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	    }
 	}
@@ -150,9 +150,9 @@  csinhq (__complex128 x)
 	  __real__ retval = HUGE_VALQ;
 	  __imag__ retval = nanq ("") + nanq ("");
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
 	  if (icls == QUADFP_INFINITE)
-	    feraiseexcept (FE_INVALID);
+	    QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	}
     }
diff --git a/libquadmath/math/csinq.c b/libquadmath/math/csinq.c
index c837e50..cd37013 100644
--- a/libquadmath/math/csinq.c
+++ b/libquadmath/math/csinq.c
@@ -98,9 +98,9 @@  csinq (__complex128 x)
 	      __real__ retval = nanq ("");
 	      __imag__ retval = __imag__ x;
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
 	      if (rcls == QUADFP_INFINITE)
-		feraiseexcept (FE_INVALID);
+		QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	    }
 	  else
@@ -108,8 +108,8 @@  csinq (__complex128 x)
 	      __real__ retval = nanq ("");
 	      __imag__ retval = nanq ("");
 
-#ifdef HAVE_FENV_H
-	      feraiseexcept (FE_INVALID);
+#ifdef QUADMATH_FERAISEEXCEPT
+	      QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	    }
 	}
@@ -152,9 +152,9 @@  csinq (__complex128 x)
 	  __real__ retval = nanq ("");
 	  __imag__ retval = HUGE_VALQ;
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
 	  if (rcls == QUADFP_INFINITE)
-	    feraiseexcept (FE_INVALID);
+	    QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	}
     }
diff --git a/libquadmath/math/ctanhq.c b/libquadmath/math/ctanhq.c
index 8934cfa..e954965 100644
--- a/libquadmath/math/ctanhq.c
+++ b/libquadmath/math/ctanhq.c
@@ -45,9 +45,9 @@  ctanhq (__complex128 x)
 	  __real__ res = nanq ("");
 	  __imag__ res = nanq ("");
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
 	  if (__quadmath_isinf_nsq (__imag__ x))
-	    feraiseexcept (FE_INVALID);
+	    QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	}
     }
diff --git a/libquadmath/math/ctanq.c b/libquadmath/math/ctanq.c
index d390511..d3570be 100644
--- a/libquadmath/math/ctanq.c
+++ b/libquadmath/math/ctanq.c
@@ -45,9 +45,9 @@  ctanq (__complex128 x)
 	  __real__ res = nanq ("");
 	  __imag__ res = nanq ("");
 
-#ifdef HAVE_FENV_H
+#ifdef QUADMATH_FERAISEEXCEPT
 	  if (__quadmath_isinf_nsq (__real__ x))
-	    feraiseexcept (FE_INVALID);
+	    QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	}
     }
diff --git a/libquadmath/math/feraiseexcept.c b/libquadmath/math/feraiseexcept.c
new file mode 100644
index 0000000..b47ff5c
--- /dev/null
+++ b/libquadmath/math/feraiseexcept.c
@@ -0,0 +1,12 @@ 
+/* Wrapper for feraiseexcept.  This file is in the public domain.
+   Contributed by Alexandre Oliva <aoliva@redhat.com>
+   See QUADMATH_FERAISEEXCEPT in configure.ac for more information.  */
+
+/* Do NOT include fenv.h.  This is a wrapper for a broken extern
+   inline feraiseexcept defined there.  */
+int
+__quadmath_feraiseexcept (int xcpt)
+{
+  extern int feraiseexcept (int);
+  return feraiseexcept (xcpt);
+}
diff --git a/libquadmath/math/ilogbq.c b/libquadmath/math/ilogbq.c
index 7f95e9c..553df9e 100644
--- a/libquadmath/math/ilogbq.c
+++ b/libquadmath/math/ilogbq.c
@@ -29,6 +29,10 @@  static char rcsid[] = "$NetBSD: $";
 #include <errno.h>
 #include "quadmath-imp.h"
 
+#ifdef HAVE_FENV_H
+# include <fenv.h>
+#endif
+
 #ifndef FP_ILOGB0
 # define FP_ILOGB0 INT_MIN
 #endif
@@ -48,8 +52,8 @@  ilogbq (__float128 x)
 	    if((hx|lx)==0)
 	      {
 		errno = EDOM;
-#ifdef USE_FENV_H
-		feraiseexcept (FE_INVALID);
+#ifdef QUADMATH_FERAISEEXCEPT
+		QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 		return FP_ILOGB0;	/* ilogbl(0) = FP_ILOGB0 */
 	      }
@@ -67,16 +71,16 @@  ilogbq (__float128 x)
 	    if (((hx^0x7fff000000000000LL)|lx) == 0)
 	      {
 		errno = EDOM;
-#ifdef USE_FENV_H
-		feraiseexcept (FE_INVALID);
+#ifdef QUADMATH_FERAISEEXCEPT
+		QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 		return INT_MAX;
 	      }
 	}
 
 	errno = EDOM;
-#ifdef USE_FENV_H
-	feraiseexcept (FE_INVALID);
+#ifdef QUADMATH_FERAISEEXCEPT
+	QUADMATH_FERAISEEXCEPT (FE_INVALID);
 #endif
 	return FP_ILOGBNAN;
 }
diff --git a/libquadmath/quadmath-imp.h b/libquadmath/quadmath-imp.h
index 40b346b..6951393 100644
--- a/libquadmath/quadmath-imp.h
+++ b/libquadmath/quadmath-imp.h
@@ -46,8 +46,9 @@  extern __float128 __quadmath_kernel_cosq (__float128, __float128);
 extern __float128 __quadmath_x2y2m1q (__float128 x, __float128 y);
 extern int __quadmath_isinf_nsq (__float128 x);
 
-
-
+#ifdef HAVE_FENV_H
+extern int __quadmath_feraiseexcept (int);
+#endif
 
 
 /* Frankly, if you have __float128, you have 64-bit integers, right?  */