From e65e23ee8a264b8dec01e953529960b2e1f0bc95 Mon Sep 17 00:00:00 2001 From: Marius Gerbershagen Date: Mon, 6 Jan 2020 20:03:50 +0100 Subject: [PATCH] configure: check if feenableexcept is actually working Not all processors will signal floating point exceptions even when told so, for example the Raspberry Pi as Dave Richards pointed out on the ecl-devel mailing list. --- src/aclocal.m4 | 47 +++++++++++++++++++++++ src/configure | 91 +++++++++++++++++++++++++++++++++++++++------ src/configure.ac | 6 +-- src/ecl/configpre.h | 2 +- 4 files changed, 129 insertions(+), 17 deletions(-) diff --git a/src/aclocal.m4 b/src/aclocal.m4 index d1e626a77..dae305572 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -939,6 +939,53 @@ if test $ECL_WORKING_ENVIRON = yes ; then fi ]) +dnl +dnl -------------------------------------------------------------- +dnl Check if we have feenableexcept and the hardware generates +dnl floating point exceptions. +dnl +AC_DEFUN(ECL_FLOATING_POINT_EXCEPTIONS,[ + if test "${with_fpe}" = "yes" ; then + AC_MSG_CHECKING(for working feenableexcept) + saved_libs="${LIBS}" + LIBS="-lm" + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + +#define _GNU_SOURCE +#include +#include +#include + +const int traps = FE_DIVBYZERO | FE_OVERFLOW; + +void fpe_handler(int code) { + if (code == SIGFPE) + exit(0); +} + +double raises_fpe(double x) { + return x / 0.0; +} + +int main() { + signal(SIGFPE, fpe_handler); + feclearexcept(traps); + feenableexcept(traps); + raises_fpe(1.0); + return 1; +} +]])], + [AC_DEFINE([HAVE_FEENABLEEXCEPT], [], [feenableexcept works]) + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(only checking if feenableexcept is present due to cross compilation) + AC_CHECK_DECL([feenableexcept], + [AC_DEFINE(HAVE_FEENABLEEXCEPT,[],[feenableexcept is declared])], + [], + [#include ])]) + LIBS="${saved_libs}" + fi]) + dnl ---------------------------------------------------------------------- dnl Configure libatomic-ops dnl diff --git a/src/configure b/src/configure index 7864bb403..eb8a2c685 100755 --- a/src/configure +++ b/src/configure @@ -741,6 +741,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -866,6 +867,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1118,6 +1120,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1255,7 +1266,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1408,6 +1419,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -8996,6 +9008,8 @@ main () if (*(data + i) != *(data3 + i)) return 14; close (fd); + free (data); + free (data3); return 0; } _ACEOF @@ -9443,17 +9457,6 @@ _ACEOF fi done -ac_fn_c_check_decl "$LINENO" "feenableexcept" "ac_cv_have_decl_feenableexcept" "#include -" -if test "x$ac_cv_have_decl_feenableexcept" = xyes; then : - -$as_echo "#define HAVE_FEENABLEEXCEPT /**/" >>confdefs.h - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: feenableexcept not declared: disabling floating point exceptions" >&5 -$as_echo "$as_me: WARNING: feenableexcept not declared: disabling floating point exceptions" >&2;} -fi - for ac_func in expf powf logf sqrtf cosf sinf tanf sinhf coshf tanhf \ floorf ceilf fabsf frexpf ldexpf log1p log1pf log1pl \ @@ -9537,6 +9540,70 @@ fi + if test "${with_fpe}" = "yes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working feenableexcept" >&5 +$as_echo_n "checking for working feenableexcept... " >&6; } + saved_libs="${LIBS}" + LIBS="-lm" + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: only checking if feenableexcept is present due to cross compilation" >&5 +$as_echo "only checking if feenableexcept is present due to cross compilation" >&6; } + ac_fn_c_check_decl "$LINENO" "feenableexcept" "ac_cv_have_decl_feenableexcept" "#include +" +if test "x$ac_cv_have_decl_feenableexcept" = xyes; then : + +$as_echo "#define HAVE_FEENABLEEXCEPT /**/" >>confdefs.h + +fi + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#define _GNU_SOURCE +#include +#include +#include + +const int traps = FE_DIVBYZERO | FE_OVERFLOW; + +void fpe_handler(int code) { + if (code == SIGFPE) + exit(0); +} + +double raises_fpe(double x) { + return x / 0.0; +} + +int main() { + signal(SIGFPE, fpe_handler); + feclearexcept(traps); + feenableexcept(traps); + raises_fpe(1.0); + return 1; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +$as_echo "#define HAVE_FEENABLEEXCEPT /**/" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + LIBS="${saved_libs}" + fi + + if test ${with_cxx} = "no" ; then ECL_CC=${CC} diff --git a/src/configure.ac b/src/configure.ac index 84c45229e..d4740fa66 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -738,10 +738,6 @@ dnl !!! end autoscan AC_CHECK_FUNCS( [nanosleep alarm times select setenv putenv] \ [lstat mkstemp sigprocmask isatty tzset] \ [gettimeofday getrusage system] ) -AC_CHECK_DECL([feenableexcept], - [AC_DEFINE(HAVE_FEENABLEEXCEPT,[],[feenableexcept is available])], - [AC_MSG_WARN(feenableexcept not declared: disabling floating point exceptions)], - [#include ]) AC_CHECK_FUNCS( [expf powf logf sqrtf cosf sinf tanf sinhf coshf tanhf] \ [floorf ceilf fabsf frexpf ldexpf log1p log1pf log1pl] \ @@ -756,6 +752,8 @@ AC_CHECK_HEADER( [sys/mman.h], ECL_POSIX_ENVIRON +ECL_FLOATING_POINT_EXCEPTIONS + dnl ===================================================================== dnl Checks for system services diff --git a/src/ecl/configpre.h b/src/ecl/configpre.h index 41c737dc2..c573e5fd7 100644 --- a/src/ecl/configpre.h +++ b/src/ecl/configpre.h @@ -303,7 +303,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H -/* feenableexcept is available */ +/* feenableexcept works */ #undef HAVE_FEENABLEEXCEPT /* Define to 1 if you have the header file. */