xref: /netbsd-src/external/lgpl3/mpfr/dist/acinclude.m4 (revision 924795e69c8bb3f17afd8fcbb799710cc1719dc4)
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
873])
874dnl end of MPFR_CONFIGS
875
876
877dnl MPFR_CHECK_GMP
878dnl --------------
879dnl Check GMP library vs header. Useful if the user provides --with-gmp
880dnl with a directory containing a GMP version that doesn't have the
881dnl correct ABI: the previous tests won't trigger the error if the same
882dnl GMP version with the right ABI is installed on the system, as this
883dnl library is automatically selected by the linker, while the header
884dnl (which depends on the ABI) of the --with-gmp include directory is
885dnl used.
886dnl Note: if the error is changed to a warning due to that fact that
887dnl libtool is not used, then the same thing should be done for the
888dnl other tests based on GMP.
889AC_DEFUN([MPFR_CHECK_GMP], [
890AC_REQUIRE([MPFR_CONFIGS])dnl
891AC_CACHE_CHECK([for GMP library vs header correctness], mpfr_cv_check_gmp, [
892AC_RUN_IFELSE([AC_LANG_PROGRAM([[
893#include <stdio.h>
894#include <limits.h>
895#include <gmp.h>
896]], [[
897  fprintf (stderr, "GMP_NAIL_BITS     = %d\n", (int) GMP_NAIL_BITS);
898  fprintf (stderr, "GMP_NUMB_BITS     = %d\n", (int) GMP_NUMB_BITS);
899  fprintf (stderr, "mp_bits_per_limb  = %d\n", (int) mp_bits_per_limb);
900  fprintf (stderr, "sizeof(mp_limb_t) = %d\n", (int) sizeof(mp_limb_t));
901  if (GMP_NAIL_BITS != 0)
902    {
903      fprintf (stderr, "GMP_NAIL_BITS != 0\n");
904      return 81;
905    }
906  if (GMP_NUMB_BITS != mp_bits_per_limb)
907    {
908      fprintf (stderr, "GMP_NUMB_BITS != mp_bits_per_limb\n");
909      return 82;
910    }
911  if (GMP_NUMB_BITS != sizeof(mp_limb_t) * CHAR_BIT)
912    {
913      fprintf (stderr, "GMP_NUMB_BITS != sizeof(mp_limb_t) * CHAR_BIT\n");
914      return 83;
915    }
916  return 0;
917]])], [mpfr_cv_check_gmp="yes"],
918      [mpfr_cv_check_gmp="no (exit status is $?)"],
919      [mpfr_cv_check_gmp="cannot test, assume yes"])
920])
921case $mpfr_cv_check_gmp in
922no*)
923  AC_MSG_ERROR([bad GMP library or header - ABI problem?
924See 'config.log' for details.]) ;;
925esac
926])
927
928
929dnl MPFR_CHECK_DBL2INT_BUG
930dnl ----------------------
931dnl Check for double-to-integer conversion bug
932dnl https://gforge.inria.fr/tracker/index.php?func=detail&aid=14435
933dnl The following problem has been seen under Solaris in config.log,
934dnl i.e. the failure to link with libgmp wasn't detected in the first
935dnl test:
936dnl   configure: checking if gmp.h version and libgmp version are the same
937dnl   configure: gcc -o conftest -Wall -Wmissing-prototypes [...]
938dnl   configure: $? = 0
939dnl   configure: ./conftest
940dnl   ld.so.1: conftest: fatal: libgmp.so.10: open failed: No such file [...]
941dnl   configure: $? = 0
942dnl   configure: result: yes
943dnl   configure: checking for double-to-integer conversion bug
944dnl   configure: gcc -o conftest -Wall -Wmissing-prototypes [...]
945dnl   configure: $? = 0
946dnl   configure: ./conftest
947dnl   ld.so.1: conftest: fatal: libgmp.so.10: open failed: No such file [...]
948dnl   ./configure[1680]: eval: line 1: 1971: Killed
949dnl   configure: $? = 9
950dnl   configure: program exited with status 9
951AC_DEFUN([MPFR_CHECK_DBL2INT_BUG], [
952AC_REQUIRE([MPFR_CONFIGS])dnl
953AC_CACHE_CHECK([for double-to-integer conversion bug], mpfr_cv_dbl_int_bug, [
954AC_RUN_IFELSE([AC_LANG_PROGRAM([[
955#include <stdio.h>
956#include <gmp.h>
957]], [[
958  double d;
959  mp_limb_t u;
960  int i;
961
962  d = 1.0;
963  for (i = 0; i < GMP_NUMB_BITS - 1; i++)
964    d = d + d;
965  u = (mp_limb_t) d;
966  for (; i > 0; i--)
967    {
968      if (u & 1)
969        break;
970      u = u >> 1;
971    }
972  if (i == 0 && u == 1UL)
973    return 0;
974  fprintf (stderr, "Failure: i = %d, (unsigned long) u = %lu\n",
975           i, (unsigned long) u);
976  return 1;
977]])], [mpfr_cv_dbl_int_bug="no"],
978      [mpfr_cv_dbl_int_bug="yes or failed to exec (exit status is $?)"],
979      [mpfr_cv_dbl_int_bug="cannot test, assume not present"])
980])
981case $mpfr_cv_dbl_int_bug in
982yes*)
983  AC_MSG_ERROR([double-to-integer conversion is incorrect.
984You need to use another compiler (or lower the optimization level).]) ;;
985esac
986])
987
988dnl MPFR_CHECK_MP_LIMB_T_VS_LONG
989dnl ----------------------------
990dnl Check whether a long fits in mp_limb_t.
991dnl If static assertions are not supported, one gets "no" even though a long
992dnl fits in mp_limb_t. Therefore, code without MPFR_LONG_WITHIN_LIMB defined
993dnl needs to be portable.
994dnl According to the GMP developers, a limb is always as large as a long,
995dnl except when __GMP_SHORT_LIMB is defined. It is currently never defined:
996dnl https://gmplib.org/list-archives/gmp-discuss/2018-February/006190.html
997dnl but it is not clear whether this could change in the future.
998AC_DEFUN([MPFR_CHECK_MP_LIMB_T_VS_LONG], [
999AC_REQUIRE([MPFR_CONFIGS])
1000AC_CACHE_CHECK([for long to fit in mp_limb_t], mpfr_cv_long_within_limb, [
1001saved_CPPFLAGS="$CPPFLAGS"
1002CPPFLAGS="$CPPFLAGS -I$srcdir/src"
1003dnl AC_LINK_IFELSE is safer than AC_COMPILE_IFELSE, as it will detect
1004dnl undefined function-like macros (which otherwise may be regarded
1005dnl as valid function calls with AC_COMPILE_IFELSE since prototypes
1006dnl are not required by the C standard).
1007AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1008#include <gmp.h>
1009/* Make sure that a static assertion is used (not MPFR_ASSERTN). */
1010#undef MPFR_USE_STATIC_ASSERT
1011#define MPFR_USE_STATIC_ASSERT 1
1012#include "mpfr-sassert.h"
1013]], [[
1014  MPFR_STAT_STATIC_ASSERT ((mp_limb_t) -1 >= (unsigned long) -1);
1015  return 0;
1016]])], [mpfr_cv_long_within_limb="yes"],
1017      [mpfr_cv_long_within_limb="no"])
1018])
1019case $mpfr_cv_long_within_limb in
1020yes*)
1021      AC_DEFINE([MPFR_LONG_WITHIN_LIMB],1,[long can be stored in mp_limb_t]) ;;
1022esac
1023CPPFLAGS="$saved_CPPFLAGS"
1024])
1025
1026dnl MPFR_CHECK_MP_LIMB_T_VS_INTMAX
1027dnl ------------------------------
1028dnl Check that an intmax_t can fit in a mp_limb_t.
1029AC_DEFUN([MPFR_CHECK_MP_LIMB_T_VS_INTMAX], [
1030AC_REQUIRE([MPFR_CONFIGS])
1031if test "$ac_cv_type_intmax_t" = yes; then
1032AC_CACHE_CHECK([for intmax_t to fit in mp_limb_t], mpfr_cv_intmax_within_limb, [
1033saved_CPPFLAGS="$CPPFLAGS"
1034CPPFLAGS="$CPPFLAGS -I$srcdir/src -DMPFR_NEED_INTMAX_H"
1035dnl AC_LINK_IFELSE is safer than AC_COMPILE_IFELSE, as it will detect
1036dnl undefined function-like macros (which otherwise may be regarded
1037dnl as valid function calls with AC_COMPILE_IFELSE since prototypes
1038dnl are not required by the C standard).
1039AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1040#include <gmp.h>
1041/* Make sure that a static assertion is used (not MPFR_ASSERTN). */
1042#undef MPFR_USE_STATIC_ASSERT
1043#define MPFR_USE_STATIC_ASSERT 1
1044#include "mpfr-sassert.h"
1045#include "mpfr-intmax.h"
1046]], [[
1047  MPFR_STAT_STATIC_ASSERT ((mp_limb_t) -1 >= (uintmax_t) -1);
1048  return 0;
1049]])], [mpfr_cv_intmax_within_limb="yes"],
1050      [mpfr_cv_intmax_within_limb="no"])
1051])
1052case $mpfr_cv_intmax_within_limb in
1053yes*)
1054      AC_DEFINE([MPFR_INTMAX_WITHIN_LIMB],1,[intmax_t can be stored in mp_limb_t]) ;;
1055esac
1056CPPFLAGS="$saved_CPPFLAGS"
1057fi
1058])
1059
1060dnl MPFR_PARSE_DIRECTORY
1061dnl Input:  $1 = a string to a relative or absolute directory
1062dnl Output: $2 = the variable to set with the absolute directory
1063AC_DEFUN([MPFR_PARSE_DIRECTORY],
1064[
1065 dnl Check if argument is a directory
1066 if test -d $1 ; then
1067    dnl Get the absolute path of the directory in case of relative directory
1068    dnl with the realpath command. If the output is empty, the cause may be
1069    dnl that this command has not been found, and we do an alternate test,
1070    dnl the same as what autoconf does for the generated configure script to
1071    dnl determine whether a pathname is absolute or relative.
1072    local_tmp=`realpath $1 2>/dev/null`
1073    if test "$local_tmp" != "" ; then
1074       if test -d "$local_tmp" ; then
1075           $2="$local_tmp"
1076       else
1077           $2=$1
1078       fi
1079    else
1080       dnl The quadrigraphs @<:@, @:>@ and @:}@ produce [, ] and )
1081       dnl respectively (see Autoconf manual). We cannot use quoting here
1082       dnl as the result depends on the context in which this macro is
1083       dnl invoked! To detect that, one needs to look at every instance
1084       dnl of the macro expansion in the generated configure script.
1085       case $1 in
1086         @<:@\\/@:>@* | ?:@<:@\\/@:>@* @:}@ $2=$1 ;;
1087         *@:}@ $2="$PWD"/$1 ;;
1088       esac
1089    fi
1090    dnl Check for space in the directory
1091    if test `echo $1|cut -d' ' -f1` != $1 ; then
1092        AC_MSG_ERROR($1 directory shall not contain any space.)
1093    fi
1094 else
1095    AC_MSG_ERROR($1 shall be a valid directory)
1096 fi
1097])
1098
1099
1100dnl MPFR_C_REALFP_FORMAT
1101dnl --------------------
1102dnl Determine the format of a real floating type (first argument),
1103dnl actually either double or long double. The second argument is
1104dnl the printf length modifier.
1105dnl
1106dnl The object file is grepped, so as to work when cross-compiling.
1107dnl Start and end sequences are included to avoid false matches, and
1108dnl allowance is made for the desired data crossing an "od -b" line
1109dnl boundary.  The test number is a small integer so it should appear
1110dnl exactly, without rounding or truncation, etc.
1111dnl
1112dnl "od -b" is supported even by Unix V7, and the awk script used doesn't
1113dnl have functions or anything, so even an "old" awk should suffice.
1114dnl
1115dnl Concerning long double: The 10-byte IEEE extended format is generally
1116dnl padded with null bytes to either 12 or 16 bytes for alignment purposes.
1117dnl The SVR4 i386 ABI is 12 bytes, or i386 gcc -m128bit-long-double selects
1118dnl 16 bytes. IA-64 is 16 bytes in LP64 mode, or 12 bytes in ILP32 mode.
1119dnl The relevant part in all cases (big and little endian) consists of the
1120dnl first 10 bytes.
1121dnl
1122dnl We compile and link (with "-o conftest$EXEEXT") instead of just
1123dnl compiling (with "-c"), so that this test works with GCC's and
1124dnl clang's LTO (-flto). If we just compile with LTO, the generated
1125dnl object file does not contain the structure as is. This new test
1126dnl is inspired by the one used by GMP for the double type:
1127dnl   https://gmplib.org/repo/gmp/rev/33eb0998a052
1128dnl   https://gmplib.org/repo/gmp/rev/cbc6dbf95a10
1129dnl "$EXEEXT" had to be added, otherwise the test was failing on
1130dnl MS-Windows (see Autoconf manual).
1131
1132AC_DEFUN([MPFR_C_REALFP_FORMAT],
1133[AC_REQUIRE([AC_PROG_CC])
1134AC_REQUIRE([AC_PROG_AWK])
1135AC_REQUIRE([AC_OBJEXT])
1136AS_VAR_PUSHDEF([my_Type_var], [mpfr_cv_c_$1_format])dnl
1137AC_CACHE_CHECK([format of floating-point type `$1'],
1138                my_Type_var,
1139[my_Type_var=unknown
1140 cat >conftest.c <<\EOF
1141[
1142#include <stdio.h>
1143/* "before" is 16 bytes to ensure there's no padding between it and "x".
1144   We're not expecting any type bigger than 16 bytes or with
1145   alignment requirements stricter than 16 bytes.  */
1146typedef struct {
1147  char         before[16];
1148  $1           x;
1149  char         after[8];
1150} foo_t;
1151
1152foo_t foo = {
1153  { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
1154    '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
1155  -123456789.0,
1156  { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
1157};
1158
1159int main (void) {
1160  int i;
1161  for (i = 0; i < 8; i++)
1162    printf ("%d %$2f\n", foo.before[i] + foo.after[i], foo.x);
1163  return 0;
1164}
1165]
1166EOF
1167 mpfr_compile="$CC $CFLAGS $CPPFLAGS $LDFLAGS conftest.c -o conftest$EXEEXT >&AS_MESSAGE_LOG_FD 2>&1"
1168 if AC_TRY_EVAL(mpfr_compile); then
1169   cat >conftest.awk <<\EOF
1170[
1171BEGIN {
1172  found = 0
1173}
1174
1175# got[] holds a sliding window of bytes read the input.  got[0] is the most
1176# recent byte read, and got[31] the oldest byte read, so when looking to
1177# match some data the indices are "reversed".
1178#
1179{
1180  for (f = 2; f <= NF; f++)
1181    {
1182      # new byte, shift others up
1183      for (i = 31; i >= 0; i--)
1184        got[i+1] = got[i];
1185      got[0] = $f;
1186
1187      # end sequence
1188      if (got[7] != "376") continue
1189      if (got[6] != "334") continue
1190      if (got[5] != "272") continue
1191      if (got[4] != "230") continue
1192      if (got[3] != "166") continue
1193      if (got[2] != "124") continue
1194      if (got[1] != "062") continue
1195      if (got[0] != "020") continue
1196
1197      # start sequence, with 8-byte body
1198      if (got[23] == "001" && \
1199          got[22] == "043" && \
1200          got[21] == "105" && \
1201          got[20] == "147" && \
1202          got[19] == "211" && \
1203          got[18] == "253" && \
1204          got[17] == "315" && \
1205          got[16] == "357")
1206        {
1207          saw = " (" got[15] \
1208                 " " got[14] \
1209                 " " got[13] \
1210                 " " got[12] \
1211                 " " got[11] \
1212                 " " got[10] \
1213                 " " got[9]  \
1214                 " " got[8] ")"
1215
1216          if (got[15] == "301" && \
1217              got[14] == "235" && \
1218              got[13] == "157" && \
1219              got[12] == "064" && \
1220              got[11] == "124" && \
1221              got[10] == "000" && \
1222              got[9] ==  "000" && \
1223              got[8] ==  "000")
1224            {
1225              print "IEEE double, big endian"
1226              found = 1
1227              exit
1228            }
1229
1230          if (got[15] == "000" && \
1231              got[14] == "000" && \
1232              got[13] == "000" && \
1233              got[12] == "124" && \
1234              got[11] == "064" && \
1235              got[10] == "157" && \
1236              got[9] ==  "235" && \
1237              got[8] ==  "301")
1238            {
1239              print "IEEE double, little endian"
1240              found = 1
1241              exit
1242            }
1243        }
1244
1245      # start sequence, with 12-byte body
1246      if (got[27] == "001" && \
1247          got[26] == "043" && \
1248          got[25] == "105" && \
1249          got[24] == "147" && \
1250          got[23] == "211" && \
1251          got[22] == "253" && \
1252          got[21] == "315" && \
1253          got[20] == "357")
1254        {
1255          saw = " (" got[19] \
1256                 " " got[18] \
1257                 " " got[17] \
1258                 " " got[16] \
1259                 " " got[15] \
1260                 " " got[14] \
1261                 " " got[13] \
1262                 " " got[12] \
1263                 " " got[11] \
1264                 " " got[10] \
1265                 " " got[9]  \
1266                 " " got[8] ")"
1267
1268          if (got[19] == "000" && \
1269              got[18] == "000" && \
1270              got[17] == "000" && \
1271              got[16] == "000" && \
1272              got[15] == "240" && \
1273              got[14] == "242" && \
1274              got[13] == "171" && \
1275              got[12] == "353" && \
1276              got[11] == "031" && \
1277              got[10] == "300")
1278            {
1279              print "IEEE extended, little endian (12 bytes)"
1280              found = 1
1281              exit
1282            }
1283
1284          if (got[19] == "300" && \
1285              got[18] == "031" && \
1286              got[17] == "000" && \
1287              got[16] == "000" && \
1288              got[15] == "353" && \
1289              got[14] == "171" && \
1290              got[13] == "242" && \
1291              got[12] == "240" && \
1292              got[11] == "000" && \
1293              got[10] == "000" && \
1294              got[09] == "000" && \
1295              got[08] == "000")
1296            {
1297              # format found on m68k
1298              print "IEEE extended, big endian (12 bytes)"
1299              found = 1
1300              exit
1301            }
1302        }
1303
1304      # start sequence, with 16-byte body
1305      if (got[31] == "001" && \
1306          got[30] == "043" && \
1307          got[29] == "105" && \
1308          got[28] == "147" && \
1309          got[27] == "211" && \
1310          got[26] == "253" && \
1311          got[25] == "315" && \
1312          got[24] == "357")
1313        {
1314          saw = " (" got[23] \
1315                 " " got[22] \
1316                 " " got[21] \
1317                 " " got[20] \
1318                 " " got[19] \
1319                 " " got[18] \
1320                 " " got[17] \
1321                 " " got[16] \
1322                 " " got[15] \
1323                 " " got[14] \
1324                 " " got[13] \
1325                 " " got[12] \
1326                 " " got[11] \
1327                 " " got[10] \
1328                 " " got[9]  \
1329                 " " got[8] ")"
1330
1331          if (got[23] == "000" && \
1332              got[22] == "000" && \
1333              got[21] == "000" && \
1334              got[20] == "000" && \
1335              got[19] == "240" && \
1336              got[18] == "242" && \
1337              got[17] == "171" && \
1338              got[16] == "353" && \
1339              got[15] == "031" && \
1340              got[14] == "300")
1341            {
1342              print "IEEE extended, little endian (16 bytes)"
1343              found = 1
1344              exit
1345            }
1346
1347          if (got[23] == "300" && \
1348              got[22] == "031" && \
1349              got[21] == "326" && \
1350              got[20] == "363" && \
1351              got[19] == "105" && \
1352              got[18] == "100" && \
1353              got[17] == "000" && \
1354              got[16] == "000" && \
1355              got[15] == "000" && \
1356              got[14] == "000" && \
1357              got[13] == "000" && \
1358              got[12] == "000" && \
1359              got[11] == "000" && \
1360              got[10] == "000" && \
1361              got[9]  == "000" && \
1362              got[8]  == "000")
1363            {
1364              # format used on HP 9000/785 under HP-UX
1365              print "IEEE quad, big endian"
1366              found = 1
1367              exit
1368            }
1369
1370          if (got[23] == "000" && \
1371              got[22] == "000" && \
1372              got[21] == "000" && \
1373              got[20] == "000" && \
1374              got[19] == "000" && \
1375              got[18] == "000" && \
1376              got[17] == "000" && \
1377              got[16] == "000" && \
1378              got[15] == "000" && \
1379              got[14] == "000" && \
1380              got[13] == "100" && \
1381              got[12] == "105" && \
1382              got[11] == "363" && \
1383              got[10] == "326" && \
1384              got[9]  == "031" && \
1385	      got[8]  == "300")
1386            {
1387              print "IEEE quad, little endian"
1388              found = 1
1389              exit
1390            }
1391
1392          if (got[23] == "301" && \
1393              got[22] == "235" && \
1394              got[21] == "157" && \
1395              got[20] == "064" && \
1396              got[19] == "124" && \
1397              got[18] == "000" && \
1398              got[17] == "000" && \
1399              got[16] == "000" && \
1400              got[15] == "000" && \
1401              got[14] == "000" && \
1402              got[13] == "000" && \
1403              got[12] == "000" && \
1404              got[11] == "000" && \
1405              got[10] == "000" && \
1406              got[9]  == "000" && \
1407              got[8]  == "000")
1408            {
1409              # format used on 32-bit PowerPC (Mac OS X and Debian GNU/Linux)
1410              print "possibly double-double, big endian"
1411              found = 1
1412              exit
1413            }
1414
1415          if (got[23] == "000" && \
1416              got[22] == "000" && \
1417              got[21] == "000" && \
1418              got[20] == "124" && \
1419              got[19] == "064" && \
1420              got[18] == "157" && \
1421              got[17] == "235" && \
1422              got[16] == "301" && \
1423              got[15] == "000" && \
1424              got[14] == "000" && \
1425              got[13] == "000" && \
1426              got[12] == "000" && \
1427              got[11] == "000" && \
1428              got[10] == "000" && \
1429              got[9]  == "000" && \
1430              got[8]  == "000")
1431            {
1432              # format used on ppc64le
1433              print "possibly double-double, little endian"
1434              found = 1
1435              exit
1436            }
1437        }
1438    }
1439}
1440
1441END {
1442  if (! found)
1443    print "unknown", saw
1444}
1445]
1446EOF
1447   my_Type_var=`od -b conftest$EXEEXT | $AWK -f conftest.awk`
1448   case $my_Type_var in
1449   unknown*)
1450     echo "cannot match anything, conftest$EXEEXT contains" >&AS_MESSAGE_LOG_FD
1451     od -b conftest$EXEEXT >&AS_MESSAGE_LOG_FD
1452     ;;
1453   esac
1454 else
1455   AC_MSG_WARN([oops, cannot compile test program])
1456 fi
1457 rm -f conftest*
1458])])
1459
1460
1461dnl  MPFR_HAVE_LIB
1462dnl  -------------
1463dnl
1464dnl  Similar to AC_CHECK_LIB, but without checking any function.
1465dnl  This is useful, because AC_CHECK_LIB has compatibility issues
1466dnl  with GCC's -Werror, such has
1467dnl    error: infinite recursion detected [-Werror=infinite-recursion]
1468dnl  if "main" is checked, or
1469dnl    error: conflicting types for built-in function 'floor'; expected
1470dnl    'double(double)' [-Werror=builtin-declaration-mismatch]
1471dnl  if "floor" is checked (since "char floor ();" is used by autoconf).
1472dnl
1473dnl  In the future, use AC_SEARCH_LIBS instead?
1474
1475AC_DEFUN([MPFR_HAVE_LIB], [
1476saved_LIBS="$LIBS"
1477LIBS="-l$1 $LIBS"
1478AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], $2)
1479LIBS="$saved_LIBS"
1480])
1481
1482
1483dnl  MPFR_CHECK_LIBM
1484dnl  ---------------
1485dnl  Determine math libraries to use.
1486dnl  The actual functions will individually be checked later.
1487
1488AC_DEFUN([MPFR_CHECK_LIBM],
1489[AC_REQUIRE([AC_CANONICAL_HOST])
1490AC_SUBST(MPFR_LIBM,'')
1491case $host in
1492  *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
1493    # According to libtool.m4:
1494    #   These systems don't have libm, or don't need it.
1495    ;;
1496  *-*-solaris*)
1497    # On Solaris, some additional math functions are in -lm9x.
1498    # For MPFR, https://docs.oracle.com/cd/E19957-01/806-3568/ncg_lib.html
1499    # says that ceil, floor and rint are provided by libm. We would also
1500    # like nearbyint when available, but there is no mention of it in this
1501    # doc. Just in case, let's check for it in m9x, e.g. if it is added in
1502    # the future.
1503    MPFR_HAVE_LIB(m9x, MPFR_LIBM="-lm9x")
1504    MPFR_HAVE_LIB(m, MPFR_LIBM="$MPFR_LIBM -lm")
1505    ;;
1506  *-ncr-sysv4.3*)
1507    # The following AC_CHECK_LIB line about -lmw is copied from libtool.m4,
1508    # but do we need it? This has never been tested in MPFR. See commits
1509    #   6d34bd85f038abeaeeb77aa8f65b562623cc38bc (1999-02-13)
1510    #   e65f46d3fc4eb98d25ee94ad8e6f51c5846c8fe3 (1999-03-20)
1511    # in the libtool repository.
1512    AC_CHECK_LIB(mw, _mwvalidcheckl, MPFR_LIBM="-lmw")
1513    MPFR_HAVE_LIB(m, MPFR_LIBM="$MPFR_LIBM -lm")
1514    ;;
1515  *)
1516    MPFR_HAVE_LIB(m, MPFR_LIBM="-lm")
1517    ;;
1518esac
1519])
1520
1521dnl  MPFR_CHECK_LIBQUADMATH
1522dnl  ----------------------
1523dnl  Determine a math library -lquadmath to use.
1524
1525AC_DEFUN([MPFR_CHECK_LIBQUADMATH],
1526[AC_REQUIRE([AC_CANONICAL_HOST])
1527AC_SUBST(MPFR_LIBQUADMATH,'')
1528case $host in
1529  *)
1530    MPFR_HAVE_LIB(quadmath, MPFR_LIBQUADMATH="-lquadmath")
1531    ;;
1532esac
1533])
1534
1535
1536dnl  MPFR_LD_SEARCH_PATHS_FIRST
1537dnl  --------------------------
1538
1539AC_DEFUN([MPFR_LD_SEARCH_PATHS_FIRST],
1540[case "$LD $LDFLAGS" in
1541  *-Wl,-search_paths_first*) ;;
1542  *) AC_MSG_CHECKING([if the compiler understands -Wl,-search_paths_first])
1543     saved_LDFLAGS="$LDFLAGS"
1544     LDFLAGS="-Wl,-search_paths_first $LDFLAGS"
1545     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
1546       [AC_MSG_RESULT(yes)],
1547       [AC_MSG_RESULT(no)]
1548        LDFLAGS="$saved_LDFLAGS")
1549     ;;
1550 esac
1551])
1552
1553
1554dnl  GMP_C_ATTRIBUTE_MODE
1555dnl  --------------------
1556dnl  Introduced in gcc 2.2, but perhaps not in all Apple derived versions.
1557dnl  Needed for mpfr-longlong.h; this is currently necessary for s390.
1558dnl
1559dnl  TODO: Replace this with a cleaner type size detection, as this
1560dnl  solution only works with gcc and assumes CHAR_BIT == 8. Probably use
1561dnl  <stdint.h>, and <https://gcc.gnu.org/viewcvs/gcc/trunk/config/stdint.m4>
1562dnl  as a fallback.
1563
1564AC_DEFUN([GMP_C_ATTRIBUTE_MODE],
1565[AC_CACHE_CHECK([whether gcc __attribute__ ((mode (XX))) works],
1566               gmp_cv_c_attribute_mode,
1567[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[typedef int SItype __attribute__ ((mode (SI)));]], [[]])],
1568 gmp_cv_c_attribute_mode=yes, gmp_cv_c_attribute_mode=no)
1569])
1570if test $gmp_cv_c_attribute_mode = yes; then
1571 AC_DEFINE(HAVE_ATTRIBUTE_MODE, 1,
1572 [Define to 1 if the compiler accepts gcc style __attribute__ ((mode (XX)))])
1573fi
1574])
1575
1576
1577dnl  MPFR_FUNC_GMP_PRINTF_SPEC
1578dnl  ------------------------------------
1579dnl  MPFR_FUNC_GMP_PRINTF_SPEC(spec, type, [includes], [if-true], [if-false])
1580dnl  Check if sprintf and gmp_sprintf support the conversion specifier 'spec'
1581dnl  with type 'type'.
1582dnl  Expand 'if-true' if printf supports 'spec', 'if-false' otherwise.
1583
1584AC_DEFUN([MPFR_FUNC_GMP_PRINTF_SPEC],[
1585AC_MSG_CHECKING(if gmp_printf supports "%$1")
1586AC_RUN_IFELSE([AC_LANG_PROGRAM([[
1587#include <stdio.h>
1588#include <string.h>
1589$3
1590#include <gmp.h>
1591]], [[
1592  char s[256];
1593  $2 a = 17;
1594
1595  /* Contrary to the gmp_sprintf test, do not use the 0 flag with the
1596     precision, as -Werror=format yields an error, even though this
1597     flag is allowed by the ISO C standard (it is just ignored).
1598     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70813 */
1599  if (sprintf (s, "(%.0$1)(%d)", a, 42) != 8 ||
1600      strcmp (s, "(17)(42)") != 0)
1601    return 1;
1602
1603  if (gmp_sprintf (s, "(%0.0$1)(%d)", a, 42) == -1 ||
1604      strcmp (s, "(17)(42)") != 0)
1605    return 1;
1606
1607  return 0;
1608]])],
1609  [AC_MSG_RESULT(yes)
1610  $4],
1611  [AC_MSG_RESULT(no)
1612  $5],
1613  [AC_MSG_RESULT(cross-compiling, assuming yes)
1614  $4])
1615])
1616
1617
1618dnl MPFR_CHECK_PRINTF_SPEC
1619dnl ----------------------
1620dnl Check if gmp_printf supports some optional length modifiers.
1621dnl Defined symbols are negative to shorten the gcc command line.
1622
1623AC_DEFUN([MPFR_CHECK_PRINTF_SPEC], [
1624AC_REQUIRE([MPFR_CONFIGS])dnl
1625if test "$ac_cv_type_intmax_t" = yes; then
1626 MPFR_FUNC_GMP_PRINTF_SPEC([jd], [intmax_t], [
1627#ifdef HAVE_INTTYPES_H
1628# include <inttypes.h>
1629#endif
1630#ifdef HAVE_STDINT_H
1631# include <stdint.h>
1632#endif
1633         ],,
1634         [AC_DEFINE([NPRINTF_J], 1, [printf/gmp_printf cannot read intmax_t])])
1635fi
1636
1637MPFR_FUNC_GMP_PRINTF_SPEC([hhd], [char], [
1638#include <gmp.h>
1639         ],,
1640         [AC_DEFINE([NPRINTF_HH], 1, [printf/gmp_printf cannot use `hh' length modifier])])
1641
1642MPFR_FUNC_GMP_PRINTF_SPEC([lld], [long long int], [
1643#include <gmp.h>
1644         ],,
1645         [AC_DEFINE([NPRINTF_LL], 1, [printf/gmp_printf cannot read long long int])])
1646
1647MPFR_FUNC_GMP_PRINTF_SPEC([Lf], [long double], [
1648#include <gmp.h>
1649         ],
1650         [AC_DEFINE([PRINTF_L], 1, [printf/gmp_printf can read long double])],
1651         [AC_DEFINE([NPRINTF_L], 1, [printf/gmp_printf cannot read long double])])
1652
1653MPFR_FUNC_GMP_PRINTF_SPEC([td], [ptrdiff_t], [
1654#if defined (__cplusplus)
1655#include <cstddef>
1656#else
1657#include <stddef.h>
1658#endif
1659#include <gmp.h>
1660    ],
1661    [AC_DEFINE([PRINTF_T], 1, [printf/gmp_printf can read ptrdiff_t])],
1662    [AC_DEFINE([NPRINTF_T], 1, [printf/gmp_printf cannot read ptrdiff_t])])
1663])
1664
1665dnl MPFR_CHECK_PRINTF_GROUPFLAG
1666dnl ---------------------------
1667dnl Check the support of the group flag for native integers, which is
1668dnl a Single UNIX Specification extension.
1669dnl This will be used to enable some tests, as the implementation of
1670dnl the P length modifier for mpfr_*printf relies on this support.
1671
1672AC_DEFUN([MPFR_CHECK_PRINTF_GROUPFLAG], [
1673AC_MSG_CHECKING(if gmp_printf supports the ' group flag)
1674AC_RUN_IFELSE([AC_LANG_PROGRAM([[
1675#include <string.h>
1676#include <gmp.h>
1677]], [[
1678  char s[256];
1679
1680  if (gmp_sprintf (s, "%'d", 17) == -1) return 1;
1681  return (strcmp (s, "17") != 0);
1682]])],
1683  [AC_MSG_RESULT(yes)
1684   AC_DEFINE([PRINTF_GROUPFLAG], 1, [Define if gmp_printf supports the ' group flag])],
1685  [AC_MSG_RESULT(no)],
1686  [AC_MSG_RESULT(cannot test, assume no)])
1687])
1688])
1689
1690dnl MPFR_LTO
1691dnl --------
1692dnl To be representative, we need:
1693dnl * to compile a source,
1694dnl * to generate a library archive,
1695dnl * to generate a program with this archive.
1696AC_DEFUN([MPFR_LTO],[
1697dnl Check for -flto support
1698CFLAGS="$CFLAGS -flto"
1699
1700AC_MSG_CHECKING([if Link Time Optimisation flag '-flto' is supported...])
1701AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
1702int main(void) { return 0; }
1703  ]])],
1704     [AC_MSG_RESULT(yes)
1705     ],
1706     [AC_MSG_RESULT(no)
1707      AC_MSG_ERROR([Link Time Optimisation flag '-flto' is not supported.])
1708     ])
1709
1710dnl Check if it works...
1711mpfr_compile_and_link()
1712{
1713   echo "int f(int); int f(int n) { return n; }" > conftest-f.c
1714   echo "int f(int); int main() { return f(0); }" > conftest-m.c
1715   echo "$CC $CFLAGS -c -o conftest-f.o conftest-f.c" >&2
1716   $CC $CFLAGS -c -o conftest-f.o conftest-f.c || return 1
1717   echo "$AR cru conftest-lib.a conftest-f.o" >&2
1718   $AR cru conftest-lib.a conftest-f.o || return 1
1719   echo "$RANLIB conftest-lib.a" >&2
1720   $RANLIB conftest-lib.a || return 1
1721   echo "$CC $CFLAGS conftest-m.c conftest-lib.a" >&2
1722   $CC $CFLAGS conftest-m.c conftest-lib.a || return 1
1723   return 0
1724}
1725   AC_MSG_CHECKING([if Link Time Optimisation works with AR=$AR])
1726   if mpfr_compile_and_link 2> conftest-log1.txt ; then
1727      cat conftest-log1.txt >&AS_MESSAGE_LOG_FD
1728      AC_MSG_RESULT(yes)
1729   else
1730      cat conftest-log1.txt >&AS_MESSAGE_LOG_FD
1731      AC_MSG_RESULT(no)
1732      AR=gcc-ar
1733      RANLIB=gcc-ranlib
1734      AC_MSG_CHECKING([if Link Time Optimisation works with AR=$AR])
1735      if mpfr_compile_and_link 2> conftest-log2.txt; then
1736         cat conftest-log2.txt >&AS_MESSAGE_LOG_FD
1737         AC_MSG_RESULT(yes)
1738      else
1739        cat conftest-log2.txt >&AS_MESSAGE_LOG_FD
1740        AC_MSG_RESULT(no)
1741        AC_MSG_ERROR([Link Time Optimisation is not supported (see config.log for details).])
1742      fi
1743   fi
1744rm -f conftest*
1745])
1746
1747dnl MPFR_CHECK_CONSTRUCTOR_ATTR
1748dnl ---------------------------
1749dnl Check for constructor/destructor attributes to function.
1750dnl Output: Define
1751dnl  * MPFR_HAVE_CONSTRUCTOR_ATTR C define
1752dnl  * mpfr_have_constructor_destructor_attributes shell variable to yes
1753dnl if supported.
1754AC_DEFUN([MPFR_CHECK_CONSTRUCTOR_ATTR], [
1755AC_MSG_CHECKING([for constructor and destructor attributes])
1756AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1757#include <stdlib.h>
1758int x = 0;
1759__attribute__((constructor)) static void
1760call_f(void) { x = 1742; }
1761__attribute__((destructor)) static void
1762call_g(void) { x = 1448; }
1763]], [[
1764    return (x == 1742) ? 0 : 1;
1765]])], [AC_MSG_RESULT(yes)
1766       mpfr_have_constructor_destructor_attributes=yes ],
1767      [AC_MSG_RESULT(no)]
1768)
1769
1770if test "$mpfr_have_constructor_destructor_attributes" = "yes"; then
1771  AC_DEFINE(MPFR_HAVE_CONSTRUCTOR_ATTR, 1,
1772   [Define if the constructor/destructor GCC attributes are supported.])
1773fi
1774])
1775
1776dnl MPFR_CHECK_C11_THREAD
1777dnl ---------------------
1778dnl Check for C11 thread support
1779dnl Output: Define
1780dnl  * MPFR_HAVE_C11_LOCK C define
1781dnl  * mpfr_c11_thread_ok shell variable to yes
1782dnl if supported.
1783dnl We don't check for __STDC_NO_THREADS__ define variable but rather try to mimic our usage.
1784AC_DEFUN([MPFR_CHECK_C11_THREAD], [
1785AC_MSG_CHECKING([for ISO C11 thread support])
1786AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1787#include <assert.h>
1788#include <threads.h>
1789 mtx_t lock;
1790 once_flag once = ONCE_FLAG_INIT;
1791 thrd_t thd_idx;
1792 int x = 0;
1793 void once_call (void) { x = 1; }
1794]], [[
1795    int err;
1796    err = mtx_init(&lock, mtx_plain);
1797    assert(err == thrd_success);
1798    err = mtx_lock(&lock);
1799    assert(err == thrd_success);
1800    err = mtx_unlock(&lock);
1801    assert(err == thrd_success);
1802    mtx_destroy(&lock);
1803    once_call(&once, once_call);
1804    return x == 1 ? 0 : -1;
1805]])], [AC_MSG_RESULT(yes)
1806       mpfr_c11_thread_ok=yes ],
1807      [AC_MSG_RESULT(no)]
1808)
1809
1810if test "$mpfr_c11_thread_ok" = "yes"; then
1811  AC_DEFINE(MPFR_HAVE_C11_LOCK, 1,
1812   [Define if the ISO C11 Thread is supported.])
1813fi
1814])
1815
1816
1817