]> granicus.if.org Git - postgresql/blob - config/c-compiler.m4
Add a basic atomic ops API abstracting away platform/architecture details.
[postgresql] / config / c-compiler.m4
1 # Macros to detect C compiler features
2 # config/c-compiler.m4
3
4
5 # PGAC_C_SIGNED
6 # -------------
7 # Check if the C compiler understands signed types.
8 AC_DEFUN([PGAC_C_SIGNED],
9 [AC_CACHE_CHECK(for signed types, pgac_cv_c_signed,
10 [AC_TRY_COMPILE([],
11 [signed char c; signed short s; signed int i;],
12 [pgac_cv_c_signed=yes],
13 [pgac_cv_c_signed=no])])
14 if test x"$pgac_cv_c_signed" = xno ; then
15   AC_DEFINE(signed,, [Define to empty if the C compiler does not understand signed types.])
16 fi])# PGAC_C_SIGNED
17
18
19
20 # PGAC_C_INLINE
21 # -------------
22 # Check if the C compiler understands inline functions without being
23 # noisy about unused static inline functions. Some older compilers
24 # understand inline functions (as tested by AC_C_INLINE) but warn about
25 # them if they aren't used in a translation unit.
26 #
27 # This test used to just define an inline function, but some compilers
28 # (notably clang) got too smart and now warn about unused static
29 # inline functions when defined inside a .c file, but not when defined
30 # in an included header. Since the latter is what we want to use, test
31 # to see if the warning appears when the function is in a header file.
32 # Not pretty, but it works.
33 #
34 # Defines: inline, PG_USE_INLINE
35 AC_DEFUN([PGAC_C_INLINE],
36 [AC_C_INLINE
37 AC_CACHE_CHECK([for quiet inline (no complaint if unreferenced)], pgac_cv_c_inline_quietly,
38   [pgac_cv_c_inline_quietly=no
39   if test "$ac_cv_c_inline" != no; then
40     pgac_c_inline_save_werror=$ac_c_werror_flag
41     ac_c_werror_flag=yes
42     AC_LINK_IFELSE([AC_LANG_PROGRAM([#include "$srcdir/config/test_quiet_include.h"],[])],
43                    [pgac_cv_c_inline_quietly=yes])
44     ac_c_werror_flag=$pgac_c_inline_save_werror
45   fi])
46 if test "$pgac_cv_c_inline_quietly" != no; then
47   AC_DEFINE_UNQUOTED([PG_USE_INLINE], 1,
48     [Define to 1 if "static inline" works without unwanted warnings from ]
49     [compilations where static inline functions are defined but not called.])
50 fi
51 ])# PGAC_C_INLINE
52
53
54
55 # PGAC_TYPE_64BIT_INT(TYPE)
56 # -------------------------
57 # Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to
58 # yes or no respectively, and define HAVE_TYPE_64 if yes.
59 AC_DEFUN([PGAC_TYPE_64BIT_INT],
60 [define([Ac_define], [translit([have_$1_64], [a-z *], [A-Z_P])])dnl
61 define([Ac_cachevar], [translit([pgac_cv_type_$1_64], [ *], [_p])])dnl
62 AC_CACHE_CHECK([whether $1 is 64 bits], [Ac_cachevar],
63 [AC_TRY_RUN(
64 [typedef $1 ac_int64;
65
66 /*
67  * These are globals to discourage the compiler from folding all the
68  * arithmetic tests down to compile-time constants.
69  */
70 ac_int64 a = 20000001;
71 ac_int64 b = 40000005;
72
73 int does_int64_work()
74 {
75   ac_int64 c,d;
76
77   if (sizeof(ac_int64) != 8)
78     return 0;                   /* definitely not the right size */
79
80   /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
81   c = a * b;
82   d = (c + b) / b;
83   if (d != a+1)
84     return 0;
85   return 1;
86 }
87 main() {
88   exit(! does_int64_work());
89 }],
90 [Ac_cachevar=yes],
91 [Ac_cachevar=no],
92 [# If cross-compiling, check the size reported by the compiler and
93 # trust that the arithmetic works.
94 AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [sizeof($1) == 8])],
95                   Ac_cachevar=yes,
96                   Ac_cachevar=no)])])
97
98 Ac_define=$Ac_cachevar
99 if test x"$Ac_cachevar" = xyes ; then
100   AC_DEFINE(Ac_define, 1, [Define to 1 if `]$1[' works and is 64 bits.])
101 fi
102 undefine([Ac_define])dnl
103 undefine([Ac_cachevar])dnl
104 ])# PGAC_TYPE_64BIT_INT
105
106
107
108 # PGAC_C_FUNCNAME_SUPPORT
109 # -----------------------
110 # Check if the C compiler understands __func__ (C99) or __FUNCTION__ (gcc).
111 # Define HAVE_FUNCNAME__FUNC or HAVE_FUNCNAME__FUNCTION accordingly.
112 AC_DEFUN([PGAC_C_FUNCNAME_SUPPORT],
113 [AC_CACHE_CHECK(for __func__, pgac_cv_funcname_func_support,
114 [AC_TRY_COMPILE([#include <stdio.h>],
115 [printf("%s\n", __func__);],
116 [pgac_cv_funcname_func_support=yes],
117 [pgac_cv_funcname_func_support=no])])
118 if test x"$pgac_cv_funcname_func_support" = xyes ; then
119 AC_DEFINE(HAVE_FUNCNAME__FUNC, 1,
120           [Define to 1 if your compiler understands __func__.])
121 else
122 AC_CACHE_CHECK(for __FUNCTION__, pgac_cv_funcname_function_support,
123 [AC_TRY_COMPILE([#include <stdio.h>],
124 [printf("%s\n", __FUNCTION__);],
125 [pgac_cv_funcname_function_support=yes],
126 [pgac_cv_funcname_function_support=no])])
127 if test x"$pgac_cv_funcname_function_support" = xyes ; then
128 AC_DEFINE(HAVE_FUNCNAME__FUNCTION, 1,
129           [Define to 1 if your compiler understands __FUNCTION__.])
130 fi
131 fi])# PGAC_C_FUNCNAME_SUPPORT
132
133
134
135 # PGAC_C_STATIC_ASSERT
136 # --------------------
137 # Check if the C compiler understands _Static_assert(),
138 # and define HAVE__STATIC_ASSERT if so.
139 #
140 # We actually check the syntax ({ _Static_assert(...) }), because we need
141 # gcc-style compound expressions to be able to wrap the thing into macros.
142 AC_DEFUN([PGAC_C_STATIC_ASSERT],
143 [AC_CACHE_CHECK(for _Static_assert, pgac_cv__static_assert,
144 [AC_TRY_LINK([],
145 [({ _Static_assert(1, "foo"); })],
146 [pgac_cv__static_assert=yes],
147 [pgac_cv__static_assert=no])])
148 if test x"$pgac_cv__static_assert" = xyes ; then
149 AC_DEFINE(HAVE__STATIC_ASSERT, 1,
150           [Define to 1 if your compiler understands _Static_assert.])
151 fi])# PGAC_C_STATIC_ASSERT
152
153
154
155 # PGAC_C_TYPES_COMPATIBLE
156 # -----------------------
157 # Check if the C compiler understands __builtin_types_compatible_p,
158 # and define HAVE__BUILTIN_TYPES_COMPATIBLE_P if so.
159 #
160 # We check usage with __typeof__, though it's unlikely any compiler would
161 # have the former and not the latter.
162 AC_DEFUN([PGAC_C_TYPES_COMPATIBLE],
163 [AC_CACHE_CHECK(for __builtin_types_compatible_p, pgac_cv__types_compatible,
164 [AC_TRY_COMPILE([],
165 [ int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)]; ],
166 [pgac_cv__types_compatible=yes],
167 [pgac_cv__types_compatible=no])])
168 if test x"$pgac_cv__types_compatible" = xyes ; then
169 AC_DEFINE(HAVE__BUILTIN_TYPES_COMPATIBLE_P, 1,
170           [Define to 1 if your compiler understands __builtin_types_compatible_p.])
171 fi])# PGAC_C_TYPES_COMPATIBLE
172
173
174
175 # PGAC_C_BUILTIN_CONSTANT_P
176 # -------------------------
177 # Check if the C compiler understands __builtin_constant_p(),
178 # and define HAVE__BUILTIN_CONSTANT_P if so.
179 AC_DEFUN([PGAC_C_BUILTIN_CONSTANT_P],
180 [AC_CACHE_CHECK(for __builtin_constant_p, pgac_cv__builtin_constant_p,
181 [AC_TRY_COMPILE([static int x; static int y[__builtin_constant_p(x) ? x : 1];],
182 [],
183 [pgac_cv__builtin_constant_p=yes],
184 [pgac_cv__builtin_constant_p=no])])
185 if test x"$pgac_cv__builtin_constant_p" = xyes ; then
186 AC_DEFINE(HAVE__BUILTIN_CONSTANT_P, 1,
187           [Define to 1 if your compiler understands __builtin_constant_p.])
188 fi])# PGAC_C_BUILTIN_CONSTANT_P
189
190
191
192 # PGAC_C_BUILTIN_UNREACHABLE
193 # --------------------------
194 # Check if the C compiler understands __builtin_unreachable(),
195 # and define HAVE__BUILTIN_UNREACHABLE if so.
196 #
197 # NB: Don't get the idea of putting a for(;;); or such before the
198 # __builtin_unreachable() call.  Some compilers would remove it before linking
199 # and only a warning instead of an error would be produced.
200 AC_DEFUN([PGAC_C_BUILTIN_UNREACHABLE],
201 [AC_CACHE_CHECK(for __builtin_unreachable, pgac_cv__builtin_unreachable,
202 [AC_TRY_LINK([],
203 [__builtin_unreachable();],
204 [pgac_cv__builtin_unreachable=yes],
205 [pgac_cv__builtin_unreachable=no])])
206 if test x"$pgac_cv__builtin_unreachable" = xyes ; then
207 AC_DEFINE(HAVE__BUILTIN_UNREACHABLE, 1,
208           [Define to 1 if your compiler understands __builtin_unreachable.])
209 fi])# PGAC_C_BUILTIN_UNREACHABLE
210
211
212
213 # PGAC_C_VA_ARGS
214 # --------------
215 # Check if the C compiler understands C99-style variadic macros,
216 # and define HAVE__VA_ARGS if so.
217 AC_DEFUN([PGAC_C_VA_ARGS],
218 [AC_CACHE_CHECK(for __VA_ARGS__, pgac_cv__va_args,
219 [AC_TRY_COMPILE([#include <stdio.h>],
220 [#define debug(...) fprintf(stderr, __VA_ARGS__)
221 debug("%s", "blarg");
222 ],
223 [pgac_cv__va_args=yes],
224 [pgac_cv__va_args=no])])
225 if test x"$pgac_cv__va_args" = xyes ; then
226 AC_DEFINE(HAVE__VA_ARGS, 1,
227           [Define to 1 if your compiler understands __VA_ARGS__ in macros.])
228 fi])# PGAC_C_VA_ARGS
229
230
231
232 # PGAC_PROG_CC_CFLAGS_OPT
233 # -----------------------
234 # Given a string, check if the compiler supports the string as a
235 # command-line option. If it does, add the string to CFLAGS.
236 AC_DEFUN([PGAC_PROG_CC_CFLAGS_OPT],
237 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_cflags_$1])])dnl
238 AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar],
239 [pgac_save_CFLAGS=$CFLAGS
240 CFLAGS="$pgac_save_CFLAGS $1"
241 ac_save_c_werror_flag=$ac_c_werror_flag
242 ac_c_werror_flag=yes
243 _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
244                    [Ac_cachevar=yes],
245                    [Ac_cachevar=no])
246 ac_c_werror_flag=$ac_save_c_werror_flag
247 CFLAGS="$pgac_save_CFLAGS"])
248 if test x"$Ac_cachevar" = x"yes"; then
249   CFLAGS="$CFLAGS $1"
250 fi
251 undefine([Ac_cachevar])dnl
252 ])# PGAC_PROG_CC_CFLAGS_OPT
253
254
255
256 # PGAC_PROG_CC_VAR_OPT
257 # -----------------------
258 # Given a variable name and a string, check if the compiler supports
259 # the string as a command-line option. If it does, add the string to
260 # the given variable.
261 AC_DEFUN([PGAC_PROG_CC_VAR_OPT],
262 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_cflags_$2])])dnl
263 AC_CACHE_CHECK([whether $CC supports $2], [Ac_cachevar],
264 [pgac_save_CFLAGS=$CFLAGS
265 CFLAGS="$pgac_save_CFLAGS $2"
266 ac_save_c_werror_flag=$ac_c_werror_flag
267 ac_c_werror_flag=yes
268 _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
269                    [Ac_cachevar=yes],
270                    [Ac_cachevar=no])
271 ac_c_werror_flag=$ac_save_c_werror_flag
272 CFLAGS="$pgac_save_CFLAGS"])
273 if test x"$Ac_cachevar" = x"yes"; then
274   $1="${$1} $2"
275 fi
276 undefine([Ac_cachevar])dnl
277 ])# PGAC_PROG_CC_CFLAGS_OPT
278
279
280
281 # PGAC_PROG_CC_LDFLAGS_OPT
282 # ------------------------
283 # Given a string, check if the compiler supports the string as a
284 # command-line option. If it does, add the string to LDFLAGS.
285 # For reasons you'd really rather not know about, this checks whether
286 # you can link to a particular function, not just whether you can link.
287 # In fact, we must actually check that the resulting program runs :-(
288 AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT],
289 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_ldflags_$1])])dnl
290 AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar],
291 [pgac_save_LDFLAGS=$LDFLAGS
292 LDFLAGS="$pgac_save_LDFLAGS $1"
293 AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $2 (); void (*fptr) () = $2;],[])],
294               [Ac_cachevar=yes],
295               [Ac_cachevar=no],
296               [Ac_cachevar="assuming no"])
297 LDFLAGS="$pgac_save_LDFLAGS"])
298 if test x"$Ac_cachevar" = x"yes"; then
299   LDFLAGS="$LDFLAGS $1"
300 fi
301 undefine([Ac_cachevar])dnl
302 ])# PGAC_PROG_CC_LDFLAGS_OPT
303
304 # PGAC_HAVE_GCC__SYNC_CHAR_TAS
305 # -------------------------
306 # Check if the C compiler understands __sync_lock_test_and_set(char),
307 # and define HAVE_GCC__SYNC_CHAR_TAS
308 #
309 # NB: There are platforms where test_and_set is available but compare_and_swap
310 # is not, so test this separately.
311 # NB: Some platforms only do 32bit tas, others only do 8bit tas. Test both.
312 AC_DEFUN([PGAC_HAVE_GCC__SYNC_CHAR_TAS],
313 [AC_CACHE_CHECK(for builtin __sync char locking functions, pgac_cv_gcc_sync_char_tas,
314 [AC_TRY_LINK([],
315   [char lock = 0;
316    __sync_lock_test_and_set(&lock, 1);
317    __sync_lock_release(&lock);],
318   [pgac_cv_gcc_sync_char_tas="yes"],
319   [pgac_cv_gcc_sync_char_tas="no"])])
320 if test x"$pgac_cv_gcc_sync_char_tas" = x"yes"; then
321   AC_DEFINE(HAVE_GCC__SYNC_CHAR_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(char *) and friends.])
322 fi])# PGAC_HAVE_GCC__SYNC_CHAR_TAS
323
324 # PGAC_HAVE_GCC__SYNC_INT32_TAS
325 # -------------------------
326 # Check if the C compiler understands __sync_lock_test_and_set(),
327 # and define HAVE_GCC__SYNC_INT32_TAS
328 AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_TAS],
329 [AC_CACHE_CHECK(for builtin __sync int32 locking functions, pgac_cv_gcc_sync_int32_tas,
330 [AC_TRY_LINK([],
331   [int lock = 0;
332    __sync_lock_test_and_set(&lock, 1);
333    __sync_lock_release(&lock);],
334   [pgac_cv_gcc_sync_int32_tas="yes"],
335   [pgac_cv_gcc_sync_int32_tas="no"])])
336 if test x"$pgac_cv_gcc_sync_int32_tas" = x"yes"; then
337   AC_DEFINE(HAVE_GCC__SYNC_INT32_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(int *) and friends.])
338 fi])# PGAC_HAVE_GCC__SYNC_INT32_TAS
339
340 # PGAC_HAVE_GCC__SYNC_INT32_CAS
341 # -------------------------
342 # Check if the C compiler understands __sync_compare_and_swap() for 32bit
343 # types, and define HAVE_GCC__SYNC_INT32_CAS if so.
344 AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_CAS],
345 [AC_CACHE_CHECK(for builtin __sync int32 atomic operations, pgac_cv_gcc_sync_int32_cas,
346 [AC_TRY_LINK([],
347   [int val = 0;
348    __sync_val_compare_and_swap(&val, 0, 37);],
349   [pgac_cv_gcc_sync_int32_cas="yes"],
350   [pgac_cv_gcc_sync_int32_cas="no"])])
351 if test x"$pgac_cv_gcc_sync_int32_cas" = x"yes"; then
352   AC_DEFINE(HAVE_GCC__SYNC_INT32_CAS, 1, [Define to 1 if you have __sync_compare_and_swap(int *, int, int).])
353 fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS
354
355 # PGAC_HAVE_GCC__SYNC_INT64_CAS
356 # -------------------------
357 # Check if the C compiler understands __sync_compare_and_swap() for 64bit
358 # types, and define HAVE_GCC__SYNC_INT64_CAS if so.
359 AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS],
360 [AC_CACHE_CHECK(for builtin __sync int64 atomic operations, pgac_cv_gcc_sync_int64_cas,
361 [AC_TRY_LINK([],
362   [PG_INT64_TYPE lock = 0;
363    __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);],
364   [pgac_cv_gcc_sync_int64_cas="yes"],
365   [pgac_cv_gcc_sync_int64_cas="no"])])
366 if test x"$pgac_cv_gcc_sync_int64_cas" = x"yes"; then
367   AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_compare_and_swap(int64 *, int64, int64).])
368 fi])# PGAC_HAVE_GCC__SYNC_INT64_CAS
369
370 # PGAC_HAVE_GCC__ATOMIC_INT32_CAS
371 # -------------------------
372 # Check if the C compiler understands __atomic_compare_exchange_n() for 32bit
373 # types, and define HAVE_GCC__ATOMIC_INT32_CAS if so.
374 AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT32_CAS],
375 [AC_CACHE_CHECK(for builtin __atomic int32 atomic operations, pgac_cv_gcc_atomic_int32_cas,
376 [AC_TRY_LINK([],
377   [int val = 0;
378    int expect = 0;
379    __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);],
380   [pgac_cv_gcc_atomic_int32_cas="yes"],
381   [pgac_cv_gcc_atomic_int32_cas="no"])])
382 if test x"$pgac_cv_gcc_atomic_int32_cas" = x"yes"; then
383   AC_DEFINE(HAVE_GCC__ATOMIC_INT32_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int).])
384 fi])# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
385
386 # PGAC_HAVE_GCC__ATOMIC_INT64_CAS
387 # -------------------------
388 # Check if the C compiler understands __atomic_compare_exchange_n() for 64bit
389 # types, and define HAVE_GCC__ATOMIC_INT64_CAS if so.
390 AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS],
391 [AC_CACHE_CHECK(for builtin __atomic int64 atomic operations, pgac_cv_gcc_atomic_int64_cas,
392 [AC_TRY_LINK([],
393   [PG_INT64_TYPE val = 0;
394    PG_INT64_TYPE expect = 0;
395    __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);],
396   [pgac_cv_gcc_atomic_int64_cas="yes"],
397   [pgac_cv_gcc_atomic_int64_cas="no"])])
398 if test x"$pgac_cv_gcc_atomic_int64_cas" = x"yes"; then
399   AC_DEFINE(HAVE_GCC__ATOMIC_INT64_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int64 *, int *, int64).])
400 fi])# PGAC_HAVE_GCC__ATOMIC_INT64_CAS