xref: /netbsd-src/external/lgpl3/mpfr/dist/acinclude.m4 (revision ec6772edaf0cdcb5f52a48f4aca5e33a8fb8ecfd)
1dnl  MPFR specific autoconf macros
2
3dnl  Copyright 2000, 2002-2023 Free Software Foundation, Inc.
4dnl  Contributed by the AriC and Caramba projects, INRIA.
5dnl
6dnl  This file is part of the GNU MPFR Library.
7dnl
8dnl  The GNU MPFR Library is free software; you can redistribute it and/or modify
9dnl  it under the terms of the GNU Lesser General Public License as published
10dnl  by the Free Software Foundation; either version 3 of the License, or (at
11dnl  your option) any later version.
12dnl
13dnl  The GNU MPFR Library is distributed in the hope that it will be useful, but
14dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16dnl  License for more details.
17dnl
18dnl  You should have received a copy of the GNU Lesser General Public License
19dnl  along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20dnl  https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21dnl  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
22
23dnl  autoconf 2.60 is necessary because of the use of AC_PROG_SED.
24dnl  The following line allows the autoconf wrapper (when installed)
25dnl  to work as expected.
26dnl  If you change the required version, please update README.dev too!
27AC_PREREQ(2.60)
28
29dnl ------------------------------------------------------------
30dnl You must put in MPFR_CONFIGS everything that configures MPFR except:
31dnl   - Everything dealing with CC and CFLAGS in particular the ABI
32dnl     but the IEEE-754 specific flags must be set here.
33dnl   - Tests that depend on gmp.h (see MPFR_CHECK_DBL2INT_BUG as an example:
34dnl     a function needs to be defined and called in configure.ac).
35dnl   - GMP's linkage.
36dnl   - Libtool stuff.
37dnl   - Handling of special arguments of MPFR's configure.
38AC_DEFUN([MPFR_CONFIGS],
39[
40AC_REQUIRE([AC_OBJEXT])
41AC_REQUIRE([MPFR_CHECK_LIBM])
42AC_REQUIRE([MPFR_CHECK_LIBQUADMATH])
43AC_REQUIRE([AC_CANONICAL_HOST])
44
45dnl Features for the MPFR shared cache. This needs to be done
46dnl quite early since this may change CC, CFLAGS and LIBS, which
47dnl may affect the other tests.
48
49if test "$enable_shared_cache" = yes; then
50
51dnl Prefer ISO C11 threads (as in mpfr-thread.h).
52  MPFR_CHECK_C11_THREAD()
53
54  if test "$mpfr_c11_thread_ok" != yes; then
55dnl Check for POSIX threads. Since the AX_PTHREAD macro is not standard
56dnl (it is provided by autoconf-archive), we need to detect whether it
57dnl is left unexpanded, otherwise the configure script won't fail and
58dnl "make distcheck" won't give any error, yielding buggy tarballs!
59dnl The \b is necessary to avoid an error with recent ax_pthread.m4
60dnl (such as with Debian's autoconf-archive 20160320-1), which contains
61dnl AX_PTHREAD_ZOS_MISSING, etc. It is not documented, but see:
62dnl   https://lists.gnu.org/archive/html/autoconf/2015-03/msg00011.html
63dnl
64dnl AX_PTHREAD is now in the MPFR repository (m4/ax_pthread.m4), but we
65dnl should leave this test, just in case there is some issue loading it
66dnl (or any other reason).
67dnl
68dnl Note: each time a change is done in m4_pattern_forbid, autogen.sh
69dnl should be tested with and without ax_pthread.m4 availability (in
70dnl the latter case, there should be an error).
71    m4_pattern_forbid([AX_PTHREAD\b])
72    AX_PTHREAD([])
73    if test "$ax_pthread_ok" = yes; then
74      CC="$PTHREAD_CC"
75      CXX="$PTHREAD_CXX"
76      CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
77      CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
78      LIBS="$LIBS $PTHREAD_LIBS"
79dnl Do a compilation test, as this is currently not done by AX_PTHREAD.
80dnl Moreover, MPFR needs pthread_rwlock_t, which is conditionally defined
81dnl in glibc's bits/pthreadtypes.h (via <pthread.h>), not sure why...
82      AC_MSG_CHECKING([for pthread_rwlock_t])
83      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
84#include <pthread.h>
85]], [[
86pthread_rwlock_t lock; (void) lock;
87]])],
88        [AC_MSG_RESULT([yes])
89         mpfr_pthread_ok=yes],
90        [AC_MSG_RESULT([no])
91         mpfr_pthread_ok=no])
92    else
93      mpfr_pthread_ok=no
94    fi
95  fi
96
97  AC_MSG_CHECKING(if shared cache can be supported)
98  if test "$mpfr_c11_thread_ok" = yes; then
99    AC_MSG_RESULT([yes, with ISO C11 threads])
100  elif test "$mpfr_pthread_ok" = yes; then
101    AC_MSG_RESULT([yes, with pthread])
102  else
103    AC_MSG_RESULT(no)
104    AC_MSG_ERROR([shared cache needs C11 threads or pthread support])
105  fi
106
107fi
108
109dnl End of features for the MPFR shared cache.
110
111AC_CHECK_HEADER([limits.h],, AC_MSG_ERROR([limits.h not found]))
112AC_CHECK_HEADER([float.h],,  AC_MSG_ERROR([float.h not found]))
113AC_CHECK_HEADER([string.h],, AC_MSG_ERROR([string.h not found]))
114
115dnl Check for locales
116AC_CHECK_HEADERS([locale.h])
117
118dnl Check for wide characters (wchar_t and wint_t)
119AC_CHECK_HEADERS([wchar.h])
120
121dnl Check for stdargs
122AC_CHECK_HEADER([stdarg.h],[AC_DEFINE([HAVE_STDARG],1,[Define if stdarg])],
123  [AC_CHECK_HEADER([varargs.h],,
124    AC_MSG_ERROR([stdarg.h or varargs.h not found]))])
125
126dnl sys/fpu.h - MIPS specific
127AC_CHECK_HEADERS([sys/fpu.h])
128
129dnl Android has a <locale.h>, but not the following members.
130AC_CHECK_MEMBERS([struct lconv.decimal_point, struct lconv.thousands_sep],,,
131  [#include <locale.h>])
132
133dnl Check how to get `alloca'
134AC_FUNC_ALLOCA
135
136dnl Define uintptr_t if not available.
137AC_TYPE_UINTPTR_T
138
139dnl va_copy macro
140AC_MSG_CHECKING([how to copy va_list])
141AC_LINK_IFELSE([AC_LANG_PROGRAM([[
142#include <stdarg.h>
143]], [[
144   va_list ap1, ap2;
145   va_copy(ap1, ap2);
146]])], [
147   AC_MSG_RESULT([va_copy])
148   AC_DEFINE(HAVE_VA_COPY)
149], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
150#include <stdarg.h>
151]], [[
152   va_list ap1, ap2;
153   __va_copy(ap1, ap2);
154]])], [AC_DEFINE([HAVE___VA_COPY]) AC_MSG_RESULT([__va_copy])],
155   [AC_MSG_RESULT([memcpy])])])
156
157dnl Options like -Werror can yield a failure as AC_CHECK_FUNCS uses some
158dnl fixed prototype for function detection, generally incompatible with
159dnl the standard one. For instance, with GCC, if the function is defined
160dnl as a builtin, one can get a "conflicting types for built-in function"
161dnl error [-Werror=builtin-declaration-mismatch], even though the header
162dnl is not included; when these functions were tested, this occurred with
163dnl memmove and memset. Even though no failures are known with the tested
164dnl functions at this time, let's remove options starting with "-Werror"
165dnl since failures may still be possible.
166dnl
167dnl The gettimeofday function is not defined with MinGW.
168saved_CFLAGS="$CFLAGS"
169CFLAGS=`[echo " $CFLAGS" | $SED 's/ -Werror[^ ]*//g']`
170AC_CHECK_FUNCS([setlocale gettimeofday signal])
171CFLAGS="$saved_CFLAGS"
172
173dnl We cannot use AC_CHECK_FUNCS on sigaction, because while this
174dnl function may be provided by the C library, its prototype and
175dnl associated structure may not be available, e.g. when compiling
176dnl with "gcc -std=c99".
177AC_MSG_CHECKING(for sigaction and its associated structure)
178AC_LINK_IFELSE([AC_LANG_PROGRAM([[
179#include <signal.h>
180static int f (int (*func)(int, const struct sigaction *, struct sigaction *))
181{ return 0; }
182]], [[
183 return f(sigaction);
184]])], [
185   AC_MSG_RESULT(yes)
186   AC_DEFINE(HAVE_SIGACTION, 1,
187    [Define if you have a working sigaction function.])
188],[AC_MSG_RESULT(no)])
189
190dnl check for long long
191AC_CHECK_TYPE([long long int],
192   AC_DEFINE(HAVE_LONG_LONG, 1, [Define if compiler supports long long]),,)
193
194dnl intmax_t is C99
195AC_CHECK_TYPES([intmax_t])
196if test "$ac_cv_type_intmax_t" = yes; then
197  AC_CACHE_CHECK([for working INTMAX_MAX], mpfr_cv_have_intmax_max, [
198    saved_CPPFLAGS="$CPPFLAGS"
199    CPPFLAGS="$CPPFLAGS -I$srcdir/src -DMPFR_NEED_INTMAX_H"
200    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
201        [[#include "mpfr-intmax.h"]],
202        [[intmax_t x = INTMAX_MAX; (void) x;]]
203      )],
204      mpfr_cv_have_intmax_max=yes, mpfr_cv_have_intmax_max=no)
205    CPPFLAGS="$saved_CPPFLAGS"
206  ])
207  if test "$mpfr_cv_have_intmax_max" = "yes"; then
208    AC_DEFINE(MPFR_HAVE_INTMAX_MAX,1,[Define if you have a working INTMAX_MAX.])
209  fi
210fi
211
212AC_CHECK_TYPE( [union fpc_csr],
213   AC_DEFINE(HAVE_FPC_CSR,1,[Define if union fpc_csr is available]), ,
214[
215#if HAVE_SYS_FPU_H
216#  include <sys/fpu.h>
217#endif
218])
219
220dnl Check for _Noreturn function specifier (ISO C11)
221AC_CACHE_CHECK([for _Noreturn], mpfr_cv_have_noreturn, [
222  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[_Noreturn void foo(int);]])],
223    mpfr_cv_have_noreturn=yes, mpfr_cv_have_noreturn=no)
224])
225if test "$mpfr_cv_have_noreturn" = "yes"; then
226  AC_DEFINE(MPFR_HAVE_NORETURN,1,[Define if the _Noreturn function specifier is supported.])
227fi
228
229dnl Check for __builtin_unreachable
230AC_CACHE_CHECK([for __builtin_unreachable], mpfr_cv_have_builtin_unreachable,
231[
232  AC_LINK_IFELSE([AC_LANG_PROGRAM(
233      [[int x;]],
234      [[if (x) __builtin_unreachable(); ]]
235    )],
236    mpfr_cv_have_builtin_unreachable=yes,
237    mpfr_cv_have_builtin_unreachable=no)
238])
239if test "$mpfr_cv_have_builtin_unreachable" = "yes"; then
240  AC_DEFINE(MPFR_HAVE_BUILTIN_UNREACHABLE, 1,
241   [Define if the __builtin_unreachable GCC built-in is supported.])
242fi
243
244dnl Check for attribute constructor and destructor
245MPFR_CHECK_CONSTRUCTOR_ATTR()
246
247dnl Check for fesetround
248AC_CACHE_CHECK([for fesetround], mpfr_cv_have_fesetround, [
249saved_LIBS="$LIBS"
250LIBS="$LIBS $MPFR_LIBM"
251AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <fenv.h>]], [[fesetround(FE_TONEAREST);]])],
252  mpfr_cv_have_fesetround=yes, mpfr_cv_have_fesetround=no)
253LIBS="$saved_LIBS"
254])
255if test "$mpfr_cv_have_fesetround" = "yes"; then
256  AC_DEFINE(MPFR_HAVE_FESETROUND,1,[Define if you have the `fesetround' function via the <fenv.h> header file.])
257fi
258
259dnl Check for gcc float-conversion bug; if need be, -ffloat-store is used to
260dnl force the conversion to the destination type when a value is stored to
261dnl a variable (see ISO C99 standard 5.1.2.3#13, 6.3.1.5#2, 6.3.1.8#2). This
262dnl is important concerning the exponent range. Note that this doesn't solve
263dnl the double-rounding problem.
264if test -n "$GCC"; then
265  AC_CACHE_CHECK([for gcc float-conversion bug], mpfr_cv_gcc_floatconv_bug, [
266  saved_LIBS="$LIBS"
267  LIBS="$LIBS $MPFR_LIBM"
268  AC_RUN_IFELSE([AC_LANG_SOURCE([[
269#include <float.h>
270#ifdef MPFR_HAVE_FESETROUND
271#include <fenv.h>
272#endif
273static double get_max (void);
274int main (void) {
275  double x = 0.5;
276  double y;
277  int i;
278  for (i = 1; i <= 11; i++)
279    x *= x;
280  if (x != 0)
281    return 1;
282#ifdef MPFR_HAVE_FESETROUND
283  /* Useful test for the G4 PowerPC */
284  fesetround(FE_TOWARDZERO);
285  x = y = get_max ();
286  x *= 2.0;
287  if (x != y)
288    return 1;
289#endif
290  return 0;
291}
292static double get_max (void) { static volatile double d = DBL_MAX; return d; }
293  ]])],
294     [mpfr_cv_gcc_floatconv_bug="no"],
295     [mpfr_cv_gcc_floatconv_bug="yes, use -ffloat-store"],
296     [mpfr_cv_gcc_floatconv_bug="cannot test, use -ffloat-store"])
297  LIBS="$saved_LIBS"
298  ])
299  if test "$mpfr_cv_gcc_floatconv_bug" != "no"; then
300    CFLAGS="$CFLAGS -ffloat-store"
301  fi
302fi
303
304dnl Check if subnormal numbers are supported.
305dnl For the binary64 format, the smallest normal number is 2^(-1022).
306dnl For the binary32 format, the smallest normal number is 2^(-126).
307dnl Do not use the corresponding HAVE_SUBNORM_* macros as they
308dnl are not available when cross-compiling. For the tests, use
309dnl the have_subnorm_* functions if need be.
310dnl Note: "volatile" is needed to avoid -ffast-math optimizations
311dnl (default in icx 2021.2.0, which also sets the FZ and DAZ bits
312dnl of the x86-64 MXCSR register to disregard subnormals).
313AC_CACHE_CHECK([for subnormal double-precision numbers],
314mpfr_cv_have_subnorm_dbl, [
315AC_RUN_IFELSE([AC_LANG_SOURCE([[
316#include <stdio.h>
317int main (void) {
318  volatile double x = 2.22507385850720138309e-308, y;
319  y = x / 2.0;
320  fprintf (stderr, "%e\n", y);
321  return 2.0 * y != x;
322}
323]])],
324   [mpfr_cv_have_subnorm_dbl="yes"],
325   [mpfr_cv_have_subnorm_dbl="no"],
326   [mpfr_cv_have_subnorm_dbl="cannot test, assume no"])
327])
328if test "$mpfr_cv_have_subnorm_dbl" = "yes"; then
329  AC_DEFINE(HAVE_SUBNORM_DBL, 1,
330   [Define if the double type fully supports subnormals.])
331fi
332AC_CACHE_CHECK([for subnormal single-precision numbers],
333mpfr_cv_have_subnorm_flt, [
334AC_RUN_IFELSE([AC_LANG_SOURCE([[
335#include <stdio.h>
336int main (void) {
337  volatile float x = 1.17549435082229e-38, y;
338  y = x / 2.0f;
339  fprintf (stderr, "%e\n", (double) y);
340  return 2.0f * y != x;
341}
342]])],
343   [mpfr_cv_have_subnorm_flt="yes"],
344   [mpfr_cv_have_subnorm_flt="no"],
345   [mpfr_cv_have_subnorm_flt="cannot test, assume no"])
346])
347if test "$mpfr_cv_have_subnorm_flt" = "yes"; then
348  AC_DEFINE(HAVE_SUBNORM_FLT, 1,
349   [Define if the float type fully supports subnormals.])
350fi
351
352dnl Check if signed zeros are supported. Note: the test will fail
353dnl if the division by 0 generates a trap.
354AC_CACHE_CHECK([for signed zeros], mpfr_cv_have_signedz, [
355AC_RUN_IFELSE([AC_LANG_SOURCE([[
356int main (void) {
357  return 1.0 / 0.0 == 1.0 / -0.0;
358}
359]])],
360   [mpfr_cv_have_signedz="yes"],
361   [mpfr_cv_have_signedz="no"],
362   [mpfr_cv_have_signedz="cannot test, assume no"])
363])
364if test "$mpfr_cv_have_signedz" = "yes"; then
365  AC_DEFINE(HAVE_SIGNEDZ,1,[Define if signed zeros are supported.])
366fi
367
368dnl Check the FP division by 0 fails (e.g. on a non-IEEE-754 platform).
369dnl In such a case, MPFR_ERRDIVZERO is defined to disable the tests
370dnl involving a FP division by 0.
371dnl For the developers: to check whether all these tests are disabled,
372dnl configure MPFR with "-DMPFR_TESTS_FPE_DIV -DMPFR_ERRDIVZERO".
373AC_CACHE_CHECK([if the FP division by 0 fails], mpfr_cv_errdivzero, [
374AC_RUN_IFELSE([AC_LANG_SOURCE([[
375int main (void) {
376  volatile double d = 0.0, x;
377  x = 0.0 / d;
378  x = 1.0 / d;
379  (void) x;
380  return 0;
381}
382]])],
383   [mpfr_cv_errdivzero="no"],
384   [mpfr_cv_errdivzero="yes"],
385   [mpfr_cv_errdivzero="cannot test, assume no"])
386])
387if test "$mpfr_cv_errdivzero" = "yes"; then
388  AC_DEFINE(MPFR_ERRDIVZERO,1,[Define if the FP division by 0 fails.])
389  AC_MSG_WARN([The floating-point division by 0 fails instead of])
390  AC_MSG_WARN([returning a special value: NaN or infinity. Tests])
391  AC_MSG_WARN([involving a FP division by 0 will be disabled.])
392fi
393
394dnl Check whether NAN != NAN (as required by the IEEE-754 standard,
395dnl but not by the ISO C standard). For instance, this is false with
396dnl MIPSpro 7.3.1.3m under IRIX64. By default, assume this is true.
397dnl Note that this test may not detect all issues. For instance, with
398dnl icx 2021.2.0 (and default fast-math), the result depends on whether
399dnl the identifier has internal or external linkage:
400dnl   https://community.intel.com/t5/Intel-oneAPI-Base-Toolkit/icx-2021-2-0-bug-incorrect-NaN-comparison-using-an-identifier/m-p/1286869
401dnl TODO: change "NAN == NAN" to "NaN is supported" and rename
402dnl the MPFR_NANISNAN macro?
403AC_CACHE_CHECK([if NAN == NAN], mpfr_cv_nanisnan, [
404AC_RUN_IFELSE([AC_LANG_SOURCE([[
405#include <stdio.h>
406#include <math.h>
407#ifndef NAN
408# define NAN (0.0/0.0)
409#endif
410int main (void) {
411  double d;
412  d = NAN;
413  return d != d;
414}
415]])],
416   [mpfr_cv_nanisnan="yes"],
417   [mpfr_cv_nanisnan="no"],
418   [mpfr_cv_nanisnan="cannot test, assume no"])
419])
420if test "$mpfr_cv_nanisnan" = "yes"; then
421  AC_DEFINE(MPFR_NANISNAN,1,[Define if NAN == NAN.])
422  AC_MSG_WARN([The test NAN != NAN is false. The probable reason is that])
423  AC_MSG_WARN([your compiler optimizes floating-point expressions in an])
424  AC_MSG_WARN([unsafe way because some option, such as -ffast-math or])
425  AC_MSG_WARN([-fast (depending on the compiler), has been used.  You])
426  AC_MSG_WARN([should NOT use such an option, otherwise MPFR functions])
427  AC_MSG_WARN([such as mpfr_get_d and mpfr_set_d may return incorrect])
428  AC_MSG_WARN([results on special FP numbers (e.g. NaN or signed zeros).])
429  AC_MSG_WARN([If you did not use such an option, please send us a bug])
430  AC_MSG_WARN([report so that we can try to find a workaround for your])
431  AC_MSG_WARN([platform and/or document the behavior.])
432fi
433
434dnl Check if the chars '0' to '9', 'a' to 'z', and 'A' to 'Z' are
435dnl consecutive values.
436dnl The const is necessary with GCC's "-Wwrite-strings -Werror".
437AC_MSG_CHECKING([if charset has consecutive values])
438AC_RUN_IFELSE([AC_LANG_PROGRAM([[
439const char *number = "0123456789";
440const char *lower  = "abcdefghijklmnopqrstuvwxyz";
441const char *upper  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
442]],[[
443 int i;
444 unsigned char *p;
445 for (p = (unsigned char*) number, i = 0; i < 9; i++)
446   if ( (*p)+1 != *(p+1) ) return 1;
447 for (p = (unsigned char*) lower, i = 0; i < 25; i++)
448   if ( (*p)+1 != *(p+1) ) return 1;
449 for (p = (unsigned char*) upper, i = 0; i < 25; i++)
450   if ( (*p)+1 != *(p+1) ) return 1;
451]])], [AC_MSG_RESULT(yes)],[
452 AC_MSG_RESULT(no)
453 AC_DEFINE(MPFR_NO_CONSECUTIVE_CHARSET,1,[Charset is not consecutive])
454], [AC_MSG_RESULT(cannot test)])
455
456dnl Must be checked with the LIBM
457dnl but we don't want to add the LIBM to MPFR dependency.
458dnl Can't use AC_CHECK_FUNCS since the function may be in LIBM but
459dnl not exported in math.h
460saved_LIBS="$LIBS"
461LIBS="$LIBS $MPFR_LIBM"
462dnl AC_CHECK_FUNCS([round trunc floor ceil nearbyint])
463AC_MSG_CHECKING(for math/round)
464AC_LINK_IFELSE([AC_LANG_PROGRAM([[
465#include <math.h>
466static int f (double (*func)(double)) { return 0; }
467]], [[
468 return f(round);
469]])], [
470   AC_MSG_RESULT(yes)
471   AC_DEFINE(HAVE_ROUND, 1,[Have ISO C99 round function])
472],[AC_MSG_RESULT(no)])
473
474AC_MSG_CHECKING(for math/trunc)
475AC_LINK_IFELSE([AC_LANG_PROGRAM([[
476#include <math.h>
477static int f (double (*func)(double)) { return 0; }
478]], [[
479 return f(trunc);
480]])], [
481   AC_MSG_RESULT(yes)
482   AC_DEFINE(HAVE_TRUNC, 1,[Have ISO C99 trunc function])
483],[AC_MSG_RESULT(no)])
484
485AC_MSG_CHECKING(for math/floor)
486AC_LINK_IFELSE([AC_LANG_PROGRAM([[
487#include <math.h>
488static int f (double (*func)(double)) { return 0; }
489]], [[
490 return f(floor);
491]])], [
492   AC_MSG_RESULT(yes)
493   AC_DEFINE(HAVE_FLOOR, 1,[Have ISO C99 floor function])
494],[AC_MSG_RESULT(no)])
495
496AC_MSG_CHECKING(for math/ceil)
497AC_LINK_IFELSE([AC_LANG_PROGRAM([[
498#include <math.h>
499static int f (double (*func)(double)) { return 0; }
500]], [[
501 return f(ceil);
502]])], [
503   AC_MSG_RESULT(yes)
504   AC_DEFINE(HAVE_CEIL, 1,[Have ISO C99 ceil function])
505],[AC_MSG_RESULT(no)])
506
507AC_MSG_CHECKING(for math/nearbyint)
508AC_LINK_IFELSE([AC_LANG_PROGRAM([[
509#include <math.h>
510static int f (double (*func)(double)) { return 0; }
511]], [[
512 return f(nearbyint);
513]])], [
514   AC_MSG_RESULT(yes)
515   AC_DEFINE(HAVE_NEARBYINT, 1,[Have ISO C99 nearbyint function])
516],[AC_MSG_RESULT(no)])
517
518LIBS="$saved_LIBS"
519
520dnl Try to determine the format of double
521MPFR_C_REALFP_FORMAT(double,)
522case $mpfr_cv_c_double_format in
523  "IEEE double, big endian"*)
524    AC_DEFINE(HAVE_DOUBLE_IEEE_BIG_ENDIAN, 1)
525    ;;
526  "IEEE double, little endian"*)
527    AC_DEFINE(HAVE_DOUBLE_IEEE_LITTLE_ENDIAN, 1)
528    ;;
529  unknown*)
530    ;;
531  *)
532    AC_MSG_WARN([format of `double' unsupported or not recognized: $mpfr_cv_c_double_format])
533    ;;
534esac
535
536dnl Now try to determine the format of long double
537MPFR_C_REALFP_FORMAT(long double,L)
538case $mpfr_cv_c_long_double_format in
539  "IEEE double, big endian"*)
540    AC_DEFINE(HAVE_LDOUBLE_IS_DOUBLE, 1)
541    ;;
542  "IEEE double, little endian"*)
543    AC_DEFINE(HAVE_LDOUBLE_IS_DOUBLE, 1)
544    ;;
545  "IEEE extended, little endian"*)
546    AC_DEFINE(HAVE_LDOUBLE_IEEE_EXT_LITTLE, 1)
547    ;;
548  "IEEE extended, big endian"*)
549    AC_DEFINE(HAVE_LDOUBLE_IEEE_EXT_BIG, 1)
550    ;;
551  "IEEE quad, big endian"*)
552    AC_DEFINE(HAVE_LDOUBLE_IEEE_QUAD_BIG, 1)
553    ;;
554  "IEEE quad, little endian"*)
555    AC_DEFINE(HAVE_LDOUBLE_IEEE_QUAD_LITTLE, 1)
556    ;;
557  "possibly double-double, big endian"*)
558    AC_MSG_WARN([This format is known on GCC/PowerPC platforms,])
559    AC_MSG_WARN([but due to GCC PR26374, we can't test further.])
560    AC_MSG_WARN([You can safely ignore this warning, though.])
561    AC_DEFINE(HAVE_LDOUBLE_MAYBE_DOUBLE_DOUBLE, 1)
562    ;;
563  "possibly double-double, little endian"*)
564    AC_MSG_WARN([This format is known on GCC/PowerPC platforms,])
565    AC_MSG_WARN([but due to GCC PR26374, we can't test further.])
566    AC_MSG_WARN([You can safely ignore this warning, though.])
567    AC_DEFINE(HAVE_LDOUBLE_MAYBE_DOUBLE_DOUBLE, 1)
568    ;;
569  unknown*)
570    ;;
571  *)
572    AC_MSG_WARN([format of `long double' unsupported or not recognized: $mpfr_cv_c_long_double_format])
573    ;;
574esac
575
576dnl Check if thread-local variables are supported.
577dnl At least two problems can occur in practice:
578dnl 1. The compilation fails, e.g. because the compiler doesn't know
579dnl    about the __thread keyword.
580dnl 2. The compilation succeeds, but the system doesn't support TLS or
581dnl    there is some ld configuration problem. One of the effects can
582dnl    be that thread-local variables always evaluate to 0. So, it is
583dnl    important to run the test below.
584if test "$enable_thread_safe" != no; then
585AC_MSG_CHECKING(for TLS support using C11)
586saved_CPPFLAGS="$CPPFLAGS"
587CPPFLAGS="$CPPFLAGS -I$srcdir/src"
588AC_RUN_IFELSE([AC_LANG_SOURCE([[
589#define MPFR_USE_THREAD_SAFE 1
590#define MPFR_USE_C11_THREAD_SAFE 1
591#include "mpfr-thread.h"
592MPFR_THREAD_ATTR int x = 17;
593int main (void) {
594  return x != 17;
595}
596  ]])],
597     [AC_MSG_RESULT(yes)
598      AC_DEFINE([MPFR_USE_THREAD_SAFE],1,[Build MPFR as thread safe])
599      AC_DEFINE([MPFR_USE_C11_THREAD_SAFE],1,[Build MPFR as thread safe using C11])
600      tls_c11_support=yes
601      enable_thread_safe=yes
602     ],
603     [AC_MSG_RESULT(no)
604     ],
605     [AC_MSG_RESULT([cannot test, assume no])
606     ])
607CPPFLAGS="$saved_CPPFLAGS"
608
609if test "$tls_c11_support" != "yes"
610then
611
612 AC_MSG_CHECKING(for TLS support)
613 saved_CPPFLAGS="$CPPFLAGS"
614 CPPFLAGS="$CPPFLAGS -I$srcdir/src"
615 AC_RUN_IFELSE([AC_LANG_SOURCE([[
616 #define MPFR_USE_THREAD_SAFE 1
617 #include "mpfr-thread.h"
618 MPFR_THREAD_ATTR int x = 17;
619 int main (void) {
620   return x != 17;
621 }
622   ]])],
623      [AC_MSG_RESULT(yes)
624       AC_DEFINE([MPFR_USE_THREAD_SAFE],1,[Build MPFR as thread safe])
625       enable_thread_safe=yes
626      ],
627      [AC_MSG_RESULT(no)
628       if test "$enable_thread_safe" = yes; then
629         AC_MSG_ERROR([please configure with --disable-thread-safe])
630       fi
631      ],
632      [if test "$enable_thread_safe" = yes; then
633         AC_MSG_RESULT([cannot test, assume yes])
634         AC_DEFINE([MPFR_USE_THREAD_SAFE],1,[Build MPFR as thread safe])
635       else
636         AC_MSG_RESULT([cannot test, assume no])
637       fi
638      ])
639 CPPFLAGS="$saved_CPPFLAGS"
640 fi
641fi
642
643if test "$enable_decimal_float" != no; then
644
645dnl Check if decimal floats are available.
646dnl For the different cases, we try to use values that will not be returned
647dnl by build tools. For instance, 1 must not be used as it can be returned
648dnl by gcc or by ld in case of link failure.
649dnl Note: We currently reread the 64-bit data memory as a double and compare
650dnl it with constants. However, if there is any issue with double, such as
651dnl the use of an extended precision, this may fail. Possible solutions:
652dnl   1. Use the hex format for the double constants (this format should be
653dnl      supported if _Decimal64 is).
654dnl   2. Use more precision in the double constants (more decimal digits),
655dnl      just in case.
656dnl   3. Use uint64_t (or unsigned long long, though this type might not be
657dnl      on 64 bits) instead of or in addition to the test on double.
658dnl   4. Use an array of 8 unsigned char's instead of or in addition to the
659dnl      test on double, considering the 2 practical cases of endianness.
660  AC_MSG_CHECKING(if compiler knows _Decimal64)
661  AC_COMPILE_IFELSE(
662    [AC_LANG_PROGRAM([[_Decimal64 x;]])],
663    [AC_MSG_RESULT(yes)
664     AC_MSG_CHECKING(decimal float format)
665     AC_RUN_IFELSE([AC_LANG_PROGRAM([[
666#include <stdlib.h>
667]], [[
668volatile _Decimal64 x = 1;
669union { double d; _Decimal64 d64; } y;
670if (x != x) return 83;
671y.d64 = 1234567890123456.0dd;
672return y.d == 0.14894469406741037E-123 ? 80 :
673       y.d == 0.59075095508629822E-68  ? 81 : 82;
674]])], [AC_MSG_RESULT(internal error)
675       AC_MSG_FAILURE(unexpected exit status 0)],
676      [d64_exit_status=$?
677       case "$d64_exit_status" in
678         80) AC_MSG_RESULT(DPD)
679             if test "$enable_decimal_float" = bid; then
680               AC_MSG_ERROR([encoding mismatch (BID requested).])
681             fi
682             if test "$enable_decimal_float" != generic; then
683               enable_decimal_float=dpd
684             fi ;;
685         81) AC_MSG_RESULT(BID)
686             if test "$enable_decimal_float" = dpd; then
687               AC_MSG_ERROR([encoding mismatch (DPD requested).])
688             fi
689             if test "$enable_decimal_float" != generic; then
690               enable_decimal_float=bid
691             fi ;;
692         82) AC_MSG_RESULT(neither DPD nor BID)
693             if test "$enable_decimal_float" = dpd; then
694               AC_MSG_ERROR([encoding mismatch (DPD requested).])
695             fi
696             if test "$enable_decimal_float" = bid; then
697               AC_MSG_ERROR([encoding mismatch (BID requested).])
698             fi
699             enable_decimal_float=generic
700  AC_MSG_WARN([The _Decimal64 encoding is non-standard or there was an])
701  AC_MSG_WARN([issue with its detection.  The generic code will be used.])
702  AC_MSG_WARN([Please do not forget to test with `make check'.])
703  AC_MSG_WARN([In case of failure of a decimal test, you should rebuild])
704  AC_MSG_WARN([MPFR without --enable-decimal-float.]) ;;
705         *)  AC_MSG_RESULT(error (exit status $d64_exit_status))
706             case "$enable_decimal_float" in
707               yes|bid|dpd|generic) AC_MSG_FAILURE([internal or link error.
708Please build MPFR without --enable-decimal-float.]) ;;
709               *) enable_decimal_float=no ;;
710             esac ;;
711       esac],
712      [AC_MSG_RESULT(cannot test)
713       dnl Since the _Decimal64 type exists, we assume that it is correctly
714       dnl supported. The detection of the encoding may still be done at
715       dnl compile time. We do not add a configure test for it so that this
716       dnl can be done on platforms where configure cannot be used.
717       enable_decimal_float=compile-time])
718    ],
719    [AC_MSG_RESULT(no)
720     case "$enable_decimal_float" in
721       yes|bid|dpd|generic)
722         AC_MSG_FAILURE([compiler doesn't know _Decimal64 (ISO/IEC TR 24732).
723Please use another compiler or build MPFR without --enable-decimal-float.]) ;;
724       *) enable_decimal_float=no ;;
725     esac])
726  if test "$enable_decimal_float" != no; then
727    AC_DEFINE([MPFR_WANT_DECIMAL_FLOATS],1,
728              [Build decimal float functions])
729    case "$enable_decimal_float" in
730      dpd) AC_DEFINE([DECIMAL_DPD_FORMAT],1,[]) ;;
731      bid) AC_DEFINE([DECIMAL_BID_FORMAT],1,[]) ;;
732      generic) AC_DEFINE([DECIMAL_GENERIC_CODE],1,[]) ;;
733      compile-time) ;;
734      *) AC_MSG_ERROR(internal error) ;;
735    esac
736  fi
737
738dnl Check the bit-field ordering for _Decimal128.
739dnl Little endian: sig=0 comb=49400 t0=0 t1=0 t2=0 t3=10
740dnl Big endian: sig=0 comb=8 t0=0 t1=0 t2=0 t3=570933248
741dnl Note: If the compilation fails, the compiler should exit with
742dnl an exit status less than 80.
743  AC_MSG_CHECKING(bit-field ordering for _Decimal128)
744  AC_RUN_IFELSE([AC_LANG_PROGRAM([[
745  ]], [[
746    union ieee_decimal128
747    {
748      struct
749      {
750        unsigned int t3:32;
751        unsigned int t2:32;
752        unsigned int t1:32;
753        unsigned int t0:14;
754        unsigned int comb:17;
755        unsigned int sig:1;
756      } s;
757      _Decimal128 d128;
758    } x;
759
760    x.d128 = 1.0dl;
761    if (x.s.sig == 0 && x.s.comb == 49400 &&
762        x.s.t0 == 0 && x.s.t1 == 0 && x.s.t2 == 0 && x.s.t3 == 10)
763       return 80; /* little endian */
764    else if (x.s.sig == 0 && x.s.comb == 8 &&
765             x.s.t0 == 0 && x.s.t1 == 0 && x.s.t2 == 0 && x.s.t3 == 570933248)
766       return 81; /* big endian */
767    else
768       return 82; /* unknown encoding */
769  ]])], [AC_MSG_RESULT(internal error)],
770        [d128_exit_status=$?
771         case "$d128_exit_status" in
772           80) AC_MSG_RESULT(little endian)
773               AC_DEFINE([HAVE_DECIMAL128_IEEE_LITTLE_ENDIAN],1) ;;
774           81) AC_MSG_RESULT(big endian)
775               AC_DEFINE([HAVE_DECIMAL128_IEEE_BIG_ENDIAN],1) ;;
776           *)  AC_MSG_RESULT(unavailable or unknown) ;;
777         esac],
778        [AC_MSG_RESULT(cannot test)])
779
780fi
781# End of decimal float checks
782
783dnl Check if _Float128 or __float128 is available. We also require the
784dnl compiler to support hex constants with the f128 or q suffix (this
785dnl prevents the _Float128 support with GCC's -std=c90, but who cares?).
786dnl Note: We use AC_LINK_IFELSE instead of AC_COMPILE_IFELSE since an
787dnl error may occur only at link time, such as under NetBSD:
788dnl   https://mail-index.netbsd.org/pkgsrc-users/2018/02/02/msg026220.html
789dnl   https://mail-index.netbsd.org/pkgsrc-users/2018/02/05/msg026238.html
790dnl By using volatile and making the exit code depend on the value of
791dnl this variable, we also make sure that optimization doesn't make
792dnl the "undefined reference" error disappear.
793if test "$enable_float128" != no; then
794   AC_MSG_CHECKING(if _Float128 with hex constants is supported)
795   AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
796volatile _Float128 x = 0x1.fp+16383f128;
797return x == 0;
798]])],
799      [AC_MSG_RESULT(yes)
800       AC_DEFINE([MPFR_WANT_FLOAT128],1,[Build float128 functions])],
801      [AC_MSG_RESULT(no)
802       AC_MSG_CHECKING(if __float128 can be used as a fallback)
803dnl Use the q suffix in this case.
804       AC_LINK_IFELSE([AC_LANG_PROGRAM([[
805#define _Float128 __float128
806]], [[
807volatile _Float128 x = 0x1.fp+16383q;
808return x == 0;
809]])],
810          [AC_MSG_RESULT(yes)
811           AC_DEFINE([MPFR_WANT_FLOAT128],2,
812                     [Build float128 functions with float128 fallback])
813           AC_DEFINE([_Float128],[__float128],[__float128 fallback])],
814          [AC_MSG_RESULT(no)
815           if test "$enable_float128" = yes; then
816              AC_MSG_ERROR(
817[compiler doesn't know _Float128 or __float128 with hex constants.
818Please use another compiler or build MPFR without --enable-float128.])
819       fi])
820      ])
821fi
822
823dnl Check if Static Assertions are supported.
824AC_MSG_CHECKING(for Static Assertion support)
825saved_CPPFLAGS="$CPPFLAGS"
826CPPFLAGS="$CPPFLAGS -I$srcdir/src"
827AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
828#define MPFR_USE_STATIC_ASSERT 1
829#include "mpfr-sassert.h"
830
831/* Test if Static Assertions work */
832
833int main (void) {
834  int x;
835  (void) (x = 1);  /* cast to void: avoid a warning, at least with GCC */
836  /* Test of the macro after a declaraction and a statement. */
837  MPFR_STAT_STATIC_ASSERT(sizeof(short) <= sizeof(int));
838  return 0;
839}
840  ]])],
841     [AC_MSG_RESULT(yes)
842      AC_DEFINE([MPFR_USE_STATIC_ASSERT],1,[Build MPFR with Static Assertions])
843     ],
844     [AC_MSG_RESULT(no)
845     ])
846CPPFLAGS="$saved_CPPFLAGS"
847
848if test "$enable_lto" = "yes" ; then
849   MPFR_LTO
850fi
851
852dnl Logging support needs nested functions and the 'cleanup' attribute.
853dnl This is checked at the end because the change of CC and/or CFLAGS that
854dnl could occur before may have an influence on this test. The tested code
855dnl is very similar to what is used in MPFR (mpfr-impl.h).
856if test "$enable_logging" = yes; then
857AC_MSG_CHECKING(for nested functions and 'cleanup' attribute)
858AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
859int main (void) {
860  auto void f_cleanup (int *p);
861  void f_cleanup (int *p) { int v = *p; (void) v; }
862  int v __attribute__ ((cleanup (f_cleanup)));
863  v = 0;
864  return 0;
865}
866  ]])],
867     [AC_MSG_RESULT(yes)],
868     [AC_MSG_RESULT(no)
869      AC_MSG_ERROR([logging support needs nested functions and the 'cleanup' attribute])
870     ])
871fi
872
873dnl Timeout support in the testsuite.
874dnl If the --enable-tests-timeout option has not been provided, let's
875dnl enable timeout support only in -dev versions and if we detect that
876dnl the needed POSIX features seem to be available (this is not much
877dnl useful for releases, where an infinite loop is very unlikely).
878dnl When supported, default is 0 (no timeout).
879if test -z "$enable_tests_timeout" && test -n "$dev_version"; then
880AC_MSG_CHECKING(if timeout can be supported)
881AC_LINK_IFELSE([AC_LANG_PROGRAM([[
882#include <sys/resource.h>
883]], [[
884  struct rlimit rlim[1];
885  if (getrlimit (RLIMIT_CPU, rlim))
886    return 1;
887  rlim->rlim_cur = 1;
888  if (setrlimit (RLIMIT_CPU, rlim))
889    return 1;
890]])], [
891  AC_MSG_RESULT(yes)
892  enable_tests_timeout=yes
893],[AC_MSG_RESULT(no)])
894fi
895if test "$enable_tests_timeout" = yes; then
896  AC_DEFINE([MPFR_TESTS_TIMEOUT], 0, [timeout limit])
897fi
898
899])
900dnl end of MPFR_CONFIGS
901
902
903dnl MPFR_CHECK_GMP
904dnl --------------
905dnl Check GMP library vs header. Useful if the user provides --with-gmp
906dnl with a directory containing a GMP version that doesn't have the
907dnl correct ABI: the previous tests won't trigger the error if the same
908dnl GMP version with the right ABI is installed on the system, as this
909dnl library is automatically selected by the linker, while the header
910dnl (which depends on the ABI) of the --with-gmp include directory is
911dnl used.
912dnl Note: if the error is changed to a warning due to that fact that
913dnl libtool is not used, then the same thing should be done for the
914dnl other tests based on GMP.
915AC_DEFUN([MPFR_CHECK_GMP], [
916AC_REQUIRE([MPFR_CONFIGS])dnl
917AC_CACHE_CHECK([for GMP library vs header correctness], mpfr_cv_check_gmp, [
918AC_RUN_IFELSE([AC_LANG_PROGRAM([[
919#include <stdio.h>
920#include <limits.h>
921#include "gmp.h"
922]], [[
923  fprintf (stderr, "GMP_NAIL_BITS     = %d\n", (int) GMP_NAIL_BITS);
924  fprintf (stderr, "GMP_NUMB_BITS     = %d\n", (int) GMP_NUMB_BITS);
925  fprintf (stderr, "mp_bits_per_limb  = %d\n", (int) mp_bits_per_limb);
926  fprintf (stderr, "sizeof(mp_limb_t) = %d\n", (int) sizeof(mp_limb_t));
927  if (GMP_NAIL_BITS != 0)
928    {
929      fprintf (stderr, "GMP_NAIL_BITS != 0\n");
930      return 81;
931    }
932  if (GMP_NUMB_BITS != mp_bits_per_limb)
933    {
934      fprintf (stderr, "GMP_NUMB_BITS != mp_bits_per_limb\n");
935      return 82;
936    }
937  if (GMP_NUMB_BITS != sizeof(mp_limb_t) * CHAR_BIT)
938    {
939      fprintf (stderr, "GMP_NUMB_BITS != sizeof(mp_limb_t) * CHAR_BIT\n");
940      return 83;
941    }
942  return 0;
943]])], [mpfr_cv_check_gmp="yes"],
944      [mpfr_cv_check_gmp="no (exit status is $?)"],
945      [mpfr_cv_check_gmp="cannot test, assume yes"])
946])
947case $mpfr_cv_check_gmp in
948no*)
949  AC_MSG_ERROR([bad GMP library or header - ABI problem?
950See 'config.log' for details.]) ;;
951esac
952])
953
954
955dnl MPFR_CHECK_DBL2INT_BUG
956dnl ----------------------
957dnl Check for double-to-integer conversion bug
958dnl https://gforge.inria.fr/tracker/index.php?func=detail&aid=14435
959dnl The following problem has been seen under Solaris in config.log,
960dnl i.e. the failure to link with libgmp wasn't detected in the first
961dnl test:
962dnl   configure: checking if gmp.h version and libgmp version are the same
963dnl   configure: gcc -o conftest -Wall -Wmissing-prototypes [...]
964dnl   configure: $? = 0
965dnl   configure: ./conftest
966dnl   ld.so.1: conftest: fatal: libgmp.so.10: open failed: No such file [...]
967dnl   configure: $? = 0
968dnl   configure: result: yes
969dnl   configure: checking for double-to-integer conversion bug
970dnl   configure: gcc -o conftest -Wall -Wmissing-prototypes [...]
971dnl   configure: $? = 0
972dnl   configure: ./conftest
973dnl   ld.so.1: conftest: fatal: libgmp.so.10: open failed: No such file [...]
974dnl   ./configure[1680]: eval: line 1: 1971: Killed
975dnl   configure: $? = 9
976dnl   configure: program exited with status 9
977AC_DEFUN([MPFR_CHECK_DBL2INT_BUG], [
978AC_REQUIRE([MPFR_CONFIGS])dnl
979AC_CACHE_CHECK([for double-to-integer conversion bug], mpfr_cv_dbl_int_bug, [
980AC_RUN_IFELSE([AC_LANG_PROGRAM([[
981#include <stdio.h>
982#include "gmp.h"
983]], [[
984  double d;
985  mp_limb_t u;
986  int i;
987
988  d = 1.0;
989  for (i = 0; i < GMP_NUMB_BITS - 1; i++)
990    d = d + d;
991  u = (mp_limb_t) d;
992  for (; i > 0; i--)
993    {
994      if (u & 1)
995        break;
996      u = u >> 1;
997    }
998  if (i == 0 && u == 1UL)
999    return 0;
1000  fprintf (stderr, "Failure: i = %d, (unsigned long) u = %lu\n",
1001           i, (unsigned long) u);
1002  return 1;
1003]])], [mpfr_cv_dbl_int_bug="no"],
1004      [mpfr_cv_dbl_int_bug="yes or failed to exec (exit status is $?)"],
1005      [mpfr_cv_dbl_int_bug="cannot test, assume not present"])
1006])
1007case $mpfr_cv_dbl_int_bug in
1008yes*)
1009  AC_MSG_ERROR([double-to-integer conversion is incorrect.
1010You need to use another compiler (or lower the optimization level).]) ;;
1011esac
1012])
1013
1014dnl MPFR_CHECK_MP_LIMB_T_VS_LONG
1015dnl ----------------------------
1016dnl Check whether a long fits in mp_limb_t.
1017dnl If static assertions are not supported, one gets "no" even though a long
1018dnl fits in mp_limb_t. Therefore, code without MPFR_LONG_WITHIN_LIMB defined
1019dnl needs to be portable.
1020dnl According to the GMP developers, a limb is always as large as a long,
1021dnl except when __GMP_SHORT_LIMB is defined. It is currently never defined:
1022dnl https://gmplib.org/list-archives/gmp-discuss/2018-February/006190.html
1023dnl but it is not clear whether this could change in the future.
1024AC_DEFUN([MPFR_CHECK_MP_LIMB_T_VS_LONG], [
1025AC_REQUIRE([MPFR_CONFIGS])
1026AC_CACHE_CHECK([for long to fit in mp_limb_t], mpfr_cv_long_within_limb, [
1027saved_CPPFLAGS="$CPPFLAGS"
1028CPPFLAGS="$CPPFLAGS -I$srcdir/src"
1029dnl AC_LINK_IFELSE is safer than AC_COMPILE_IFELSE, as it will detect
1030dnl undefined function-like macros (which otherwise may be regarded
1031dnl as valid function calls with AC_COMPILE_IFELSE since prototypes
1032dnl are not required by the C standard).
1033AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1034#include "gmp.h"
1035/* Make sure that a static assertion is used (not MPFR_ASSERTN). */
1036#undef MPFR_USE_STATIC_ASSERT
1037#define MPFR_USE_STATIC_ASSERT 1
1038#include "mpfr-sassert.h"
1039]], [[
1040  MPFR_STAT_STATIC_ASSERT ((mp_limb_t) -1 >= (unsigned long) -1);
1041  return 0;
1042]])], [mpfr_cv_long_within_limb="yes"],
1043      [mpfr_cv_long_within_limb="no"])
1044])
1045case $mpfr_cv_long_within_limb in
1046yes*)
1047      AC_DEFINE([MPFR_LONG_WITHIN_LIMB],1,[long can be stored in mp_limb_t]) ;;
1048esac
1049CPPFLAGS="$saved_CPPFLAGS"
1050])
1051
1052dnl MPFR_CHECK_MP_LIMB_T_VS_INTMAX
1053dnl ------------------------------
1054dnl Check that an intmax_t can fit in a mp_limb_t.
1055AC_DEFUN([MPFR_CHECK_MP_LIMB_T_VS_INTMAX], [
1056AC_REQUIRE([MPFR_CONFIGS])
1057if test "$ac_cv_type_intmax_t" = yes; then
1058AC_CACHE_CHECK([for intmax_t to fit in mp_limb_t], mpfr_cv_intmax_within_limb, [
1059saved_CPPFLAGS="$CPPFLAGS"
1060CPPFLAGS="$CPPFLAGS -I$srcdir/src -DMPFR_NEED_INTMAX_H"
1061dnl AC_LINK_IFELSE is safer than AC_COMPILE_IFELSE, as it will detect
1062dnl undefined function-like macros (which otherwise may be regarded
1063dnl as valid function calls with AC_COMPILE_IFELSE since prototypes
1064dnl are not required by the C standard).
1065AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1066#include "gmp.h"
1067/* Make sure that a static assertion is used (not MPFR_ASSERTN). */
1068#undef MPFR_USE_STATIC_ASSERT
1069#define MPFR_USE_STATIC_ASSERT 1
1070#include "mpfr-sassert.h"
1071#include "mpfr-intmax.h"
1072]], [[
1073  MPFR_STAT_STATIC_ASSERT ((mp_limb_t) -1 >= (uintmax_t) -1);
1074  return 0;
1075]])], [mpfr_cv_intmax_within_limb="yes"],
1076      [mpfr_cv_intmax_within_limb="no"])
1077])
1078case $mpfr_cv_intmax_within_limb in
1079yes*)
1080      AC_DEFINE([MPFR_INTMAX_WITHIN_LIMB],1,[intmax_t can be stored in mp_limb_t]) ;;
1081esac
1082CPPFLAGS="$saved_CPPFLAGS"
1083fi
1084])
1085
1086dnl MPFR_PARSE_DIRECTORY
1087dnl Input:  $1 = a string to a relative or absolute directory
1088dnl Output: $2 = the variable to set with the absolute directory
1089AC_DEFUN([MPFR_PARSE_DIRECTORY],
1090[
1091 dnl Check if argument is a directory
1092 if test -d $1 ; then
1093    dnl Get the absolute path of the directory in case of relative directory
1094    dnl with the realpath command. If the output is empty, the cause may be
1095    dnl that this command has not been found, and we do an alternate test,
1096    dnl the same as what autoconf does for the generated configure script to
1097    dnl determine whether a pathname is absolute or relative.
1098    local_tmp=`realpath $1 2>/dev/null`
1099    if test "$local_tmp" != "" ; then
1100       if test -d "$local_tmp" ; then
1101           $2="$local_tmp"
1102       else
1103           $2=$1
1104       fi
1105    else
1106       dnl The quadrigraphs @<:@, @:>@ and @:}@ produce [, ] and )
1107       dnl respectively (see Autoconf manual). We cannot use quoting here
1108       dnl as the result depends on the context in which this macro is
1109       dnl invoked! To detect that, one needs to look at every instance
1110       dnl of the macro expansion in the generated configure script.
1111       case $1 in
1112         @<:@\\/@:>@* | ?:@<:@\\/@:>@* @:}@ $2=$1 ;;
1113         *@:}@ $2="$PWD"/$1 ;;
1114       esac
1115    fi
1116    dnl Check for space in the directory
1117    if test `echo $1|cut -d' ' -f1` != $1 ; then
1118        AC_MSG_ERROR($1 directory shall not contain any space.)
1119    fi
1120 else
1121    AC_MSG_ERROR($1 shall be a valid directory)
1122 fi
1123])
1124
1125
1126dnl MPFR_C_REALFP_FORMAT
1127dnl --------------------
1128dnl Determine the format of a real floating type (first argument),
1129dnl actually either double or long double. The second argument is
1130dnl the printf length modifier.
1131dnl
1132dnl The object file is grepped, so as to work when cross-compiling.
1133dnl Start and end sequences are included to avoid false matches, and
1134dnl allowance is made for the desired data crossing an "od -b" line
1135dnl boundary.  The test number is a small integer so it should appear
1136dnl exactly, without rounding or truncation, etc.
1137dnl
1138dnl "od -b" is supported even by Unix V7, and the awk script used doesn't
1139dnl have functions or anything, so even an "old" awk should suffice.
1140dnl
1141dnl Concerning long double: The 10-byte IEEE extended format is generally
1142dnl padded with null bytes to either 12 or 16 bytes for alignment purposes.
1143dnl The SVR4 i386 ABI is 12 bytes, or i386 gcc -m128bit-long-double selects
1144dnl 16 bytes. IA-64 is 16 bytes in LP64 mode, or 12 bytes in ILP32 mode.
1145dnl The relevant part in all cases (big and little endian) consists of the
1146dnl first 10 bytes.
1147dnl
1148dnl We compile and link (with "-o conftest$EXEEXT") instead of just
1149dnl compiling (with "-c"), so that this test works with GCC's and
1150dnl clang's LTO (-flto). If we just compile with LTO, the generated
1151dnl object file does not contain the structure as is. This new test
1152dnl is inspired by the one used by GMP for the double type:
1153dnl   https://gmplib.org/repo/gmp/rev/33eb0998a052
1154dnl   https://gmplib.org/repo/gmp/rev/cbc6dbf95a10
1155dnl "$EXEEXT" had to be added, otherwise the test was failing on
1156dnl MS-Windows (see Autoconf manual).
1157
1158AC_DEFUN([MPFR_C_REALFP_FORMAT],
1159[AC_REQUIRE([AC_PROG_CC])
1160AC_REQUIRE([AC_PROG_AWK])
1161AC_REQUIRE([AC_OBJEXT])
1162AS_VAR_PUSHDEF([my_Type_var], [mpfr_cv_c_$1_format])dnl
1163AC_CACHE_CHECK([format of floating-point type `$1'],
1164                my_Type_var,
1165[my_Type_var=unknown
1166 cat >conftest.c <<\EOF
1167[
1168#include <stdio.h>
1169/* "before" is 16 bytes to ensure there's no padding between it and "x".
1170   We're not expecting any type bigger than 16 bytes or with
1171   alignment requirements stricter than 16 bytes.  */
1172typedef struct {
1173  char         before[16];
1174  $1           x;
1175  char         after[8];
1176} foo_t;
1177
1178foo_t foo = {
1179  { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
1180    '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
1181  -123456789.0,
1182  { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
1183};
1184
1185int main (void) {
1186  int i;
1187  for (i = 0; i < 8; i++)
1188    printf ("%d %$2f\n", foo.before[i] + foo.after[i], foo.x);
1189  return 0;
1190}
1191]
1192EOF
1193 mpfr_compile="$CC $CFLAGS $CPPFLAGS $LDFLAGS conftest.c -o conftest$EXEEXT >&AS_MESSAGE_LOG_FD 2>&1"
1194 if AC_TRY_EVAL(mpfr_compile); then
1195   cat >conftest.awk <<\EOF
1196[
1197BEGIN {
1198  found = 0
1199}
1200
1201# got[] holds a sliding window of bytes read the input.  got[0] is the most
1202# recent byte read, and got[31] the oldest byte read, so when looking to
1203# match some data the indices are "reversed".
1204#
1205{
1206  for (f = 2; f <= NF; f++)
1207    {
1208      # new byte, shift others up
1209      for (i = 31; i >= 0; i--)
1210        got[i+1] = got[i];
1211      got[0] = $f;
1212
1213      # end sequence
1214      if (got[7] != "376") continue
1215      if (got[6] != "334") continue
1216      if (got[5] != "272") continue
1217      if (got[4] != "230") continue
1218      if (got[3] != "166") continue
1219      if (got[2] != "124") continue
1220      if (got[1] != "062") continue
1221      if (got[0] != "020") continue
1222
1223      # start sequence, with 8-byte body
1224      if (got[23] == "001" && \
1225          got[22] == "043" && \
1226          got[21] == "105" && \
1227          got[20] == "147" && \
1228          got[19] == "211" && \
1229          got[18] == "253" && \
1230          got[17] == "315" && \
1231          got[16] == "357")
1232        {
1233          saw = " (" got[15] \
1234                 " " got[14] \
1235                 " " got[13] \
1236                 " " got[12] \
1237                 " " got[11] \
1238                 " " got[10] \
1239                 " " got[9]  \
1240                 " " got[8] ")"
1241
1242          if (got[15] == "301" && \
1243              got[14] == "235" && \
1244              got[13] == "157" && \
1245              got[12] == "064" && \
1246              got[11] == "124" && \
1247              got[10] == "000" && \
1248              got[9] ==  "000" && \
1249              got[8] ==  "000")
1250            {
1251              print "IEEE double, big endian"
1252              found = 1
1253              exit
1254            }
1255
1256          if (got[15] == "000" && \
1257              got[14] == "000" && \
1258              got[13] == "000" && \
1259              got[12] == "124" && \
1260              got[11] == "064" && \
1261              got[10] == "157" && \
1262              got[9] ==  "235" && \
1263              got[8] ==  "301")
1264            {
1265              print "IEEE double, little endian"
1266              found = 1
1267              exit
1268            }
1269        }
1270
1271      # start sequence, with 12-byte body
1272      if (got[27] == "001" && \
1273          got[26] == "043" && \
1274          got[25] == "105" && \
1275          got[24] == "147" && \
1276          got[23] == "211" && \
1277          got[22] == "253" && \
1278          got[21] == "315" && \
1279          got[20] == "357")
1280        {
1281          saw = " (" got[19] \
1282                 " " got[18] \
1283                 " " got[17] \
1284                 " " got[16] \
1285                 " " got[15] \
1286                 " " got[14] \
1287                 " " got[13] \
1288                 " " got[12] \
1289                 " " got[11] \
1290                 " " got[10] \
1291                 " " got[9]  \
1292                 " " got[8] ")"
1293
1294          if (got[19] == "000" && \
1295              got[18] == "000" && \
1296              got[17] == "000" && \
1297              got[16] == "000" && \
1298              got[15] == "240" && \
1299              got[14] == "242" && \
1300              got[13] == "171" && \
1301              got[12] == "353" && \
1302              got[11] == "031" && \
1303              got[10] == "300")
1304            {
1305              print "IEEE extended, little endian (12 bytes)"
1306              found = 1
1307              exit
1308            }
1309
1310          if (got[19] == "300" && \
1311              got[18] == "031" && \
1312              got[17] == "000" && \
1313              got[16] == "000" && \
1314              got[15] == "353" && \
1315              got[14] == "171" && \
1316              got[13] == "242" && \
1317              got[12] == "240" && \
1318              got[11] == "000" && \
1319              got[10] == "000" && \
1320              got[09] == "000" && \
1321              got[08] == "000")
1322            {
1323              # format found on m68k
1324              print "IEEE extended, big endian (12 bytes)"
1325              found = 1
1326              exit
1327            }
1328        }
1329
1330      # start sequence, with 16-byte body
1331      if (got[31] == "001" && \
1332          got[30] == "043" && \
1333          got[29] == "105" && \
1334          got[28] == "147" && \
1335          got[27] == "211" && \
1336          got[26] == "253" && \
1337          got[25] == "315" && \
1338          got[24] == "357")
1339        {
1340          saw = " (" got[23] \
1341                 " " got[22] \
1342                 " " got[21] \
1343                 " " got[20] \
1344                 " " got[19] \
1345                 " " got[18] \
1346                 " " got[17] \
1347                 " " got[16] \
1348                 " " got[15] \
1349                 " " got[14] \
1350                 " " got[13] \
1351                 " " got[12] \
1352                 " " got[11] \
1353                 " " got[10] \
1354                 " " got[9]  \
1355                 " " got[8] ")"
1356
1357          if (got[23] == "000" && \
1358              got[22] == "000" && \
1359              got[21] == "000" && \
1360              got[20] == "000" && \
1361              got[19] == "240" && \
1362              got[18] == "242" && \
1363              got[17] == "171" && \
1364              got[16] == "353" && \
1365              got[15] == "031" && \
1366              got[14] == "300")
1367            {
1368              print "IEEE extended, little endian (16 bytes)"
1369              found = 1
1370              exit
1371            }
1372
1373          if (got[23] == "300" && \
1374              got[22] == "031" && \
1375              got[21] == "326" && \
1376              got[20] == "363" && \
1377              got[19] == "105" && \
1378              got[18] == "100" && \
1379              got[17] == "000" && \
1380              got[16] == "000" && \
1381              got[15] == "000" && \
1382              got[14] == "000" && \
1383              got[13] == "000" && \
1384              got[12] == "000" && \
1385              got[11] == "000" && \
1386              got[10] == "000" && \
1387              got[9]  == "000" && \
1388              got[8]  == "000")
1389            {
1390              # format used on HP 9000/785 under HP-UX
1391              print "IEEE quad, big endian"
1392              found = 1
1393              exit
1394            }
1395
1396          if (got[23] == "000" && \
1397              got[22] == "000" && \
1398              got[21] == "000" && \
1399              got[20] == "000" && \
1400              got[19] == "000" && \
1401              got[18] == "000" && \
1402              got[17] == "000" && \
1403              got[16] == "000" && \
1404              got[15] == "000" && \
1405              got[14] == "000" && \
1406              got[13] == "100" && \
1407              got[12] == "105" && \
1408              got[11] == "363" && \
1409              got[10] == "326" && \
1410              got[9]  == "031" && \
1411	      got[8]  == "300")
1412            {
1413              print "IEEE quad, little endian"
1414              found = 1
1415              exit
1416            }
1417
1418          if (got[23] == "301" && \
1419              got[22] == "235" && \
1420              got[21] == "157" && \
1421              got[20] == "064" && \
1422              got[19] == "124" && \
1423              got[18] == "000" && \
1424              got[17] == "000" && \
1425              got[16] == "000" && \
1426              got[15] == "000" && \
1427              got[14] == "000" && \
1428              got[13] == "000" && \
1429              got[12] == "000" && \
1430              got[11] == "000" && \
1431              got[10] == "000" && \
1432              got[9]  == "000" && \
1433              got[8]  == "000")
1434            {
1435              # format used on 32-bit PowerPC (Mac OS X and Debian GNU/Linux)
1436              print "possibly double-double, big endian"
1437              found = 1
1438              exit
1439            }
1440
1441          if (got[23] == "000" && \
1442              got[22] == "000" && \
1443              got[21] == "000" && \
1444              got[20] == "124" && \
1445              got[19] == "064" && \
1446              got[18] == "157" && \
1447              got[17] == "235" && \
1448              got[16] == "301" && \
1449              got[15] == "000" && \
1450              got[14] == "000" && \
1451              got[13] == "000" && \
1452              got[12] == "000" && \
1453              got[11] == "000" && \
1454              got[10] == "000" && \
1455              got[9]  == "000" && \
1456              got[8]  == "000")
1457            {
1458              # format used on ppc64le
1459              print "possibly double-double, little endian"
1460              found = 1
1461              exit
1462            }
1463        }
1464    }
1465}
1466
1467END {
1468  if (! found)
1469    print "unknown", saw
1470}
1471]
1472EOF
1473   my_Type_var=`od -b conftest$EXEEXT | $AWK -f conftest.awk`
1474   case $my_Type_var in
1475   unknown*)
1476     echo "cannot match anything, conftest$EXEEXT contains" >&AS_MESSAGE_LOG_FD
1477     od -b conftest$EXEEXT >&AS_MESSAGE_LOG_FD
1478     ;;
1479   esac
1480 else
1481   AC_MSG_WARN([oops, cannot compile test program])
1482 fi
1483 rm -f conftest*
1484])])
1485
1486
1487dnl  MPFR_HAVE_LIB
1488dnl  -------------
1489dnl
1490dnl  Similar to AC_CHECK_LIB, but without checking any function.
1491dnl  This is useful, because AC_CHECK_LIB has compatibility issues
1492dnl  with GCC's -Werror, such has
1493dnl    error: infinite recursion detected [-Werror=infinite-recursion]
1494dnl  if "main" is checked, or
1495dnl    error: conflicting types for built-in function 'floor'; expected
1496dnl    'double(double)' [-Werror=builtin-declaration-mismatch]
1497dnl  if "floor" is checked (since "char floor ();" is used by autoconf).
1498dnl
1499dnl  In the future, use AC_SEARCH_LIBS instead?
1500
1501AC_DEFUN([MPFR_HAVE_LIB], [
1502saved_LIBS="$LIBS"
1503LIBS="-l$1 $LIBS"
1504AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], $2)
1505LIBS="$saved_LIBS"
1506])
1507
1508
1509dnl  MPFR_CHECK_LIBM
1510dnl  ---------------
1511dnl  Determine math libraries to use.
1512dnl  The actual functions will individually be checked later.
1513
1514AC_DEFUN([MPFR_CHECK_LIBM],
1515[AC_REQUIRE([AC_CANONICAL_HOST])
1516AC_SUBST(MPFR_LIBM,'')
1517case $host in
1518  *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
1519    # According to libtool.m4:
1520    #   These systems don't have libm, or don't need it.
1521    ;;
1522  *-*-solaris*)
1523    # On Solaris, some additional math functions are in -lm9x.
1524    # For MPFR, https://docs.oracle.com/cd/E19957-01/806-3568/ncg_lib.html
1525    # says that ceil, floor and rint are provided by libm. We would also
1526    # like nearbyint when available, but there is no mention of it in this
1527    # doc. Just in case, let's check for it in m9x, e.g. if it is added in
1528    # the future.
1529    MPFR_HAVE_LIB(m9x, MPFR_LIBM="-lm9x")
1530    MPFR_HAVE_LIB(m, MPFR_LIBM="$MPFR_LIBM -lm")
1531    ;;
1532  *-ncr-sysv4.3*)
1533    # The following AC_CHECK_LIB line about -lmw is copied from libtool.m4,
1534    # but do we need it? This has never been tested in MPFR. See commits
1535    #   6d34bd85f038abeaeeb77aa8f65b562623cc38bc (1999-02-13)
1536    #   e65f46d3fc4eb98d25ee94ad8e6f51c5846c8fe3 (1999-03-20)
1537    # in the libtool repository.
1538    AC_CHECK_LIB(mw, _mwvalidcheckl, MPFR_LIBM="-lmw")
1539    MPFR_HAVE_LIB(m, MPFR_LIBM="$MPFR_LIBM -lm")
1540    ;;
1541  *)
1542    MPFR_HAVE_LIB(m, MPFR_LIBM="-lm")
1543    ;;
1544esac
1545])
1546
1547dnl  MPFR_CHECK_LIBQUADMATH
1548dnl  ----------------------
1549dnl  Determine a math library -lquadmath to use.
1550
1551AC_DEFUN([MPFR_CHECK_LIBQUADMATH],
1552[AC_REQUIRE([AC_CANONICAL_HOST])
1553AC_SUBST(MPFR_LIBQUADMATH,'')
1554case $host in
1555  *)
1556    MPFR_HAVE_LIB(quadmath, MPFR_LIBQUADMATH="-lquadmath")
1557    ;;
1558esac
1559])
1560
1561
1562dnl  MPFR_LD_SEARCH_PATHS_FIRST
1563dnl  --------------------------
1564
1565AC_DEFUN([MPFR_LD_SEARCH_PATHS_FIRST],
1566[case "$LD $LDFLAGS" in
1567  *-Wl,-search_paths_first*) ;;
1568  *) AC_MSG_CHECKING([if the compiler understands -Wl,-search_paths_first])
1569     saved_LDFLAGS="$LDFLAGS"
1570     LDFLAGS="-Wl,-search_paths_first $LDFLAGS"
1571     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
1572       [AC_MSG_RESULT(yes)],
1573       [AC_MSG_RESULT(no)]
1574        LDFLAGS="$saved_LDFLAGS")
1575     ;;
1576 esac
1577])
1578
1579
1580dnl  GMP_C_ATTRIBUTE_MODE
1581dnl  --------------------
1582dnl  Introduced in gcc 2.2, but perhaps not in all Apple derived versions.
1583dnl  Needed for mpfr-longlong.h; this is currently necessary for s390.
1584dnl
1585dnl  TODO: Replace this with a cleaner type size detection, as this
1586dnl  solution only works with gcc and assumes CHAR_BIT == 8. Probably use
1587dnl  <stdint.h>, and <https://gcc.gnu.org/viewcvs/gcc/trunk/config/stdint.m4>
1588dnl  as a fallback.
1589
1590AC_DEFUN([GMP_C_ATTRIBUTE_MODE],
1591[AC_CACHE_CHECK([whether gcc __attribute__ ((mode (XX))) works],
1592               gmp_cv_c_attribute_mode,
1593[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[typedef int SItype __attribute__ ((mode (SI)));]], [[]])],
1594 gmp_cv_c_attribute_mode=yes, gmp_cv_c_attribute_mode=no)
1595])
1596if test $gmp_cv_c_attribute_mode = yes; then
1597 AC_DEFINE(HAVE_ATTRIBUTE_MODE, 1,
1598 [Define to 1 if the compiler accepts gcc style __attribute__ ((mode (XX)))])
1599fi
1600])
1601
1602
1603dnl  MPFR_FUNC_GMP_PRINTF_SPEC
1604dnl  ------------------------------------
1605dnl  MPFR_FUNC_GMP_PRINTF_SPEC(spec, type, [includes], [if-true], [if-false])
1606dnl  Check if sprintf and gmp_sprintf support the conversion specifier 'spec'
1607dnl  with type 'type'.
1608dnl  Expand 'if-true' if printf supports 'spec', 'if-false' otherwise.
1609
1610AC_DEFUN([MPFR_FUNC_GMP_PRINTF_SPEC],[
1611AC_MSG_CHECKING(if gmp_printf supports "%$1")
1612AC_RUN_IFELSE([AC_LANG_PROGRAM([[
1613#include <stdio.h>
1614#include <string.h>
1615$3
1616#include "gmp.h"
1617]], [[
1618  char s[256];
1619  $2 a = 17;
1620
1621  /* Contrary to the gmp_sprintf test, do not use the 0 flag with the
1622     precision, as -Werror=format yields an error, even though this
1623     flag is allowed by the ISO C standard (it is just ignored).
1624     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70813 */
1625  if (sprintf (s, "(%.0$1)(%d)", a, 42) != 8 ||
1626      strcmp (s, "(17)(42)") != 0)
1627    return 1;
1628
1629  if (gmp_sprintf (s, "(%0.0$1)(%d)", a, 42) == -1 ||
1630      strcmp (s, "(17)(42)") != 0)
1631    return 1;
1632
1633  return 0;
1634]])],
1635  [AC_MSG_RESULT(yes)
1636  $4],
1637  [AC_MSG_RESULT(no)
1638  $5],
1639  [AC_MSG_RESULT(cross-compiling, assuming yes)
1640  $4])
1641])
1642
1643
1644dnl MPFR_CHECK_PRINTF_SPEC
1645dnl ----------------------
1646dnl Check if gmp_printf supports some optional length modifiers.
1647dnl Defined symbols are negative to shorten the gcc command line.
1648
1649AC_DEFUN([MPFR_CHECK_PRINTF_SPEC], [
1650AC_REQUIRE([MPFR_CONFIGS])dnl
1651if test "$ac_cv_type_intmax_t" = yes; then
1652 MPFR_FUNC_GMP_PRINTF_SPEC([jd], [intmax_t], [
1653#ifdef HAVE_INTTYPES_H
1654# include <inttypes.h>
1655#endif
1656#ifdef HAVE_STDINT_H
1657# include <stdint.h>
1658#endif
1659         ],,
1660         [AC_DEFINE([NPRINTF_J], 1, [printf/gmp_printf cannot read intmax_t])])
1661fi
1662
1663MPFR_FUNC_GMP_PRINTF_SPEC([hhd], [char], [
1664#include "gmp.h"
1665         ],,
1666         [AC_DEFINE([NPRINTF_HH], 1, [printf/gmp_printf cannot use `hh' length modifier])])
1667
1668MPFR_FUNC_GMP_PRINTF_SPEC([lld], [long long int], [
1669#include "gmp.h"
1670         ],,
1671         [AC_DEFINE([NPRINTF_LL], 1, [printf/gmp_printf cannot read long long int])])
1672
1673MPFR_FUNC_GMP_PRINTF_SPEC([Lf], [long double], [
1674#include "gmp.h"
1675         ],
1676         [AC_DEFINE([PRINTF_L], 1, [printf/gmp_printf can read long double])],
1677         [AC_DEFINE([NPRINTF_L], 1, [printf/gmp_printf cannot read long double])])
1678
1679MPFR_FUNC_GMP_PRINTF_SPEC([td], [ptrdiff_t], [
1680#if defined (__cplusplus)
1681#include <cstddef>
1682#else
1683#include <stddef.h>
1684#endif
1685#include "gmp.h"
1686    ],
1687    [AC_DEFINE([PRINTF_T], 1, [printf/gmp_printf can read ptrdiff_t])],
1688    [AC_DEFINE([NPRINTF_T], 1, [printf/gmp_printf cannot read ptrdiff_t])])
1689])
1690
1691dnl MPFR_CHECK_PRINTF_GROUPFLAG
1692dnl ---------------------------
1693dnl Check the support of the group flag for native integers, which is
1694dnl a Single UNIX Specification extension.
1695dnl This will be used to enable some tests, as the implementation of
1696dnl the P length modifier for mpfr_*printf relies on this support.
1697
1698AC_DEFUN([MPFR_CHECK_PRINTF_GROUPFLAG], [
1699AC_MSG_CHECKING(if gmp_printf supports the ' group flag)
1700AC_RUN_IFELSE([AC_LANG_PROGRAM([[
1701#include <string.h>
1702#include "gmp.h"
1703]], [[
1704  char s[256];
1705
1706  if (gmp_sprintf (s, "%'d", 17) == -1) return 1;
1707  return (strcmp (s, "17") != 0);
1708]])],
1709  [AC_MSG_RESULT(yes)
1710   AC_DEFINE([PRINTF_GROUPFLAG], 1, [Define if gmp_printf supports the ' group flag])],
1711  [AC_MSG_RESULT(no)],
1712  [AC_MSG_RESULT(cannot test, assume no)])
1713])
1714])
1715
1716dnl MPFR_LTO
1717dnl --------
1718dnl To be representative, we need:
1719dnl * to compile a source,
1720dnl * to generate a library archive,
1721dnl * to generate a program with this archive.
1722AC_DEFUN([MPFR_LTO],[
1723dnl Check for -flto support
1724CFLAGS="$CFLAGS -flto"
1725
1726AC_MSG_CHECKING([if Link Time Optimisation flag '-flto' is supported...])
1727AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
1728int main(void) { return 0; }
1729  ]])],
1730     [AC_MSG_RESULT(yes)
1731     ],
1732     [AC_MSG_RESULT(no)
1733      AC_MSG_ERROR([Link Time Optimisation flag '-flto' is not supported.])
1734     ])
1735
1736dnl Check if it works...
1737mpfr_compile_and_link()
1738{
1739   echo "int f(int); int f(int n) { return n; }" > conftest-f.c
1740   echo "int f(int); int main() { return f(0); }" > conftest-m.c
1741   echo "$CC $CFLAGS -c -o conftest-f.o conftest-f.c" >&2
1742   $CC $CFLAGS -c -o conftest-f.o conftest-f.c || return 1
1743   echo "$AR cru conftest-lib.a conftest-f.o" >&2
1744   $AR cru conftest-lib.a conftest-f.o || return 1
1745   echo "$RANLIB conftest-lib.a" >&2
1746   $RANLIB conftest-lib.a || return 1
1747   echo "$CC $CFLAGS conftest-m.c conftest-lib.a" >&2
1748   $CC $CFLAGS conftest-m.c conftest-lib.a || return 1
1749   return 0
1750}
1751   AC_MSG_CHECKING([if Link Time Optimisation works with AR=$AR])
1752   if mpfr_compile_and_link 2> conftest-log1.txt ; then
1753      cat conftest-log1.txt >&AS_MESSAGE_LOG_FD
1754      AC_MSG_RESULT(yes)
1755   else
1756      cat conftest-log1.txt >&AS_MESSAGE_LOG_FD
1757      AC_MSG_RESULT(no)
1758      AR=gcc-ar
1759      RANLIB=gcc-ranlib
1760      AC_MSG_CHECKING([if Link Time Optimisation works with AR=$AR])
1761      if mpfr_compile_and_link 2> conftest-log2.txt; then
1762         cat conftest-log2.txt >&AS_MESSAGE_LOG_FD
1763         AC_MSG_RESULT(yes)
1764      else
1765        cat conftest-log2.txt >&AS_MESSAGE_LOG_FD
1766        AC_MSG_RESULT(no)
1767        AC_MSG_ERROR([Link Time Optimisation is not supported (see config.log for details).])
1768      fi
1769   fi
1770rm -f conftest*
1771])
1772
1773dnl MPFR_CHECK_CONSTRUCTOR_ATTR
1774dnl ---------------------------
1775dnl Check for constructor/destructor attributes to function.
1776dnl Output: Define
1777dnl  * MPFR_HAVE_CONSTRUCTOR_ATTR C define
1778dnl  * mpfr_have_constructor_destructor_attributes shell variable to yes
1779dnl if supported.
1780AC_DEFUN([MPFR_CHECK_CONSTRUCTOR_ATTR], [
1781AC_MSG_CHECKING([for constructor and destructor attributes])
1782AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1783#include <stdlib.h>
1784int x = 0;
1785__attribute__((constructor)) static void
1786call_f(void) { x = 1742; }
1787__attribute__((destructor)) static void
1788call_g(void) { x = 1448; }
1789]], [[
1790    return (x == 1742) ? 0 : 1;
1791]])], [AC_MSG_RESULT(yes)
1792       mpfr_have_constructor_destructor_attributes=yes ],
1793      [AC_MSG_RESULT(no)]
1794)
1795
1796if test "$mpfr_have_constructor_destructor_attributes" = "yes"; then
1797  AC_DEFINE(MPFR_HAVE_CONSTRUCTOR_ATTR, 1,
1798   [Define if the constructor/destructor GCC attributes are supported.])
1799fi
1800])
1801
1802dnl MPFR_CHECK_C11_THREAD
1803dnl ---------------------
1804dnl Check for C11 thread support
1805dnl Output: Define
1806dnl  * MPFR_HAVE_C11_LOCK C define
1807dnl  * mpfr_c11_thread_ok shell variable to yes
1808dnl if supported.
1809dnl We don't check for __STDC_NO_THREADS__ define variable but rather try to mimic our usage.
1810AC_DEFUN([MPFR_CHECK_C11_THREAD], [
1811AC_MSG_CHECKING([for ISO C11 thread support])
1812AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1813#include <assert.h>
1814#include <threads.h>
1815 mtx_t lock;
1816 once_flag once = ONCE_FLAG_INIT;
1817 thrd_t thd_idx;
1818 int x = 0;
1819 void once_call (void) { x = 1; }
1820]], [[
1821    int err;
1822    err = mtx_init(&lock, mtx_plain);
1823    assert(err == thrd_success);
1824    err = mtx_lock(&lock);
1825    assert(err == thrd_success);
1826    err = mtx_unlock(&lock);
1827    assert(err == thrd_success);
1828    mtx_destroy(&lock);
1829    once_call(&once, once_call);
1830    return x == 1 ? 0 : -1;
1831]])], [AC_MSG_RESULT(yes)
1832       mpfr_c11_thread_ok=yes ],
1833      [AC_MSG_RESULT(no)]
1834)
1835
1836if test "$mpfr_c11_thread_ok" = "yes"; then
1837  AC_DEFINE(MPFR_HAVE_C11_LOCK, 1,
1838   [Define if the ISO C11 Thread is supported.])
1839fi
1840])
1841
1842
1843