1dnl AC_PROG_CC_GNU
2ifdef([AC_PROG_CC_GNU],,[AC_DEFUN([AC_PROG_CC_GNU],)])
3
4dnl
5dnl/*D
6dnl PAC_C_CHECK_COMPILER_OPTION - Check that a compiler option is accepted
7dnl without warning messages
8dnl
9dnl Synopsis:
10dnl PAC_C_CHECK_COMPILER_OPTION(optionname,action-if-ok,action-if-fail)
11dnl
12dnl Output Effects:
13dnl
14dnl If no actions are specified, a working value is added to 'COPTIONS'
15dnl
16dnl Notes:
17dnl This is now careful to check that the output is different, since
18dnl some compilers are noisy.
19dnl
20dnl We are extra careful to prototype the functions in case compiler options
21dnl that complain about poor code are in effect.
22dnl
23dnl Because this is a long script, we have ensured that you can pass a
24dnl variable containing the option name as the first argument.
25dnl
26dnl D*/
27AC_DEFUN([PAC_C_CHECK_COMPILER_OPTION],[
28AC_MSG_CHECKING([whether C compiler accepts option $1])
29pac_opt="$1"
30AC_LANG_PUSH([C])
31CFLAGS_orig="$CFLAGS"
32CFLAGS_opt="$pac_opt $CFLAGS"
33pac_result="unknown"
34
35AC_LANG_CONFTEST([
36	AC_LANG_PROGRAM([[#include <stdio.h>
37                          const char hw[] = "Hello, World\n";]],
38		[[fputs (hw, stdout);]])
39])
40CFLAGS="$CFLAGS_orig"
41rm -f pac_test1.log
42PAC_LINK_IFELSE_LOG([pac_test1.log], [], [
43    CFLAGS="$CFLAGS_opt"
44    rm -f pac_test2.log
45    PAC_LINK_IFELSE_LOG([pac_test2.log], [], [
46        PAC_RUNLOG_IFELSE([diff -b pac_test1.log pac_test2.log],
47                          [pac_result=yes],[pac_result=no])
48    ],[
49        pac_result=no
50    ])
51], [
52    pac_result=no
53])
54AC_MSG_RESULT([$pac_result])
55dnl Delete the conftest created by AC_LANG_CONFTEST.
56rm -f conftest.$ac_ext
57
58if test "$pac_result" = "yes" ; then
59    AC_MSG_CHECKING([whether routines compiled with $pac_opt can be linked with ones compiled without $pac_opt])
60    pac_result=unknown
61    CFLAGS="$CFLAGS_orig"
62    rm -f pac_test3.log
63    PAC_COMPILE_IFELSE_LOG([pac_test3.log], [
64        AC_LANG_SOURCE([
65            int foo(void);
66            int foo(void){return 0;}
67        ])
68    ],[
69        PAC_RUNLOG([mv conftest.$OBJEXT pac_conftest.$OBJEXT])
70        saved_LIBS="$LIBS"
71        LIBS="pac_conftest.$OBJEXT $LIBS"
72
73        rm -f pac_test4.log
74        PAC_LINK_IFELSE_LOG([pac_test4.log], [AC_LANG_PROGRAM()], [
75            CFLAGS="$CFLAGS_opt"
76            rm -f pac_test5.log
77            PAC_LINK_IFELSE_LOG([pac_test5.log], [AC_LANG_PROGRAM()], [
78                PAC_RUNLOG_IFELSE([diff -b pac_test4.log pac_test5.log],
79                                  [pac_result=yes], [pac_result=no])
80            ],[
81                pac_result=no
82            ])
83        ],[
84            pac_result=no
85        ])
86        LIBS="$saved_LIBS"
87        rm -f pac_conftest.$OBJEXT
88    ],[
89        pac_result=no
90    ])
91    AC_MSG_RESULT([$pac_result])
92    rm -f pac_test3.log pac_test4.log pac_test5.log
93fi
94rm -f pac_test1.log pac_test2.log
95
96dnl Restore CFLAGS before 2nd/3rd argument commands are executed,
97dnl as 2nd/3rd argument command could be modifying CFLAGS.
98CFLAGS="$CFLAGS_orig"
99if test "$pac_result" = "yes" ; then
100     ifelse([$2],[],[COPTIONS="$COPTIONS $1"],[$2])
101else
102     ifelse([$3],[],[:],[$3])
103fi
104AC_LANG_POP([C])
105])
106dnl
107dnl/*D
108dnl PAC_C_OPTIMIZATION - Determine C options for producing optimized code
109dnl
110dnl Synopsis
111dnl PAC_C_OPTIMIZATION([action if found])
112dnl
113dnl Output Effect:
114dnl Adds options to 'COPTIONS' if no other action is specified
115dnl
116dnl Notes:
117dnl This is a temporary standin for compiler optimization.
118dnl It should try to match known systems to known compilers (checking, of
119dnl course), and then falling back to some common defaults.
120dnl Note that many compilers will complain about -g and aggressive
121dnl optimization.
122dnl D*/
123AC_DEFUN([PAC_C_OPTIMIZATION],[
124    for copt in "-O4 -Ofast" "-Ofast" "-fast" "-O3" "-xO3" "-O" ; do
125        PAC_C_CHECK_COMPILER_OPTION($copt,found_opt=yes,found_opt=no)
126        if test "$found_opt" = "yes" ; then
127	    ifelse($1,,COPTIONS="$COPTIONS $copt",$1)
128	    break
129        fi
130    done
131    if test "$ac_cv_prog_gcc" = "yes" ; then
132	for copt in "-fomit-frame-pointer" "-finline-functions" \
133		 "-funroll-loops" ; do
134	    PAC_C_CHECK_COMPILER_OPTION($copt,found_opt=yes,found_opt=no)
135	    if test "$found_opt" = "yes" ; then
136	        ifelse($1,,COPTIONS="$COPTIONS $copt",$1)
137	        # no break because we're trying to add them all
138	    fi
139	done
140	# We could also look for architecture-specific gcc options
141    fi
142
143])
144
145dnl/*D
146dnl PAC_PROG_C_UNALIGNED_DOUBLES - Check that the C compiler allows unaligned
147dnl doubles
148dnl
149dnl Synopsis:
150dnl   PAC_PROG_C_UNALIGNED_DOUBLES(action-if-true,action-if-false,
151dnl       action-if-unknown)
152dnl
153dnl Notes:
154dnl 'action-if-unknown' is used in the case of cross-compilation.
155dnl D*/
156AC_DEFUN([PAC_PROG_C_UNALIGNED_DOUBLES],[
157AC_CACHE_CHECK([whether C compiler allows unaligned doubles],
158pac_cv_prog_c_unaligned_doubles,[
159AC_TRY_RUN([
160void fetch_double( v )
161double *v;
162{
163*v = 1.0;
164}
165int main( argc, argv )
166int argc;
167char **argv;
168{
169int p[4];
170double *p_val;
171fetch_double( (double *)&(p[0]) );
172p_val = (double *)&(p[0]);
173if (*p_val != 1.0) return 1;
174fetch_double( (double *)&(p[1]) );
175p_val = (double *)&(p[1]);
176if (*p_val != 1.0) return 1;
177return 0;
178}
179],pac_cv_prog_c_unaligned_doubles="yes",pac_cv_prog_c_unaligned_doubles="no",
180pac_cv_prog_c_unaligned_doubles="unknown")])
181ifelse($1,,,if test "X$pac_cv_prog_c_unaligned_doubles" = "yes" ; then
182$1
183fi)
184ifelse($2,,,if test "X$pac_cv_prog_c_unaligned_doubles" = "no" ; then
185$2
186fi)
187ifelse($3,,,if test "X$pac_cv_prog_c_unaligned_doubles" = "unknown" ; then
188$3
189fi)
190])
191
192dnl/*D
193dnl PAC_PROG_C_WEAK_SYMBOLS - Test whether C supports weak alias symbols.
194dnl
195dnl Synopsis
196dnl PAC_PROG_C_WEAK_SYMBOLS(action-if-true,action-if-false)
197dnl
198dnl Output Effect:
199dnl Defines one of the following if a weak symbol pragma is found:
200dnl.vb
201dnl    HAVE_PRAGMA_WEAK - #pragma weak
202dnl    HAVE_PRAGMA_HP_SEC_DEF - #pragma _HP_SECONDARY_DEF
203dnl    HAVE_PRAGMA_CRI_DUP  - #pragma _CRI duplicate x as y
204dnl.ve
205dnl May also define
206dnl.vb
207dnl    HAVE_WEAK_ATTRIBUTE
208dnl.ve
209dnl if functions can be declared as 'int foo(...) __attribute__ ((weak));'
210dnl sets the shell variable pac_cv_attr_weak to yes.
211dnl Also checks for __attribute__((weak_import)) which is supported by
212dnl Apple in Mac OSX (at least in Darwin).  Note that this provides only
213dnl weak symbols, not weak aliases
214dnl
215dnl D*/
216AC_DEFUN([PAC_PROG_C_WEAK_SYMBOLS],[
217pragma_extra_message=""
218AC_CACHE_CHECK([for type of weak symbol alias support],
219pac_cv_prog_c_weak_symbols,[
220# Test for weak symbol support...
221# We can't put # in the message because it causes autoconf to generate
222# incorrect code
223AC_TRY_LINK([
224extern int PFoo(int);
225#pragma weak PFoo = Foo
226int Foo(int a) { return a; }
227],[return PFoo(1);],has_pragma_weak=yes)
228#
229# Some systems (Linux ia64 and ecc, for example), support weak symbols
230# only within a single object file!  This tests that case.
231# Note that there is an extern int PFoo declaration before the
232# pragma.  Some compilers require this in order to make the weak symbol
233# externally visible.
234if test "$has_pragma_weak" = yes ; then
235    PAC_COMPLINK_IFELSE([
236        AC_LANG_SOURCE([
237extern int PFoo(int);
238#pragma weak PFoo = Foo
239int Foo(int);
240int Foo(int a) { return a; }
241        ])
242    ],[
243        AC_LANG_SOURCE([
244extern int PFoo(int);
245int main(int argc, char **argv) {
246return PFoo(0);}
247        ])
248    ],[
249        PAC_COMPLINK_IFELSE([
250            AC_LANG_SOURCE([
251extern int PFoo(int);
252#pragma weak PFoo = Foo
253int Foo(int);
254int Foo(int a) { return a; }
255            ])
256        ],[
257            AC_LANG_SOURCE([
258extern int Foo(int);
259int PFoo(int a) { return a+1;}
260int main(int argc, char **argv) {
261return Foo(0);}
262            ])
263        ],[
264            pac_cv_prog_c_weak_symbols="pragma weak"
265        ],[
266            has_pragma_weak=0
267            pragma_extra_message="pragma weak accepted but does not work (probably creates two non-weak entries)"
268        ])
269    ],[
270        has_pragma_weak=0
271        pragma_extra_message="pragma weak accepted but does not work (probably creates two non-weak entries)"
272    ])
273fi
274dnl
275if test -z "$pac_cv_prog_c_weak_symbols" ; then
276    AC_TRY_LINK([
277extern int PFoo(int);
278#pragma _HP_SECONDARY_DEF Foo  PFoo
279int Foo(int a) { return a; }
280],[return PFoo(1);],pac_cv_prog_c_weak_symbols="pragma _HP_SECONDARY_DEF")
281fi
282dnl
283if test -z "$pac_cv_prog_c_weak_symbols" ; then
284    AC_TRY_LINK([
285extern int PFoo(int);
286#pragma _CRI duplicate PFoo as Foo
287int Foo(int a) { return a; }
288],[return PFoo(1);],pac_cv_prog_c_weak_symbols="pragma _CRI duplicate x as y")
289fi
290dnl
291if test -z "$pac_cv_prog_c_weak_symbols" ; then
292    pac_cv_prog_c_weak_symbols="no"
293fi
294dnl
295dnl If there is an extra explanatory message, echo it now so that it
296dnl doesn't interfere with the cache result value
297if test -n "$pragma_extra_message" ; then
298    echo $pragma_extra_message
299fi
300dnl
301])
302if test "$pac_cv_prog_c_weak_symbols" != "no" ; then
303    case "$pac_cv_prog_c_weak_symbols" in
304        "pragma weak") AC_DEFINE(HAVE_PRAGMA_WEAK,1,[Supports weak pragma])
305        ;;
306        "pragma _HP")  AC_DEFINE(HAVE_PRAGMA_HP_SEC_DEF,1,[HP style weak pragma])
307        ;;
308        "pragma _CRI") AC_DEFINE(HAVE_PRAGMA_CRI_DUP,1,[Cray style weak pragma])
309        ;;
310    esac
311fi
312AC_CACHE_CHECK([whether __attribute__ ((weak)) allowed],
313pac_cv_attr_weak,[
314AC_TRY_COMPILE([int foo(int) __attribute__ ((weak));],[int a;],
315pac_cv_attr_weak=yes,pac_cv_attr_weak=no)])
316# Note that being able to compile with weak_import doesn't mean that
317# it works.
318AC_CACHE_CHECK([whether __attribute__ ((weak_import)) allowed],
319pac_cv_attr_weak_import,[
320AC_TRY_COMPILE([int foo(int) __attribute__ ((weak_import));],[int a;],
321pac_cv_attr_weak_import=yes,pac_cv_attr_weak_import=no)])
322# Check if the alias option for weak attributes is allowed
323AC_CACHE_CHECK([whether __attribute__((weak,alias(...))) allowed],
324pac_cv_attr_weak_alias,[
325PAC_PUSH_FLAG([CFLAGS])
326# force an error exit if the weak attribute isn't understood
327CFLAGS=-Werror
328AC_TRY_COMPILE([int __foo(int a){return 0;} int foo(int) __attribute__((weak,alias("__foo")));],[int a;],
329pac_cv_attr_weak_alias=yes,pac_cv_attr_weak_alias=no)
330# Restore original CFLAGS
331PAC_POP_FLAG([CFLAGS])])
332if test "$pac_cv_attr_weak_alias" = "yes" ; then
333    AC_DEFINE(HAVE_WEAK_ATTRIBUTE,1,[Attribute style weak pragma])
334fi
335if test "$pac_cv_prog_c_weak_symbols" = "no" -a "$pac_cv_attr_weak_alias" = "no" ; then
336    ifelse([$2],,:,[$2])
337else
338    ifelse([$1],,:,[$1])
339fi
340])
341
342#
343# This is a replacement that checks that FAILURES are signaled as well
344# (later configure macros look for the .o file, not just success from the
345# compiler, but they should not HAVE to
346#
347dnl --- insert 2.52 compatibility here ---
348dnl 2.52 does not have AC_PROG_CC_WORKS
349ifdef([AC_PROG_CC_WORKS],,[AC_DEFUN([AC_PROG_CC_WORKS],)])
350dnl
351AC_DEFUN([PAC_PROG_CC_WORKS],
352[AC_PROG_CC_WORKS
353AC_MSG_CHECKING([whether the C compiler sets its return status correctly])
354AC_LANG_SAVE
355AC_LANG_C
356AC_TRY_COMPILE(,[int a = bzzzt;],notbroken=no,notbroken=yes)
357AC_MSG_RESULT($notbroken)
358if test "$notbroken" = "no" ; then
359    AC_MSG_ERROR([installation or configuration problem: C compiler does not
360correctly set error code when a fatal error occurs])
361fi
362])
363
364dnl/*D
365dnl PAC_PROG_C_MULTIPLE_WEAK_SYMBOLS - Test whether C and the
366dnl linker allow multiple weak symbols.
367dnl
368dnl Synopsis
369dnl PAC_PROG_C_MULTIPLE_WEAK_SYMBOLS(action-if-true,action-if-false)
370dnl
371dnl
372dnl D*/
373AC_DEFUN([PAC_PROG_C_MULTIPLE_WEAK_SYMBOLS],[
374AC_CACHE_CHECK([for multiple weak symbol support],
375pac_cv_prog_c_multiple_weak_symbols,[
376# Test for multiple weak symbol support...
377PAC_COMPLINK_IFELSE([
378    AC_LANG_SOURCE([
379extern int PFoo(int);
380extern int PFoo_(int);
381extern int pfoo_(int);
382#pragma weak PFoo = Foo
383#pragma weak PFoo_ = Foo
384#pragma weak pfoo_ = Foo
385int Foo(int);
386int Foo(a) { return a; }
387    ])
388],[
389    AC_LANG_SOURCE([
390extern int PFoo(int), PFoo_(int), pfoo_(int);
391int main() {
392return PFoo(0) + PFoo_(1) + pfoo_(2);}
393    ])
394],[
395    pac_cv_prog_c_multiple_weak_symbols="yes"
396])
397dnl
398])
399if test "$pac_cv_prog_c_multiple_weak_symbols" = "yes" ; then
400    ifelse([$1],,:,[$1])
401else
402    ifelse([$2],,:,[$2])
403fi
404])
405
406dnl Use the value of enable-strict to update CFLAGS
407dnl pac_cc_strict_flags contains the strict flags.
408dnl
409dnl -std=c89 is used to select the C89 version of the ANSI/ISO C standard.
410dnl As of this writing, many C compilers still accepted only this version,
411dnl not the later C99 version. When all compilers accept C99, this
412dnl should be changed to the appropriate standard level.  Note that we've
413dnl had trouble with gcc 2.95.3 accepting -std=c89 but then trying to
414dnl compile program with a invalid set of options
415dnl (-D __STRICT_ANSI__-trigraphs)
416AC_DEFUN([PAC_CC_STRICT],[
417export enable_strict_done
418if test "$enable_strict_done" != "yes" ; then
419    # make sure we don't add the below flags multiple times
420    enable_strict_done=yes
421
422    # Some comments on strict warning options.
423    # These were added to improve portability
424    #   -Wstack-usage=262144 -- 32 bit FreeBSD did not like the mprobe test
425    #       allocating a big variable on the stack. (See tt#2160).  The "right"
426    #       value requires further investigation; 1 MiB would have at least
427    #       caught #2160 at compile-time, and only two other tests show a
428    #       warning at 256k.
429    #
430    # These were added to reduce warnings:
431    #   -Wno-missing-field-initializers  -- We want to allow a struct to be
432    #       initialized to zero using "struct x y = {0};" and not require
433    #       each field to be initialized individually.
434    #   -Wno-unused-parameter -- For portability, some parameters go unused
435    #	    when we have different implementations of functions for
436    #	    different platforms
437    #   -Wno-unused-label -- We add fn_exit: and fn_fail: on all functions,
438    #	    but fn_fail may not be used if the function doesn't return an
439    #	    error.
440    #   -Wno-sign-compare -- read() and write() return bytes read/written
441    #       as a signed value, but we often compare this to size_t (or
442    #	    msg_sz_t) variables.
443    # These were removed to reduce warnings:
444    #   -Wcast-qual -- Sometimes we need to cast "volatile char*" to
445    #	    "char*", e.g., for memcpy.
446    #   -Wpadded -- We catch struct padding with asserts when we need to
447    #   -Wredundant-decls -- Having redundant declarations is benign and the
448    #	    code already has some.
449    #   -Waggregate-return -- This seems to be a performance-related warning
450    #       aggregate return values are legal in ANSI C, but they may be returned
451    #	    in memory rather than through a register.  We do use aggregate return
452    #	    values, but they are structs of a single basic type (used to enforce
453    #	    type checking for relative vs. absolute ptrs), and with optimization
454    #	    the aggregate value is converted to a scalar.
455    #   -Wdeclaration-after-statement -- This is a C89
456    #       requirement. When compiling with C99, this should be
457    #       disabled.
458    #   -Wfloat-equal -- There are places in hwloc that set a float var to 0, then
459    #       compare it to 0 later to see if it was updated.  Also when using strtod()
460    #       one needs to compare the return value with 0 to see whether a conversion
461    #       was performed.
462    #   -Werror-implicit-function-declaration -- implicit function declarations
463    #       should never be tolerated.  This also ensures that we get quick
464    #       compilation failures rather than later link failures that usually
465    #       come from a function name typo.
466    #   -Wcast-align -- Casting alignment warnings.  This is an
467    #       important check, but is temporarily disabled, since it is
468    #       throwing too many (correct) warnings currently, causing us
469    #       to miss other warnings.
470    #   -Wshorten-64-to-32 -- Bad type-casting warnings.  This is an
471    #       important check, but is temporarily disabled, since it is
472    #       throwing too many (correct) warnings currently, causing us
473    #       to miss other warnings.
474    #
475    # This was removed because it masks important failures (see ticket #2094).
476    # However, since Intel compiler currently does not include -Wtype-limits
477    # in -Wextra, -Wtype-limits was added to handle warnings with the Intel
478    # compiler.
479    #   -Wno-type-limits -- There are places where we compare an unsigned to
480    #	    a constant that happens to be zero e.g., if x is unsigned and
481    #	    MIN_VAL is zero, we'd like to do "MPIR_Assert(x >= MIN_VAL);".
482    #       Note this option is not supported by gcc 4.2.  This needs to be added
483    #	    after most other warning flags, so that we catch a gcc bug on 32-bit
484    #	    that doesn't give a warning that this is unsupported, unless another
485    #	    warning is triggered, and then if gives an error.
486    # the embedded newlines in this string are safe because we evaluate each
487    # argument in the for-loop below and append them to the CFLAGS with a space
488    # as the separator instead
489    pac_common_strict_flags="
490        -Wall
491        -Wextra
492        -Wno-missing-field-initializers
493        -Wstrict-prototypes
494        -Wmissing-prototypes
495        -DGCC_WALL
496        -Wno-unused-parameter
497        -Wno-unused-label
498        -Wshadow
499        -Wmissing-declarations
500        -Wno-long-long
501        -Wundef
502        -Wno-endif-labels
503        -Wpointer-arith
504        -Wbad-function-cast
505        -Wwrite-strings
506        -Wno-sign-compare
507        -Wold-style-definition
508        -Wno-multichar
509        -Wno-deprecated-declarations
510        -Wnested-externs
511        -Winvalid-pch
512        -Wno-pointer-sign
513        -Wvariadic-macros
514        -Wtype-limits
515        -Werror-implicit-function-declaration
516        -Wstack-usage=262144
517        -diag-disable=all
518    "
519
520    if test -z "$1"; then
521        flags=no
522    else
523        flags="`echo $1 | sed -e 's/:/ /g' -e 's/,/ /g'`"
524    fi
525    add_cflags=yes
526    c_std=c99
527    posix_std=2001
528    enable_opt=yes
529    pac_cc_strict_werror=no
530    for flag in ${flags}; do
531        case "$flag" in
532             error)
533                # note: we can't enable -Werror early as it will break many config tests
534                #       Need apply to CFLAGS at the end of configure.
535                pac_cc_strict_werror=yes
536                ;;
537	     stdc89)
538	        c_std=c89
539		;;
540	     stdc99)
541	        c_std=c99
542		;;
543	     stdgnu99)
544	        c_std=gnu99
545		;;
546	     nostdc)
547		c_std=none
548		;;
549	     posix1995)
550		posix_std=1995
551		;;
552	     posix2001)
553		posix_std=2001
554		;;
555	     posix2008)
556		posix_std=2008
557		;;
558	     noposix)
559		posix_std=none
560		;;
561	     opt)
562		enable_opt=yes
563		;;
564	     noopt)
565		enable_opt=no
566		;;
567	     all|yes)
568		# leave the defaults
569	        ;;
570	     no|none)
571		add_cflags=no
572		;;
573	     *)
574		if test -n "$flag" ; then
575		   AC_MSG_WARN([Unrecognized value for enable-strict:$flag])
576		fi
577		;;
578	esac
579    done
580
581    pac_cc_strict_flags=""
582    if test "${add_cflags}" = "yes" ; then
583       # common flags
584       pac_cc_strict_flags="$pac_cc_strict_flags $pac_common_strict_flags"
585
586       # optimization flags
587       if test "${enable_opt}" = "yes" ; then
588	  PAC_APPEND_FLAG([-O2],[pac_cc_strict_flags])
589       fi
590
591       # stdc flags
592       case "${c_std}" in
593	    none)
594		:
595		;;
596	    c89)
597		PAC_APPEND_FLAG([-std=c89],[pac_cc_strict_flags])
598		PAC_APPEND_FLAG([-Wdeclaration-after-statement],[pac_cc_strict_flags])
599		;;
600	    c99)
601		PAC_APPEND_FLAG([-std=c99],[pac_cc_strict_flags])
602		# Use -D_STDC_C99= for Solaris compilers. See
603		# http://lists.gnu.org/archive/html/autoconf/2010-12/msg00059.html
604		# for discussion on why not to use -xc99
605		PAC_APPEND_FLAG([-D_STDC_C99=],[pac_cc_strict_flags])
606		;;
607	    gnu99)
608		PAC_APPEND_FLAG([-std=gnu99],[pac_cc_strict_flags])
609		;;
610	    *)
611		AC_MSG_ERROR([internal error, unexpected C std version: '$c_std'])
612		;;
613       esac
614
615       # posix flags
616       case "${posix_std}" in
617            none) : ;;
618            1995) PAC_APPEND_FLAG([-D_POSIX_C_SOURCE=199506L],[pac_cc_strict_flags]) ;;
619            2001) PAC_APPEND_FLAG([-D_POSIX_C_SOURCE=200112L],[pac_cc_strict_flags]) ;;
620            2008) PAC_APPEND_FLAG([-D_POSIX_C_SOURCE=200809L],[pac_cc_strict_flags]) ;;
621            *)    AC_MSG_ERROR([internal error, unexpected POSIX version: '$posix_std']) ;;
622       esac
623       if test "${posix_std}" != "none" ; then
624           AS_CASE([$host],[*-*-darwin*], [PAC_APPEND_FLAG([-D_DARWIN_C_SOURCE],[pac_cc_strict_flags])])
625       fi
626    fi
627
628    # See if the above options work with the compiler
629    accepted_flags=""
630    for flag in $pac_cc_strict_flags ; do
631        PAC_PUSH_FLAG([CFLAGS])
632	CFLAGS="$CFLAGS $accepted_flags"
633        PAC_C_CHECK_COMPILER_OPTION([$flag],[accepted_flags="$accepted_flags $flag"],)
634        PAC_POP_FLAG([CFLAGS])
635    done
636    pac_cc_strict_flags=$accepted_flags
637fi
638])
639
640dnl/*D
641dnl PAC_ARG_STRICT - Add --enable-strict to configure.
642dnl
643dnl Synopsis:
644dnl PAC_ARG_STRICT
645dnl
646dnl Output effects:
647dnl Adds '--enable-strict' to the command line.
648dnl
649dnl D*/
650AC_DEFUN([PAC_ARG_STRICT],[
651AC_ARG_ENABLE(strict,
652	AC_HELP_STRING([--enable-strict], [Turn on strict compilation testing]),,enable_strict=no)
653PAC_CC_STRICT($enable_strict)
654CFLAGS="$CFLAGS $pac_cc_strict_flags"
655export CFLAGS
656])
657
658dnl Return the integer structure alignment in pac_cv_c_max_integer_align
659dnl Possible values include
660dnl	packed
661dnl	two
662dnl	four
663dnl	eight
664dnl
665dnl In addition, a "Could not determine alignment" and a "error!"
666dnl return is possible.
667AC_DEFUN([PAC_C_MAX_INTEGER_ALIGN],[
668AC_CACHE_CHECK([for max C struct integer alignment],
669pac_cv_c_max_integer_align,[
670AC_TRY_RUN([
671#include <stdio.h>
672#define DBG(a,b,c)
673int main( int argc, char *argv[] )
674{
675    FILE *cf;
676    int is_packed  = 1;
677    int is_two     = 1;
678    int is_four    = 1;
679    int is_eight   = 1;
680    struct { char a; int b; } char_int;
681    struct { char a; short b; } char_short;
682    struct { char a; long b; } char_long;
683    struct { char a; int b; char c; } char_int_char;
684    struct { char a; short b; char c; } char_short_char;
685#ifdef HAVE_LONG_LONG_INT
686    struct { long long int a; char b; } lli_c;
687    struct { char a; long long int b; } c_lli;
688#endif
689    int size, extent, extent2;
690
691    /* assume max integer alignment isn't 8 if we don't have
692     * an eight-byte value :)
693     */
694#ifdef HAVE_LONG_LONG_INT
695    if (sizeof(int) < 8 && sizeof(long) < 8 && sizeof(long long int) < 8)
696	is_eight = 0;
697#else
698    if (sizeof(int) < 8 && sizeof(long) < 8) is_eight = 0;
699#endif
700
701    size = sizeof(char) + sizeof(int);
702    extent = sizeof(char_int);
703    if (size != extent) is_packed = 0;
704    if ( (extent % 2) != 0) is_two = 0;
705    if ( (extent % 4) != 0) is_four = 0;
706    if (sizeof(int) == 8 && (extent % 8) != 0) is_eight = 0;
707    DBG("char_int",size,extent);
708
709    size = sizeof(char) + sizeof(short);
710    extent = sizeof(char_short);
711    if (size != extent) is_packed = 0;
712    if ( (extent % 2) != 0) is_two = 0;
713    if (sizeof(short) == 4 && (extent % 4) != 0) is_four = 0;
714    if (sizeof(short) == 8 && (extent % 8) != 0) is_eight = 0;
715    DBG("char_short",size,extent);
716
717    size = sizeof(char) + sizeof(long);
718    extent = sizeof(char_long);
719    if (size != extent) is_packed = 0;
720    if ( (extent % 2) != 0) is_two = 0;
721    if ( (extent % 4) != 0) is_four = 0;
722    if (sizeof(long) == 8 && (extent % 8) != 0) is_eight = 0;
723    DBG("char_long",size,extent);
724
725#ifdef HAVE_LONG_LONG_INT
726    size = sizeof(char) + sizeof(long long int);
727    extent = sizeof(lli_c);
728    extent2 = sizeof(c_lli);
729    if (size != extent) is_packed = 0;
730    if ( (extent % 2) != 0 && (extent2 % 2) != 0) is_two = 0;
731    if ( (extent % 4) != 0 && (extent2 % 4) != 0) is_four = 0;
732    if (sizeof(long long int) >= 8 && (extent % 8) != 0 && (extent2 % 8) != 0)
733	is_eight = 0;
734#endif
735
736    size = sizeof(char) + sizeof(int) + sizeof(char);
737    extent = sizeof(char_int_char);
738    if (size != extent) is_packed = 0;
739    if ( (extent % 2) != 0) is_two = 0;
740    if ( (extent % 4) != 0) is_four = 0;
741    if (sizeof(int) == 8 && (extent % 8) != 0) is_eight = 0;
742    DBG("char_int_char",size,extent);
743
744    size = sizeof(char) + sizeof(short) + sizeof(char);
745    extent = sizeof(char_short_char);
746    if (size != extent) is_packed = 0;
747    if ( (extent % 2) != 0) is_two = 0;
748    if (sizeof(short) == 4 && (extent % 4) != 0) is_four = 0;
749    if (sizeof(short) == 8 && (extent % 8) != 0) is_eight = 0;
750    DBG("char_short_char",size,extent);
751
752    /* If aligned mod 8, it will be aligned mod 4 */
753    if (is_eight) { is_four = 0; is_two = 0; }
754
755    if (is_four) is_two = 0;
756
757    /* Tabulate the results */
758    cf = fopen( "ctest.out", "w" );
759    if (is_packed + is_two + is_four + is_eight == 0) {
760	fprintf( cf, "Could not determine alignment\n" );
761    }
762    else {
763	if (is_packed + is_two + is_four + is_eight != 1) {
764	    fprintf( cf, "error!\n" );
765	}
766	else {
767	    if (is_packed) fprintf( cf, "packed\n" );
768	    if (is_two) fprintf( cf, "two\n" );
769	    if (is_four) fprintf( cf, "four\n" );
770	    if (is_eight) fprintf( cf, "eight\n" );
771	}
772    }
773    fclose( cf );
774    return 0;
775}],
776pac_cv_c_max_integer_align=`cat ctest.out`,
777pac_cv_c_max_integer_align="unknown",
778pac_cv_c_max_integer_align="$CROSS_ALIGN_STRUCT_INT")
779rm -f ctest.out
780])
781if test -z "$pac_cv_c_max_integer_align" ; then
782    pac_cv_c_max_integer_align="unknown"
783fi
784])
785
786dnl Return the floating point structure alignment in
787dnl pac_cv_c_max_fp_align.
788dnl
789dnl Possible values include:
790dnl	packed
791dnl	two
792dnl	four
793dnl	eight
794dnl     sixteen
795dnl
796dnl In addition, a "Could not determine alignment" and a "error!"
797dnl return is possible.
798AC_DEFUN([PAC_C_MAX_FP_ALIGN],[
799AC_CACHE_CHECK([for max C struct floating point alignment],
800pac_cv_c_max_fp_align,[
801AC_TRY_RUN([
802#include <stdio.h>
803#define DBG(a,b,c)
804int main( int argc, char *argv[] )
805{
806    FILE *cf;
807    int is_packed  = 1;
808    int is_two     = 1;
809    int is_four    = 1;
810    int is_eight   = 1;
811    int is_sixteen = 1;
812    struct { char a; float b; } char_float;
813    struct { float b; char a; } float_char;
814    struct { char a; double b; } char_double;
815    struct { double b; char a; } double_char;
816#ifdef HAVE_LONG_DOUBLE
817    struct { char a; long double b; } char_long_double;
818    struct { long double b; char a; } long_double_char;
819    struct { long double a; int b; char c; } long_double_int_char;
820#endif
821    int size, extent1, extent2;
822
823    size = sizeof(char) + sizeof(float);
824    extent1 = sizeof(char_float);
825    extent2 = sizeof(float_char);
826    if (size != extent1) is_packed = 0;
827    if ( (extent1 % 2) != 0 && (extent2 % 2) != 0) is_two = 0;
828    if ( (extent1 % 4) != 0 && (extent2 % 4) != 0) is_four = 0;
829    if (sizeof(float) == 8 && (extent1 % 8) != 0 && (extent2 % 8) != 0)
830	is_eight = 0;
831    DBG("char_float",size,extent1);
832
833    size = sizeof(char) + sizeof(double);
834    extent1 = sizeof(char_double);
835    extent2 = sizeof(double_char);
836    if (size != extent1) is_packed = 0;
837    if ( (extent1 % 2) != 0 && (extent2 % 2) != 0) is_two = 0;
838    if ( (extent1 % 4) != 0 && (extent2 % 4) != 0) is_four = 0;
839    if (sizeof(double) == 8 && (extent1 % 8) != 0 && (extent2 % 8) != 0)
840	is_eight = 0;
841    DBG("char_double",size,extent1);
842
843#ifdef HAVE_LONG_DOUBLE
844    size = sizeof(char) + sizeof(long double);
845    extent1 = sizeof(char_long_double);
846    extent2 = sizeof(long_double_char);
847    if (size != extent1) is_packed = 0;
848    if ( (extent1 % 2) != 0 && (extent2 % 2) != 0) is_two = 0;
849    if ( (extent1 % 4) != 0 && (extent2 % 4) != 0) is_four = 0;
850    if (sizeof(long double) >= 8 && (extent1 % 8) != 0 && (extent2 % 8) != 0)
851	is_eight = 0;
852    if (sizeof(long double) > 8 && (extent1 % 16) != 0
853	&& (extent2 % 16) != 0) is_sixteen = 0;
854    DBG("char_long-double",size,extent1);
855
856    extent1 = sizeof(long_double_int_char);
857    if ( (extent1 % 2) != 0) is_two = 0;
858    if ( (extent1 % 4) != 0) is_four = 0;
859    if (sizeof(long double) >= 8 && (extent1 % 8) != 0)	is_eight = 0;
860    if (sizeof(long double) > 8 && (extent1 % 16) != 0) is_sixteen = 0;
861#else
862    is_sixteen = 0;
863#endif
864
865    if (is_sixteen) { is_eight = 0; is_four = 0; is_two = 0; }
866
867    if (is_eight) { is_four = 0; is_two = 0; }
868
869    if (is_four) is_two = 0;
870
871    /* Tabulate the results */
872    cf = fopen( "ctest.out", "w" );
873    if (is_packed + is_two + is_four + is_eight + is_sixteen == 0) {
874	fprintf( cf, "Could not determine alignment\n" );
875    }
876    else {
877	if (is_packed + is_two + is_four + is_eight + is_sixteen != 1) {
878	    fprintf( cf, "error!\n" );
879	}
880	else {
881	    if (is_packed) fprintf( cf, "packed\n" );
882	    if (is_two) fprintf( cf, "two\n" );
883	    if (is_four) fprintf( cf, "four\n" );
884	    if (is_eight) fprintf( cf, "eight\n" );
885	    if (is_sixteen) fprintf( cf, "sixteen\n" );
886	}
887    }
888    fclose( cf );
889    return 0;
890}],
891pac_cv_c_max_fp_align=`cat ctest.out`,
892pac_cv_c_max_fp_align="unknown",
893pac_cv_c_max_fp_align="$CROSS_ALIGN_STRUCT_FP")
894rm -f ctest.out
895])
896if test -z "$pac_cv_c_max_fp_align" ; then
897    pac_cv_c_max_fp_align="unknown"
898fi
899])
900
901dnl Return the floating point structure alignment in
902dnl pac_cv_c_max_double_fp_align.
903dnl
904dnl Possible values include:
905dnl	packed
906dnl	two
907dnl	four
908dnl	eight
909dnl
910dnl In addition, a "Could not determine alignment" and a "error!"
911dnl return is possible.
912AC_DEFUN([PAC_C_MAX_DOUBLE_FP_ALIGN],[
913AC_CACHE_CHECK([for max C struct alignment of structs with doubles],
914pac_cv_c_max_double_fp_align,[
915AC_TRY_RUN([
916#include <stdio.h>
917#define DBG(a,b,c)
918int main( int argc, char *argv[] )
919{
920    FILE *cf;
921    int is_packed  = 1;
922    int is_two     = 1;
923    int is_four    = 1;
924    int is_eight   = 1;
925    struct { char a; float b; } char_float;
926    struct { float b; char a; } float_char;
927    struct { char a; double b; } char_double;
928    struct { double b; char a; } double_char;
929    int size, extent1, extent2;
930
931    size = sizeof(char) + sizeof(float);
932    extent1 = sizeof(char_float);
933    extent2 = sizeof(float_char);
934    if (size != extent1) is_packed = 0;
935    if ( (extent1 % 2) != 0 && (extent2 % 2) != 0) is_two = 0;
936    if ( (extent1 % 4) != 0 && (extent2 % 4) != 0) is_four = 0;
937    if (sizeof(float) == 8 && (extent1 % 8) != 0 && (extent2 % 8) != 0)
938	is_eight = 0;
939    DBG("char_float",size,extent1);
940
941    size = sizeof(char) + sizeof(double);
942    extent1 = sizeof(char_double);
943    extent2 = sizeof(double_char);
944    if (size != extent1) is_packed = 0;
945    if ( (extent1 % 2) != 0 && (extent2 % 2) != 0) is_two = 0;
946    if ( (extent1 % 4) != 0 && (extent2 % 4) != 0) is_four = 0;
947    if (sizeof(double) == 8 && (extent1 % 8) != 0 && (extent2 % 8) != 0)
948	is_eight = 0;
949    DBG("char_double",size,extent1);
950
951    if (is_eight) { is_four = 0; is_two = 0; }
952
953    if (is_four) is_two = 0;
954
955    /* Tabulate the results */
956    cf = fopen( "ctest.out", "w" );
957    if (is_packed + is_two + is_four + is_eight == 0) {
958	fprintf( cf, "Could not determine alignment\n" );
959    }
960    else {
961	if (is_packed + is_two + is_four + is_eight != 1) {
962	    fprintf( cf, "error!\n" );
963	}
964	else {
965	    if (is_packed) fprintf( cf, "packed\n" );
966	    if (is_two) fprintf( cf, "two\n" );
967	    if (is_four) fprintf( cf, "four\n" );
968	    if (is_eight) fprintf( cf, "eight\n" );
969	}
970    }
971    fclose( cf );
972    return 0;
973}],
974pac_cv_c_max_double_fp_align=`cat ctest.out`,
975pac_cv_c_max_double_fp_align="unknown",
976pac_cv_c_max_double_fp_align="$CROSS_ALIGN_STRUCT_DOUBLE_FP")
977rm -f ctest.out
978])
979if test -z "$pac_cv_c_max_double_fp_align" ; then
980    pac_cv_c_max_double_fp_align="unknown"
981fi
982])
983AC_DEFUN([PAC_C_MAX_LONGDOUBLE_FP_ALIGN],[
984AC_CACHE_CHECK([for max C struct floating point alignment with long doubles],
985pac_cv_c_max_longdouble_fp_align,[
986AC_TRY_RUN([
987#include <stdio.h>
988#define DBG(a,b,c)
989int main( int argc, char *argv[] )
990{
991    FILE *cf;
992    int is_packed  = 1;
993    int is_two     = 1;
994    int is_four    = 1;
995    int is_eight   = 1;
996    int is_sixteen = 1;
997    struct { char a; long double b; } char_long_double;
998    struct { long double b; char a; } long_double_char;
999    struct { long double a; int b; char c; } long_double_int_char;
1000    int size, extent1, extent2;
1001
1002    size = sizeof(char) + sizeof(long double);
1003    extent1 = sizeof(char_long_double);
1004    extent2 = sizeof(long_double_char);
1005    if (size != extent1) is_packed = 0;
1006    if ( (extent1 % 2) != 0 && (extent2 % 2) != 0) is_two = 0;
1007    if ( (extent1 % 4) != 0 && (extent2 % 4) != 0) is_four = 0;
1008    if (sizeof(long double) >= 8 && (extent1 % 8) != 0 && (extent2 % 8) != 0)
1009	is_eight = 0;
1010    if (sizeof(long double) > 8 && (extent1 % 16) != 0
1011	&& (extent2 % 16) != 0) is_sixteen = 0;
1012    DBG("char_long-double",size,extent1);
1013
1014    extent1 = sizeof(long_double_int_char);
1015    if ( (extent1 % 2) != 0) is_two = 0;
1016    if ( (extent1 % 4) != 0) is_four = 0;
1017    if (sizeof(long double) >= 8 && (extent1 % 8) != 0)	is_eight = 0;
1018    if (sizeof(long double) > 8 && (extent1 % 16) != 0) is_sixteen = 0;
1019
1020    if (is_sixteen) { is_eight = 0; is_four = 0; is_two = 0; }
1021
1022    if (is_eight) { is_four = 0; is_two = 0; }
1023
1024    if (is_four) is_two = 0;
1025
1026    /* Tabulate the results */
1027    cf = fopen( "ctest.out", "w" );
1028    if (is_packed + is_two + is_four + is_eight + is_sixteen == 0) {
1029	fprintf( cf, "Could not determine alignment\n" );
1030    }
1031    else {
1032	if (is_packed + is_two + is_four + is_eight + is_sixteen != 1) {
1033	    fprintf( cf, "error!\n" );
1034	}
1035	else {
1036	    if (is_packed) fprintf( cf, "packed\n" );
1037	    if (is_two) fprintf( cf, "two\n" );
1038	    if (is_four) fprintf( cf, "four\n" );
1039	    if (is_eight) fprintf( cf, "eight\n" );
1040	    if (is_sixteen) fprintf( cf, "sixteen\n" );
1041	}
1042    }
1043    fclose( cf );
1044    return 0;
1045}],
1046pac_cv_c_max_longdouble_fp_align=`cat ctest.out`,
1047pac_cv_c_max_longdouble_fp_align="unknown",
1048pac_cv_c_max_longdouble_fp_align="$CROSS_ALIGN_STRUCT_LONGDOUBLE_FP")
1049rm -f ctest.out
1050])
1051if test -z "$pac_cv_c_max_longdouble_fp_align" ; then
1052    pac_cv_c_max_longdouble_fp_align="unknown"
1053fi
1054])
1055
1056dnl Other tests assume that there is potentially a maximum alignment
1057dnl and that if there is no maximum alignment, or a type is smaller than
1058dnl that value, then we align on the size of the value, with the exception
1059dnl of the "position-based alignment" rules we test for separately.
1060dnl
1061dnl It turns out that these assumptions have fallen short in at least one
1062dnl case, on MacBook Pros, where doubles are aligned on 4-byte boundaries
1063dnl even when long doubles are aligned on 16-byte boundaries. So this test
1064dnl is here specifically to handle this case.
1065dnl
1066dnl Puts result in pac_cv_c_double_alignment_exception.
1067dnl
1068dnl Possible values currently include no and four.
1069dnl
1070AC_DEFUN([PAC_C_DOUBLE_ALIGNMENT_EXCEPTION],[
1071AC_CACHE_CHECK([if double alignment breaks rules, find actual alignment],
1072pac_cv_c_double_alignment_exception,[
1073AC_TRY_RUN([
1074#include <stdio.h>
1075#define DBG(a,b,c)
1076int main( int argc, char *argv[] )
1077{
1078    FILE *cf;
1079    struct { char a; double b; } char_double;
1080    struct { double b; char a; } double_char;
1081    int extent1, extent2, align_4 = 0;
1082
1083    extent1 = sizeof(char_double);
1084    extent2 = sizeof(double_char);
1085
1086    /* we're interested in the largest value, will let separate test
1087     * deal with position-based issues.
1088     */
1089    if (extent1 < extent2) extent1 = extent2;
1090    if ((sizeof(double) == 8) && (extent1 % 8) != 0) {
1091       if (extent1 % 4 == 0) {
1092          align_4 = 1;
1093       }
1094    }
1095
1096    cf = fopen( "ctest.out", "w" );
1097
1098    if (align_4) fprintf( cf, "four\n" );
1099    else fprintf( cf, "no\n" );
1100
1101    fclose( cf );
1102    return 0;
1103}],
1104pac_cv_c_double_alignment_exception=`cat ctest.out`,
1105pac_cv_c_double_alignment_exception="unknown",
1106pac_cv_c_double_alignment_exception="$CROSS_ALIGN_DOUBLE_EXCEPTION")
1107rm -f ctest.out
1108])
1109if test -z "$pac_cv_c_double_alignment_exception" ; then
1110    pac_cv_c_double_alignment_exception="unknown"
1111fi
1112])
1113
1114dnl Test for odd struct alignment rule that only applies max.
1115dnl padding when double value is at front of type.
1116dnl Puts result in pac_cv_c_double_pos_align.
1117dnl
1118dnl Search for "Power alignment mode" for more details.
1119dnl
1120dnl Possible values include yes, no, and unknown.
1121dnl
1122AC_DEFUN([PAC_C_DOUBLE_POS_ALIGN],[
1123AC_CACHE_CHECK([if alignment of structs with doubles is based on position],
1124pac_cv_c_double_pos_align,[
1125AC_TRY_RUN([
1126#include <stdio.h>
1127#define DBG(a,b,c)
1128int main( int argc, char *argv[] )
1129{
1130    FILE *cf;
1131    int padding_varies_by_pos = 0;
1132    struct { char a; double b; } char_double;
1133    struct { double b; char a; } double_char;
1134    int extent1, extent2;
1135
1136    extent1 = sizeof(char_double);
1137    extent2 = sizeof(double_char);
1138    if (extent1 != extent2) padding_varies_by_pos = 1;
1139
1140    cf = fopen( "ctest.out", "w" );
1141    if (padding_varies_by_pos) fprintf( cf, "yes\n" );
1142    else fprintf( cf, "no\n" );
1143
1144    fclose( cf );
1145    return 0;
1146}],
1147pac_cv_c_double_pos_align=`cat ctest.out`,
1148pac_cv_c_double_pos_align="unknown",
1149pac_cv_c_double_pos_align="$CROSS_ALIGN_DOUBLE_POS")
1150rm -f ctest.out
1151])
1152if test -z "$pac_cv_c_double_pos_align" ; then
1153    pac_cv_c_double_pos_align="unknown"
1154fi
1155])
1156
1157dnl Test for odd struct alignment rule that only applies max.
1158dnl padding when long long int value is at front of type.
1159dnl Puts result in pac_cv_c_llint_pos_align.
1160dnl
1161dnl Search for "Power alignment mode" for more details.
1162dnl
1163dnl Possible values include yes, no, and unknown.
1164dnl
1165AC_DEFUN([PAC_C_LLINT_POS_ALIGN],[
1166AC_CACHE_CHECK([if alignment of structs with long long ints is based on position],
1167pac_cv_c_llint_pos_align,[
1168AC_TRY_RUN([
1169#include <stdio.h>
1170#define DBG(a,b,c)
1171int main( int argc, char *argv[] )
1172{
1173    FILE *cf;
1174    int padding_varies_by_pos = 0;
1175#ifdef HAVE_LONG_LONG_INT
1176    struct { char a; long long int b; } char_llint;
1177    struct { long long int b; char a; } llint_char;
1178    int extent1, extent2;
1179
1180    extent1 = sizeof(char_llint);
1181    extent2 = sizeof(llint_char);
1182    if (extent1 != extent2) padding_varies_by_pos = 1;
1183#endif
1184
1185    cf = fopen( "ctest.out", "w" );
1186    if (padding_varies_by_pos) fprintf( cf, "yes\n" );
1187    else fprintf( cf, "no\n" );
1188
1189    fclose( cf );
1190    return 0;
1191}],
1192pac_cv_c_llint_pos_align=`cat ctest.out`,
1193pac_cv_c_llint_pos_align="unknown",
1194pac_cv_c_llint_pos_align="$CROSS_ALIGN_LLINT_POS")
1195rm -f ctest.out
1196])
1197if test -z "$pac_cv_c_llint_pos_align" ; then
1198    pac_cv_c_llint_pos_align="unknown"
1199fi
1200])
1201
1202dnl/*D
1203dnl PAC_FUNC_NEEDS_DECL - Set NEEDS_<funcname>_DECL if a declaration is needed
1204dnl
1205dnl Synopsis:
1206dnl PAC_FUNC_NEEDS_DECL(headerfiles,funcname)
1207dnl
1208dnl Output Effect:
1209dnl Sets 'NEEDS_<funcname>_DECL' if 'funcname' is not declared by the
1210dnl headerfiles.
1211dnl
1212dnl Approach:
1213dnl Attempt to assign library function to function pointer.  If the function
1214dnl is not declared in a header, this will fail.  Use a non-static global so
1215dnl the compiler does not warn about an unused variable.
1216dnl
1217dnl Simply calling the function is not enough because C89 compilers allow
1218dnl calls to implicitly-defined functions.  Re-declaring a library function
1219dnl with an incompatible prototype is also not sufficient because some
1220dnl compilers (notably clang-3.2) only produce a warning in this case.
1221dnl
1222dnl D*/
1223AC_DEFUN([PAC_FUNC_NEEDS_DECL],[
1224AC_CACHE_CHECK([whether $2 needs a declaration],
1225pac_cv_func_decl_$2,[
1226AC_TRY_COMPILE([$1
1227void (*fptr)(void) = (void(*)(void))$2;],[],
1228pac_cv_func_decl_$2=no,pac_cv_func_decl_$2=yes)])
1229if test "$pac_cv_func_decl_$2" = "yes" ; then
1230changequote(<<,>>)dnl
1231define(<<PAC_FUNC_NAME>>, translit(NEEDS_$2_DECL, [a-z *], [A-Z__]))dnl
1232changequote([, ])dnl
1233    AC_DEFINE_UNQUOTED(PAC_FUNC_NAME,1,[Define if $2 needs a declaration])
1234undefine([PAC_FUNC_NAME])
1235fi
1236])
1237
1238dnl PAC_C_GNU_ATTRIBUTE - See if the GCC __attribute__ specifier is allow.
1239dnl Use the following
1240dnl #ifndef HAVE_GCC_ATTRIBUTE
1241dnl #define __attribute__(a)
1242dnl #endif
1243dnl If *not*, define __attribute__(a) as null
1244dnl
1245dnl We start by requiring Gcc.  Some other compilers accept __attribute__
1246dnl but generate warning messages, or have different interpretations
1247dnl (which seems to make __attribute__ just as bad as #pragma)
1248dnl For example, the Intel icc compiler accepts __attribute__ and
1249dnl __attribute__((pure)) but generates warnings for __attribute__((format...))
1250dnl
1251AC_DEFUN([PAC_C_GNU_ATTRIBUTE],[
1252AC_REQUIRE([AC_PROG_CC_GNU])
1253if test "$ac_cv_prog_gcc" = "yes" ; then
1254    AC_CACHE_CHECK([whether __attribute__ allowed],
1255pac_cv_gnu_attr_pure,[
1256AC_TRY_COMPILE([int foo(int) __attribute__ ((pure));],[int a;],
1257pac_cv_gnu_attr_pure=yes,pac_cv_gnu_attr_pure=no)])
1258AC_CACHE_CHECK([whether __attribute__((format)) allowed],
1259pac_cv_gnu_attr_format,[
1260AC_TRY_COMPILE([int foo(char *,...) __attribute__ ((format(printf,1,2)));],[int a;],
1261pac_cv_gnu_attr_format=yes,pac_cv_gnu_attr_format=no)])
1262    if test "$pac_cv_gnu_attr_pure" = "yes" -a "$pac_cv_gnu_attr_format" = "yes" ; then
1263        AC_DEFINE(HAVE_GCC_ATTRIBUTE,1,[Define if GNU __attribute__ is supported])
1264    fi
1265fi
1266])
1267
1268#
1269# determine if the compiler defines a symbol containing the function name
1270#
1271# These tests check not only that the compiler defines some symbol, such
1272# as __FUNCTION__, but that the symbol correctly names the function.
1273#
1274# Defines
1275#   HAVE__FUNC__      (if __func__ defined)
1276#   HAVE_CAP__FUNC__  (if __FUNC__ defined)
1277#   HAVE__FUNCTION__  (if __FUNCTION__ defined)
1278#
1279AC_DEFUN([PAC_CC_FUNCTION_NAME_SYMBOL],[
1280AC_CACHE_CHECK([whether the compiler defines __func__],
1281pac_cv_have__func__,[
1282tmp_am_cross=no
1283AC_RUN_IFELSE([
1284AC_LANG_SOURCE([
1285#include <string.h>
1286int foo(void);
1287int foo(void)
1288{
1289    return (strcmp(__func__, "foo") == 0);
1290}
1291int main(int argc, char ** argv)
1292{
1293    return (foo() ? 0 : 1);
1294}
1295])
1296], pac_cv_have__func__=yes, pac_cv_have__func__=no,tmp_am_cross=yes)
1297if test "$tmp_am_cross" = yes ; then
1298    AC_LINK_IFELSE([
1299    AC_LANG_SOURCE([
1300#include <string.h>
1301int foo(void);
1302int foo(void)
1303{
1304    return (strcmp(__func__, "foo") == 0);
1305}
1306int main(int argc, char ** argv)
1307{
1308    return (foo() ? 0 : 1);
1309}
1310    ])
1311], pac_cv_have__func__=yes, pac_cv_have__func__=no)
1312fi
1313])
1314
1315if test "$pac_cv_have__func__" = "yes" ; then
1316    AC_DEFINE(HAVE__FUNC__,,[define if the compiler defines __func__])
1317fi
1318
1319AC_CACHE_CHECK([whether the compiler defines __FUNC__],
1320pac_cv_have_cap__func__,[
1321tmp_am_cross=no
1322AC_RUN_IFELSE([
1323AC_LANG_SOURCE([
1324#include <string.h>
1325int foo(void);
1326int foo(void)
1327{
1328    return (strcmp(__FUNC__, "foo") == 0);
1329}
1330int main(int argc, char ** argv)
1331{
1332    return (foo() ? 0 : 1);
1333}
1334])
1335], pac_cv_have_cap__func__=yes, pac_cv_have_cap__func__=no,tmp_am_cross=yes)
1336if test "$tmp_am_cross" = yes ; then
1337    AC_LINK_IFELSE([
1338    AC_LANG_SOURCE([
1339#include <string.h>
1340int foo(void);
1341int foo(void)
1342{
1343    return (strcmp(__FUNC__, "foo") == 0);
1344}
1345int main(int argc, char ** argv)
1346{
1347    return (foo() ? 0 : 1);
1348}
1349    ])
1350], pac_cv_have__func__=yes, pac_cv_have__func__=no)
1351fi
1352])
1353
1354if test "$pac_cv_have_cap__func__" = "yes" ; then
1355    AC_DEFINE(HAVE_CAP__FUNC__,,[define if the compiler defines __FUNC__])
1356fi
1357
1358AC_CACHE_CHECK([whether the compiler sets __FUNCTION__],
1359pac_cv_have__function__,[
1360tmp_am_cross=no
1361AC_RUN_IFELSE([
1362AC_LANG_SOURCE([
1363#include <string.h>
1364int foo(void);
1365int foo(void)
1366{
1367    return (strcmp(__FUNCTION__, "foo") == 0);
1368}
1369int main(int argc, char ** argv)
1370{
1371    return (foo() ? 0 : 1);
1372}
1373])
1374], pac_cv_have__function__=yes, pac_cv_have__function__=no,tmp_am_cross=yes)
1375if test "$tmp_am_cross" = yes ; then
1376    AC_LINK_IFELSE([
1377    AC_LANG_SOURCE([
1378#include <string.h>
1379int foo(void);
1380int foo(void)
1381{
1382    return (strcmp(__FUNCTION__, "foo") == 0);
1383}
1384int main(int argc, char ** argv)
1385{
1386    return (foo() ? 0 : 1);
1387}
1388    ])
1389], pac_cv_have__func__=yes, pac_cv_have__func__=no)
1390fi
1391])
1392
1393if test "$pac_cv_have__function__" = "yes" ; then
1394    AC_DEFINE(HAVE__FUNCTION__,,[define if the compiler defines __FUNCTION__])
1395fi
1396
1397])
1398
1399
1400dnl Check structure alignment
1401AC_DEFUN([PAC_STRUCT_ALIGNMENT],[
1402	# Initialize alignment checks
1403	is_packed=1
1404	is_two=1
1405	is_four=1
1406	is_eight=1
1407	is_largest=1
1408
1409	# See if long double exists
1410	AC_TRY_COMPILE(,[long double a;],have_long_double=yes,have_long_double=no)
1411
1412	# Get sizes of regular types
1413	AC_CHECK_SIZEOF(char)
1414	AC_CHECK_SIZEOF(int)
1415	AC_CHECK_SIZEOF(short)
1416	AC_CHECK_SIZEOF(long)
1417	AC_CHECK_SIZEOF(float)
1418	AC_CHECK_SIZEOF(double)
1419	AC_CHECK_SIZEOF(long double)
1420
1421	# char_int comparison
1422	AC_CHECK_SIZEOF(char_int, 0, [typedef struct { char a; int b; } char_int; ])
1423	size=`expr $ac_cv_sizeof_char + $ac_cv_sizeof_int`
1424	extent=$ac_cv_sizeof_char_int
1425	if test "$size" != "$extent" ; then is_packed=0 ; fi
1426	if test "`expr $extent % $ac_cv_sizeof_int`" != "0" ; then is_largest=0 ; fi
1427	if test "`expr $extent % 2`" != "0" ; then is_two=0 ; fi
1428	if test "`expr $extent % 4`" != "0" ; then is_four=0 ; fi
1429	if test "$ac_cv_sizeof_int" = "8" -a "`expr $extent % 8`" != "0" ; then
1430	   is_eight=0
1431	fi
1432
1433	# char_short comparison
1434	AC_CHECK_SIZEOF(char_short, 0, [typedef struct { char a; short b; } char_short; ])
1435	size=`expr $ac_cv_sizeof_char + $ac_cv_sizeof_short`
1436	extent=$ac_cv_sizeof_char_short
1437	if test "$size" != "$extent" ; then is_packed=0 ; fi
1438	if test "`expr $extent % $ac_cv_sizeof_short`" != "0" ; then is_largest=0 ; fi
1439	if test "`expr $extent % 2`" != "0" ; then is_two=0 ; fi
1440	if test "$ac_cv_sizeof_short" = "4" -a "`expr $extent % 4`" != "0" ; then
1441	   is_four=0
1442	fi
1443	if test "$ac_cv_sizeof_short" = "8" -a "`expr $extent % 8`" != "0" ; then
1444	   is_eight=0
1445	fi
1446
1447	# char_long comparison
1448	AC_CHECK_SIZEOF(char_long, 0, [typedef struct { char a; long b; } char_long; ])
1449	size=`expr $ac_cv_sizeof_char + $ac_cv_sizeof_long`
1450	extent=$ac_cv_sizeof_char_long
1451	if test "$size" != "$extent" ; then is_packed=0 ; fi
1452	if test "`expr $extent % $ac_cv_sizeof_long`" != "0" ; then is_largest=0 ; fi
1453	if test "`expr $extent % 2`" != "0" ; then is_two=0 ; fi
1454	if test "`expr $extent % 4`" != "0" ; then is_four=0 ; fi
1455	if test "$ac_cv_sizeof_long" = "8" -a "`expr $extent % 8`" != "0" ; then
1456	   is_eight=0
1457	fi
1458
1459	# char_float comparison
1460	AC_CHECK_SIZEOF(char_float, 0, [typedef struct { char a; float b; } char_float; ])
1461	size=`expr $ac_cv_sizeof_char + $ac_cv_sizeof_float`
1462	extent=$ac_cv_sizeof_char_float
1463	if test "$size" != "$extent" ; then is_packed=0 ; fi
1464	if test "`expr $extent % $ac_cv_sizeof_float`" != "0" ; then is_largest=0 ; fi
1465	if test "`expr $extent % 2`" != "0" ; then is_two=0 ; fi
1466	if test "`expr $extent % 4`" != "0" ; then is_four=0 ; fi
1467	if test "$ac_cv_sizeof_float" = "8" -a "`expr $extent % 8`" != "0" ; then
1468	   is_eight=0
1469	fi
1470
1471	# char_double comparison
1472	AC_CHECK_SIZEOF(char_double, 0, [typedef struct { char a; double b; } char_double; ])
1473	size=`expr $ac_cv_sizeof_char + $ac_cv_sizeof_double`
1474	extent=$ac_cv_sizeof_char_double
1475	if test "$size" != "$extent" ; then is_packed=0 ; fi
1476	if test "`expr $extent % $ac_cv_sizeof_double`" != "0" ; then is_largest=0 ; fi
1477	if test "`expr $extent % 2`" != "0" ; then is_two=0 ; fi
1478	if test "`expr $extent % 4`" != "0" ; then is_four=0 ; fi
1479	if test "$ac_cv_sizeof_double" = "8" -a "`expr $extent % 8`" != "0" ; then
1480	   is_eight=0
1481	fi
1482
1483	# char_long_double comparison
1484	if test "$have_long_double" = "yes"; then
1485	AC_CHECK_SIZEOF(char_long_double, 0, [
1486				       typedef struct {
1487				       	       char a;
1488					       long double b;
1489				       } char_long_double;
1490				       ])
1491	size=`expr $ac_cv_sizeof_char + $ac_cv_sizeof_long_double`
1492	extent=$ac_cv_sizeof_char_long_double
1493	if test "$size" != "$extent" ; then is_packed=0 ; fi
1494	if test "`expr $extent % $ac_cv_sizeof_long_double`" != "0" ; then is_largest=0 ; fi
1495	if test "`expr $extent % 2`" != "0" ; then is_two=0 ; fi
1496	if test "`expr $extent % 4`" != "0" ; then is_four=0 ; fi
1497	if test "$ac_cv_sizeof_long_double" = "8" -a "`expr $extent % 8`" != "0" ; then
1498	   is_eight=0
1499	fi
1500	fi
1501
1502	# char_int_char comparison
1503	AC_CHECK_SIZEOF(char_int_char, 0, [
1504				       typedef struct {
1505				       	       char a;
1506					       int b;
1507					       char c;
1508				       } char_int_char;
1509				       ])
1510	size=`expr $ac_cv_sizeof_char + $ac_cv_sizeof_int + $ac_cv_sizeof_char`
1511	extent=$ac_cv_sizeof_char_int_char
1512	if test "$size" != "$extent" ; then is_packed=0 ; fi
1513	if test "`expr $extent % $ac_cv_sizeof_int`" != "0" ; then is_largest=0 ; fi
1514	if test "`expr $extent % 2`" != "0" ; then is_two=0 ; fi
1515	if test "`expr $extent % 4`" != "0" ; then is_four=0 ; fi
1516	if test "$ac_cv_sizeof_int" = "8" -a "`expr $extent % 8`" != "0" ; then
1517	   is_eight=0
1518	fi
1519
1520	# char_short_char comparison
1521	AC_CHECK_SIZEOF(char_short_char, 0, [
1522				       typedef struct {
1523				       	       char a;
1524					       short b;
1525					       char c;
1526				       } char_short_char;
1527				       ])
1528	size=`expr $ac_cv_sizeof_char + $ac_cv_sizeof_short + $ac_cv_sizeof_char`
1529	extent=$ac_cv_sizeof_char_short_char
1530	if test "$size" != "$extent" ; then is_packed=0 ; fi
1531	if test "`expr $extent % $ac_cv_sizeof_short`" != "0" ; then is_largest=0 ; fi
1532	if test "`expr $extent % 2`" != "0" ; then is_two=0 ; fi
1533	if test "$ac_cv_sizeof_short" = "4" -a "`expr $extent % 4`" != "0" ; then
1534	   is_four=0
1535	fi
1536	if test "$ac_cv_sizeof_short" = "8" -a "`expr $extent % 8`" != "0" ; then
1537	   is_eight=0
1538	fi
1539
1540	# If aligned mod 8, it will be aligned mod 4
1541	if test $is_eight = 1 ; then is_four=0 ; is_two=0 ; fi
1542	if test $is_four = 1 ; then is_two=0 ; fi
1543
1544	# Largest supersedes 8
1545	if test $is_largest = 1 ; then is_eight=0 ; fi
1546
1547	# Find the alignment
1548	if test "`expr $is_packed + $is_largest + $is_two + $is_four + $is_eight`" = "0" ; then
1549	   pac_cv_struct_alignment="unknown"
1550	elif test "`expr $is_packed + $is_largest + $is_two + $is_four + $is_eight`" != "1" ; then
1551	   pac_cv_struct_alignment="unknown"
1552	elif test $is_packed = 1 ; then
1553	   pac_cv_struct_alignment="packed"
1554	elif test $is_largest = 1 ; then
1555	   pac_cv_struct_alignment="largest"
1556	elif test $is_two = 1 ; then
1557	   pac_cv_struct_alignment="two"
1558	elif test $is_four = 1 ; then
1559	   pac_cv_struct_alignment="four"
1560	elif test $is_eight = 1 ; then
1561	   pac_cv_struct_alignment="eight"
1562	fi
1563])
1564dnl
1565dnl PAC_C_MACRO_VA_ARGS
1566dnl
1567dnl will AC_DEFINE([HAVE_MACRO_VA_ARGS]) if the compiler supports C99 variable
1568dnl length argument lists in macros (#define foo(...) bar(__VA_ARGS__))
1569AC_DEFUN([PAC_C_MACRO_VA_ARGS],[
1570    AC_MSG_CHECKING([for variable argument list macro functionality])
1571    AC_LINK_IFELSE([AC_LANG_PROGRAM([
1572        #include <stdio.h>
1573        #define conftest_va_arg_macro(...) printf(__VA_ARGS__)
1574    ],
1575    [conftest_va_arg_macro("a test %d", 3);])],
1576    [AC_DEFINE([HAVE_MACRO_VA_ARGS],[1],[Define if C99-style variable argument list macro functionality])
1577     AC_MSG_RESULT([yes])],
1578    [AC_MSG_RESULT([no])])
1579])dnl
1580
1581# Will AC_DEFINE([HAVE_BUILTIN_EXPECT]) if the compiler supports __builtin_expect.
1582AC_DEFUN([PAC_C_BUILTIN_EXPECT],[
1583AC_MSG_CHECKING([if C compiler supports __builtin_expect])
1584
1585AC_TRY_LINK(, [
1586    return __builtin_expect(1, 1) ? 1 : 0
1587], [
1588    have_builtin_expect=yes
1589    AC_MSG_RESULT([yes])
1590], [
1591    have_builtin_expect=no
1592    AC_MSG_RESULT([no])
1593])
1594if test x$have_builtin_expect = xyes ; then
1595    AC_DEFINE([HAVE_BUILTIN_EXPECT], [1], [Define to 1 if the compiler supports __builtin_expect.])
1596fi
1597])
1598
1599dnl
1600dnl PAC_C_STATIC_ASSERT - Test whether C11 _Static_assert is supported
1601dnl
1602dnl will AC_DEFINE([HAVE_C11__STATIC_ASSERT]) if C11 _Static_assert is supported.
1603dnl
1604AC_DEFUN([PAC_C_STATIC_ASSERT], [
1605    AC_MSG_CHECKING([for C11 _Static_assert functionality])
1606    AC_LINK_IFELSE([AC_LANG_SOURCE([
1607    int main(){
1608        _Static_assert(1, "The impossible happened!");
1609        return 0;
1610    }
1611    ])],[
1612    AC_DEFINE([HAVE_C11__STATIC_ASSERT],[1],[Define if C11 _Static_assert is supported.])
1613    AC_MSG_RESULT([yes])
1614    ],[
1615    AC_MSG_RESULT([no])
1616    ])
1617])
1618
1619dnl
1620dnl PAC_CC_CHECK_TLS - Test for thread local storage support
1621dnl
1622dnl will AC_DEFINE([TLS]) to a compiler supported TLS keyword
1623dnl
1624AC_DEFUN([PAC_CC_CHECK_TLS], [
1625    AC_CACHE_CHECK([for thread local storage], [pac_cv_tls], [
1626    if test -z $pac_cv_tls ; then
1627        AC_LINK_IFELSE([AC_LANG_PROGRAM([_Thread_local int foo=0;],[foo=1])],
1628            [pac_cv_tls=_Thread_local])
1629    fi
1630    if test -z $pac_cv_tls ; then
1631        AC_LINK_IFELSE( [AC_LANG_PROGRAM([__thread int foo=0;],[foo=1])],
1632            [pac_cv_tls=__thread])
1633    fi
1634    if test -z $pac_cv_tls ; then
1635        AC_LINK_IFELSE( [AC_LANG_PROGRAM([__declspec(thread) int foo=0;],[foo=1])],
1636            [pac_cv_tls="__declspec(thread)"])
1637    fi])
1638    if test -z $pac_cv_tls ; then
1639        AC_MSG_WARN([Compiler does not support thread local storage])
1640    else
1641        AC_DEFINE_UNQUOTED([COMPILER_TLS], [$pac_cv_tls], [Defined the keyword for thread-local storage.])
1642    fi
1643])
1644
1645dnl Test whether pointers can be aligned on a int boundary or require
1646dnl a pointer boundary.
1647AC_DEFUN([PAC_CHECK_PTR_ALIGN]), [
1648    AC_MSG_CHECKING([for alignment restrictions on pointers])
1649    AC_TRY_RUN(
1650    changequote(<<,>>)
1651    struct foo { int a; void *b; };
1652    int main() {
1653        int buf[10];
1654        struct foo *p1;
1655        p1=(struct foo*)&buf[0];
1656        p1->b = (void *)0;
1657        p1=(struct foo*)&buf[1];
1658        p1->b = (void *)0;
1659        return 0;
1660    changequote([,])
1661    },pac_cv_pointers_have_int_alignment=yes,pac_cv_pointers_have_int_alignment=no,pac_cv_pointers_have_int_alignment=unknown)
1662
1663    if test "$pac_cv_pointers_have_int_alignment" != "yes" ; then
1664        AC_DEFINE(NEEDS_POINTER_ALIGNMENT_ADJUST,1,[define if pointers must be aligned on pointer boundaries])
1665        AC_MSG_RESULT([pointer])
1666    else
1667        AC_MSG_RESULT([int or better])
1668    fi
1669])
1670
1671dnl PAC_ARG_ATOMIC_PRIMITIVES
1672dnl  - Provide configure option to select atomic primitives. Defaults to auto.
1673AC_DEFUN([PAC_ARG_ATOMIC_PRIMITIVES], [
1674     AC_ARG_WITH([mpl-atomic-primitives],
1675     [  --with-mpl-atomic-primitives=package  Atomic primitives to use. The following is include:
1676        auto - Automatically choose the best one (default)
1677        c11 - C11 atomics
1678        gcc_atomic - GCC atomic builtins
1679        gcc_sync - GCC sync builtins
1680        win - Windows builtins
1681        lock - Mutex-based synchronization
1682        no|none - atomic operations are performed without synchronization
1683     ],,with_mpl_atomic_primitives=auto)])
1684