immutable: Add tests.
[gnulib.git] / m4 / expl.m4
blob0ed62ab4e0ebcb4ae6a66e5f0d1c2deee4be5856
1 # expl.m4 serial 17
2 dnl Copyright (C) 2010-2021 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
7 AC_DEFUN([gl_FUNC_EXPL],
9   AC_REQUIRE([gl_MATH_H_DEFAULTS])
10   AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
11   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
13   dnl Persuade glibc <math.h> to declare expl().
14   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
16   EXPL_LIBM=
17   AC_CACHE_CHECK([whether expl() can be used without linking with libm],
18     [gl_cv_func_expl_no_libm],
19     [
20       AC_LINK_IFELSE(
21         [AC_LANG_PROGRAM(
22            [[#ifndef __NO_MATH_INLINES
23              # define __NO_MATH_INLINES 1 /* for glibc */
24              #endif
25              #include <math.h>
26              long double (* volatile funcptr) (long double) = expl;
27              long double x;]],
28            [[return funcptr (x) > 1.5
29                     || expl (x) > 1.5;]])],
30         [gl_cv_func_expl_no_libm=yes],
31         [gl_cv_func_expl_no_libm=no])
32     ])
33   if test $gl_cv_func_expl_no_libm = no; then
34     AC_CACHE_CHECK([whether expl() can be used with libm],
35       [gl_cv_func_expl_in_libm],
36       [
37         save_LIBS="$LIBS"
38         LIBS="$LIBS -lm"
39         AC_LINK_IFELSE(
40           [AC_LANG_PROGRAM(
41              [[#ifndef __NO_MATH_INLINES
42                # define __NO_MATH_INLINES 1 /* for glibc */
43                #endif
44                #include <math.h>
45                long double (* volatile funcptr) (long double) = expl;
46                long double x;]],
47              [[return funcptr (x) > 1.5
48                       || expl (x) > 1.5;]])],
49           [gl_cv_func_expl_in_libm=yes],
50           [gl_cv_func_expl_in_libm=no])
51         LIBS="$save_LIBS"
52       ])
53     if test $gl_cv_func_expl_in_libm = yes; then
54       EXPL_LIBM=-lm
55     fi
56   fi
57   if test $gl_cv_func_expl_no_libm = yes \
58      || test $gl_cv_func_expl_in_libm = yes; then
59     dnl Also check whether it's declared.
60     dnl Mac OS X 10.3 has expl() in libc but doesn't declare it in <math.h>.
61     AC_CHECK_DECL([expl], , [HAVE_DECL_EXPL=0], [[#include <math.h>]])
62     if test $REPLACE_EXPL = 0; then
63       AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
64       AC_CACHE_CHECK([whether expl works],
65         [gl_cv_func_expl_works],
66         [
67           save_LIBS="$LIBS"
68           LIBS="$LIBS $EXPL_LIBM"
69           AC_RUN_IFELSE(
70             [AC_LANG_SOURCE([[
71 #ifndef __NO_MATH_INLINES
72 # define __NO_MATH_INLINES 1 /* for glibc */
73 #endif
74 #include <float.h>
75 #include <math.h>
76 /* Override the values of <float.h>, like done in float.in.h.  */
77 #if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__)
78 # undef LDBL_MANT_DIG
79 # define LDBL_MANT_DIG   64
80 # undef LDBL_MIN_EXP
81 # define LDBL_MIN_EXP    (-16381)
82 # undef LDBL_MAX_EXP
83 # define LDBL_MAX_EXP    16384
84 #endif
85 #if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__)
86 # undef LDBL_MANT_DIG
87 # define LDBL_MANT_DIG   64
88 # undef LDBL_MIN_EXP
89 # define LDBL_MIN_EXP    (-16381)
90 # undef LDBL_MAX_EXP
91 # define LDBL_MAX_EXP    16384
92 #endif
93 #if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__
94 # undef LDBL_MIN_EXP
95 # define LDBL_MIN_EXP DBL_MIN_EXP
96 #endif
97 #if defined __sgi && (LDBL_MANT_DIG >= 106)
98 # undef LDBL_MANT_DIG
99 # define LDBL_MANT_DIG 106
100 # if defined __GNUC__
101 #  undef LDBL_MIN_EXP
102 #  define LDBL_MIN_EXP DBL_MIN_EXP
103 # endif
104 #endif
105 #undef expl
106 extern
107 #ifdef __cplusplus
109 #endif
110 long double expl (long double);
111 static long double dummy (long double x) { return 0; }
112 int main (int argc, char *argv[])
114   long double (* volatile my_expl) (long double) = argc ? expl : dummy;
115   int result = 0;
116   /* On Haiku 2017 the system's native expl() is just a stub: it returns 0.0
117      and prints "__expl not implemented" for all arguments.  */
118   {
119     volatile long double x1 = -1.0;
120     if (expl (x1) == 0.0)
121       result |= 1;
122   }
123   /* On OpenBSD 5.4 the system's native expl() is buggy:
124      it returns 'nan' for small values.  */
125   {
126     volatile long double x1 = -1.0;
127     volatile long double x2 = -0.8;
128     volatile long double x3 = -0.4;
129     if (isnan (expl (x1)) || isnan (expl (x2)) || isnan (expl (x3)))
130       result |= 2;
131   }
132   /* This test fails on NetBSD 9.0.  */
133   {
134     const long double TWO_LDBL_MANT_DIG = /* 2^LDBL_MANT_DIG */
135       (long double) (1U << ((LDBL_MANT_DIG - 1) / 5))
136       * (long double) (1U << ((LDBL_MANT_DIG - 1 + 1) / 5))
137       * (long double) (1U << ((LDBL_MANT_DIG - 1 + 2) / 5))
138       * (long double) (1U << ((LDBL_MANT_DIG - 1 + 3) / 5))
139       * (long double) (1U << ((LDBL_MANT_DIG - 1 + 4) / 5));
140     long double x = 11.358L;
141     long double err = (my_expl (x) * my_expl (- x) - 1.0L) * TWO_LDBL_MANT_DIG;
142     if (!(err >= -100.0L && err <= 100.0L))
143       result |= 4;
144   }
145   return result;
147             ]])],
148             [gl_cv_func_expl_works=yes],
149             [gl_cv_func_expl_works=no],
150             [case "$host_os" in
151                               # Guess yes on glibc systems.
152                *-gnu* | gnu*) gl_cv_func_expl_works="guessing yes" ;;
153                               # Guess yes on musl systems.
154                *-musl*)       gl_cv_func_expl_works="guessing yes" ;;
155                               # Guess yes on native Windows.
156                mingw*)        gl_cv_func_expl_works="guessing yes" ;;
157                               # If we don't know, obey --enable-cross-guesses.
158                *)             gl_cv_func_expl_works="$gl_cross_guess_normal" ;;
159              esac
160             ])
161           LIBS="$save_LIBS"
162         ])
163       case "$gl_cv_func_expl_works" in
164         *yes) ;;
165         *) REPLACE_EXPL=1 ;;
166       esac
167     fi
168   else
169     HAVE_DECL_EXPL=0
170     HAVE_EXPL=0
171   fi
172   if test $HAVE_EXPL = 0 || test $REPLACE_EXPL = 1; then
173     dnl Find libraries needed to link lib/expl.c.
174     if test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 1; then
175       AC_REQUIRE([gl_FUNC_EXP])
176       EXPL_LIBM="$EXP_LIBM"
177     else
178       AC_REQUIRE([gl_FUNC_ISNANL])
179       AC_REQUIRE([gl_FUNC_ROUNDL])
180       AC_REQUIRE([gl_FUNC_LDEXPL])
181       EXPL_LIBM=
182       dnl Append $ISNANL_LIBM to EXPL_LIBM, avoiding gratuitous duplicates.
183       case " $EXPL_LIBM " in
184         *" $ISNANL_LIBM "*) ;;
185         *) EXPL_LIBM="$EXPL_LIBM $ISNANL_LIBM" ;;
186       esac
187       dnl Append $ROUNDL_LIBM to EXPL_LIBM, avoiding gratuitous duplicates.
188       case " $EXPL_LIBM " in
189         *" $ROUNDL_LIBM "*) ;;
190         *) EXPL_LIBM="$EXPL_LIBM $ROUNDL_LIBM" ;;
191       esac
192       dnl Append $LDEXPL_LIBM to EXPL_LIBM, avoiding gratuitous duplicates.
193       case " $EXPL_LIBM " in
194         *" $LDEXPL_LIBM "*) ;;
195         *) EXPL_LIBM="$EXPL_LIBM $LDEXPL_LIBM" ;;
196       esac
197     fi
198   fi
199   AC_SUBST([EXPL_LIBM])