]> git.draconx.ca Git - dxcommon.git/blob - m4/align.m4
DX_C_ALIGNAS: Work around bash-5 parsing bug.
[dxcommon.git] / m4 / align.m4
1 # Copyright © 2024 Nick Bowler
2 #
3 # License WTFPL2: Do What The Fuck You Want To Public License, version 2.
4 # This is free software: you are free to do what the fuck you want to.
5 # There is NO WARRANTY, to the extent permitted by law.
6
7 # DX_C_ALIGNOF
8 #
9 # Probe whether the C compiler understands _Alignof(T).
10 #
11 # Some implementations (e.g., FreeBSD 9) define a usable _Alignof macro
12 # in <stddef.h> (and other headers), so we can use that if available.
13 #
14 # If not supported, _Alignof(T) is defined as a function-like macro which
15 # uses offsetof to guess the alignment of T, which must be a type such that
16 # T x; is a valid declaration of x as an object of type T.
17 #
18 # For these reasons, callers should #include <stddef.h> before using _Alignof.
19 #
20 # We skip the test if Autoconf has previously determined that the C compiler
21 # supports C11 or a newer standard, since the C11 test program checks this.
22 #
23 # Annoyingly, autoconf-2.71 removed the assignment of ac_cv_prog_cc_c11,
24 # even though this was actual documented behaviour...
25 AC_DEFUN([DX_C_ALIGNOF],
26 [AS_CASE([${ac_cv_prog_cc_c11-no}/${ac_prog_cc_stdc-no}],
27   [no/no|*/c89|*/c99],
28     [AC_CACHE_CHECK([if $CC supports _Alignof], [dx_cv_have_alignof],
29       [AC_COMPUTE_INT([_dx_tmp], [_Alignof(char)], [#include <stddef.h>
30 ], [_dx_tmp=0])
31 AS_CASE([$_dx_tmp], [1], [dx_cv_have_alignof=yes], [dx_cv_have_alignof=no])])],
32   [dx_cv_have_alignof=yes])
33 AS_CASE([$dx_cv_have_alignof], [no], [AC_DEFINE([_Alignof(T)],
34   [offsetof(struct { char a; T b; }, b)],
35   [Define _Alignof(T) to a suitable fallback if _Alignof is unsupported.])])])
36
37 # DX_C_ALIGNAS
38 #
39 # Probe whether the C compiler understands _Alignas(X).
40 #
41 # Some implementations (e.g., FreeBSD 9) define a usable _Alignas macro
42 # in <stddef.h> (and other headers), so we can use that if available.  For
43 # this reason, callers should #include <stddef.h> before using _Alignas.
44 #
45 # If not supported, but the compiler supports the GNU __attribute__ or
46 # Microsoft __declspec methods to set alignment, _Alignas(X) is defined
47 # as a function-like macro which expands to such syntax.  These only
48 # work if X is an integer constant (as opposed to a type name).
49 #
50 # If there is no known method of declaring a variable with increased
51 # alignment, then _Alignas(X) is defined as a function-like macro which
52 # expands to nothing, which will compile but has no runtime effect.
53 #
54 # We skip the test if Autoconf has previously determined that the C
55 # compiler supports C11 or a newer standard, since the C11 test program
56 # checks this.
57 AC_DEFUN([DX_C_ALIGNAS],
58 [AS_CASE([${ac_cv_prog_cc_c11-no}/${ac_prog_cc_stdc-no}],
59   [no/no|*/c89|*/c99],
60     [AC_CACHE_CHECK([if $CC supports _Alignas], [dx_cv_have_alignas],
61 [dx_cv_have_alignas=no
62 for _dx_alignas dnl Eat newline to work around bash-5 parsing bug.
63 in '_Alignas(X)' '__attribute__((__aligned__(X)))' '__declspec(align(X))'
64 do
65 AC_COMPUTE_INT([_dx_tmp],
66   [sizeof (struct { char a; char ALIGNAS_TEST(4) b; }) >= 8],
67   [#include <stddef.h>
68 #define ALIGNAS_TEST(X) $_dx_alignas
69 ],[_dx_tmp=0])
70 AS_CASE([$_dx_tmp/$_dx_alignas],
71   [1/_Alignas*], [dx_cv_have_alignas=yes; break],
72   [1/*], [dx_cv_have_alignas=$_dx_alignas; break])
73 done])],
74   [dx_cv_have_alignas=yes])
75 AS_CASE([$dx_cv_have_alignas],
76   [*'(X)'*], [AC_DEFINE_UNQUOTED([_Alignas(X)], [$dx_cv_have_alignas],
77     [Define _Alignas(X) to a suitable fallback if _Alignas is unsupported.])],
78   [no], [AC_DEFINE([_Alignas(X)], [/**/])])])