summaryrefslogtreecommitdiffstats
path: root/gl/m4/stdalign.m4
diff options
context:
space:
mode:
Diffstat (limited to 'gl/m4/stdalign.m4')
-rw-r--r--gl/m4/stdalign.m4206
1 files changed, 140 insertions, 66 deletions
diff --git a/gl/m4/stdalign.m4 b/gl/m4/stdalign.m4
index dc297175..885feafd 100644
--- a/gl/m4/stdalign.m4
+++ b/gl/m4/stdalign.m4
@@ -1,20 +1,25 @@
1# Check for alignas and alignof that conform to C23. 1# stdalign.m4
2 2# serial 3
3dnl Copyright 2011-2023 Free Software Foundation, Inc. 3dnl Copyright 2011-2025 Free Software Foundation, Inc.
4dnl This file is free software; the Free Software Foundation 4dnl This file is free software; the Free Software Foundation
5dnl gives unlimited permission to copy and/or distribute it, 5dnl gives unlimited permission to copy and/or distribute it,
6dnl with or without modifications, as long as this notice is preserved. 6dnl with or without modifications, as long as this notice is preserved.
7dnl This file is offered as-is, without any warranty.
8
9# Check for alignas and alignof that conform to C23.
10
11dnl Written by Paul Eggert and Bruno Haible.
7 12
8# Prepare for substituting <stdalign.h> if it is not supported. 13# Prepare for substituting <stdalign.h> if it is not supported.
9 14
10AC_DEFUN([gl_STDALIGN_H], 15AC_DEFUN([gl_ALIGNASOF],
11[ 16[
12 AC_CACHE_CHECK([for alignas and alignof], 17 AC_CACHE_CHECK([for alignas and alignof],
13 [gl_cv_header_working_stdalign_h], 18 [gl_cv_header_working_stdalign_h],
14 [gl_save_CFLAGS=$CFLAGS 19 [gl_saved_CFLAGS=$CFLAGS
15 for gl_working in "yes, keywords" "yes, <stdalign.h> macros"; do 20 for gl_working in "yes, keywords" "yes, <stdalign.h> macros"; do
16 AS_CASE([$gl_working], 21 AS_CASE([$gl_working],
17 [*stdalign.h*], [CFLAGS="$gl_save_CFLAGS -DINCLUDE_STDALIGN_H"]) 22 [*stdalign.h*], [CFLAGS="$gl_saved_CFLAGS -DINCLUDE_STDALIGN_H"])
18 AC_COMPILE_IFELSE( 23 AC_COMPILE_IFELSE(
19 [AC_LANG_PROGRAM( 24 [AC_LANG_PROGRAM(
20 [[#include <stdint.h> 25 [[#include <stdint.h>
@@ -54,85 +59,154 @@ AC_DEFUN([gl_STDALIGN_H],
54 [gl_cv_header_working_stdalign_h=$gl_working], 59 [gl_cv_header_working_stdalign_h=$gl_working],
55 [gl_cv_header_working_stdalign_h=no]) 60 [gl_cv_header_working_stdalign_h=no])
56 61
57 CFLAGS=$gl_save_CFLAGS 62 CFLAGS=$gl_saved_CFLAGS
58 test "$gl_cv_header_working_stdalign_h" != no && break 63 test "$gl_cv_header_working_stdalign_h" != no && break
59 done]) 64 done])
60 65
61 GL_GENERATE_STDALIGN_H=false
62 AS_CASE([$gl_cv_header_working_stdalign_h], 66 AS_CASE([$gl_cv_header_working_stdalign_h],
63 [no],
64 [GL_GENERATE_STDALIGN_H=true],
65 [yes*keyword*], 67 [yes*keyword*],
66 [AC_DEFINE([HAVE_C_ALIGNASOF], [1], 68 [AC_DEFINE([HAVE_C_ALIGNASOF], [1],
67 [Define to 1 if the alignas and alignof keywords work.])]) 69 [Define to 1 if the alignas and alignof keywords work.])])
68 70
69 AC_CHECK_HEADERS_ONCE([stdalign.h])
70
71 dnl The "zz" puts this toward config.h's end, to avoid potential 71 dnl The "zz" puts this toward config.h's end, to avoid potential
72 dnl collisions with other definitions. 72 dnl collisions with other definitions.
73 AH_VERBATIM([zzalignas], 73 AH_VERBATIM([zzalignas],
74[#if !defined HAVE_C_ALIGNASOF && __cplusplus < 201103 && !defined alignof 74[#if !defined HAVE_C_ALIGNASOF \
75# if HAVE_STDALIGN_H 75 && !(defined __cplusplus && 201103 <= __cplusplus) \
76 && !defined alignof
77# if defined HAVE_STDALIGN_H
76# include <stdalign.h> 78# include <stdalign.h>
77# else 79# endif
78 /* Substitute. Keep consistent with gnulib/lib/stdalign.in.h. */ 80
79# ifndef _GL_STDALIGN_H 81/* ISO C23 alignas and alignof for platforms that lack it.
80# define _GL_STDALIGN_H 82
81# undef _Alignas 83 References:
82# undef _Alignof 84 ISO C23 (latest free draft
83# if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \ 85 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf>)
84 || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \ 86 sections 6.5.3.4, 6.7.5, 7.15.
85 && !defined __clang__) \ 87 C++11 (latest free draft
86 || (defined __clang__ && __clang_major__ < 8)) 88 <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf>)
87# ifdef __cplusplus 89 section 18.10. */
88# if (201103 <= __cplusplus || defined _MSC_VER) 90
89# define _Alignof(type) alignof (type) 91/* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment
90# else 92 requirement of a structure member (i.e., slot or field) that is of
91 template <class __t> struct __alignof_helper { char __a; __t __b; }; 93 type TYPE, as an integer constant expression.
92# define _Alignof(type) offsetof (__alignof_helper<type>, __b) 94
93# define _GL_STDALIGN_NEEDS_STDDEF 1 95 This differs from GCC's and clang's __alignof__ operator, which can
94# endif 96 yield a better-performing alignment for an object of that type. For
97 example, on x86 with GCC and on Linux/x86 with clang,
98 __alignof__ (double) and __alignof__ (long long) are 8, whereas
99 alignof (double) and alignof (long long) are 4 unless the option
100 '-malign-double' is used.
101
102 The result cannot be used as a value for an 'enum' constant, if you
103 want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. */
104
105/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023
106 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>.
107 clang versions < 8.0.0 have the same bug.
108 IBM XL C V16.1.0 cc (non-clang) has the same bug. */
109# if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \
110 || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \
111 && !defined __clang__) \
112 || (defined __clang__ && __clang_major__ < 8) \
113 || defined __xlC__)
114# undef/**/_Alignof
115# ifdef __cplusplus
116# if (201103 <= __cplusplus || defined _MSC_VER)
117# define _Alignof(type) alignof (type)
95# else 118# else
119 template <class __t> struct __alignof_helper { char __a; __t __b; };
96# if (defined __GNUC__ && 4 <= __GNUC__) || defined __clang__ 120# if (defined __GNUC__ && 4 <= __GNUC__) || defined __clang__
97# define _Alignof(type) __builtin_offsetof (struct { char __a; type __b; }, __b) 121# define _Alignof(type) __builtin_offsetof (__alignof_helper<type>, __b)
98# else 122# else
99# define _Alignof(type) offsetof (struct { char __a; type __b; }, __b) 123# define _Alignof(type) offsetof (__alignof_helper<type>, __b)
100# define _GL_STDALIGN_NEEDS_STDDEF 1
101# endif 124# endif
125# define _GL_STDALIGN_NEEDS_STDDEF 1
102# endif 126# endif
103# endif 127# else
104# if ! (defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER)) 128# if (defined __GNUC__ && 4 <= __GNUC__) || defined __clang__
105# define alignof _Alignof 129# define _Alignof(type) __builtin_offsetof (struct { char __a; type __b; }, __b)
106# endif 130# else
107# define __alignof_is_defined 1 131# define _Alignof(type) offsetof (struct { char __a; type __b; }, __b)
108# if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 132# define _GL_STDALIGN_NEEDS_STDDEF 1
109# if defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER)
110# define _Alignas(a) alignas (a)
111# elif (!defined __attribute__ \
112 && ((defined __APPLE__ && defined __MACH__ \
113 ? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \
114 : __GNUC__ && !defined __ibmxl__) \
115 || (4 <= __clang_major__) \
116 || (__ia64 && (61200 <= __HP_cc || 61200 <= __HP_aCC)) \
117 || __ICC || 0x590 <= __SUNPRO_C || 0x0600 <= __xlC__))
118# define _Alignas(a) __attribute__ ((__aligned__ (a)))
119# elif 1300 <= _MSC_VER
120# define _Alignas(a) __declspec (align (a))
121# endif 133# endif
122# endif 134# endif
123# if ((defined _Alignas \ 135# endif
124 && !(defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER))) \ 136# if ! (defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER))
125 || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__)) 137# undef/**/alignof
126# define alignas _Alignas 138# define alignof _Alignof
127# endif 139# endif
128# if (defined alignas \ 140
129 || (defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER))) 141/* alignas (A), also known as _Alignas (A), aligns a variable or type
130# define __alignas_is_defined 1 142 to the alignment A, where A is an integer constant expression. For
131# endif 143 example:
132# if _GL_STDALIGN_NEEDS_STDDEF 144
133# include <stddef.h> 145 int alignas (8) foo;
134# endif 146 struct s { int a; int alignas (8) bar; };
135# endif /* _GL_STDALIGN_H */ 147
148 aligns the address of FOO and the offset of BAR to be multiples of 8.
149
150 A should be a power of two that is at least the type's alignment
151 and at most the implementation's alignment limit. This limit is
152 2**28 on typical GNUish hosts, and 2**13 on MSVC. To be portable
153 to MSVC through at least version 10.0, A should be an integer
154 constant, as MSVC does not support expressions such as 1 << 3.
155 To be portable to Sun C 5.11, do not align auto variables to
156 anything stricter than their default alignment.
157
158 The following C23 requirements are not supported here:
159
160 - If A is zero, alignas has no effect.
161 - alignas can be used multiple times; the strictest one wins.
162 - alignas (TYPE) is equivalent to alignas (alignof (TYPE)).
163
164 */
165# if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
166# if defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER)
167# define _Alignas(a) alignas (a)
168# elif (!defined __attribute__ \
169 && ((defined __APPLE__ && defined __MACH__ \
170 ? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \
171 : __GNUC__ && !defined __ibmxl__) \
172 || (4 <= __clang_major__) \
173 || (__ia64 && (61200 <= __HP_cc || 61200 <= __HP_aCC)) \
174 || __ICC || 0x590 <= __SUNPRO_C || 0x0600 <= __xlC__))
175# define _Alignas(a) __attribute__ ((__aligned__ (a)))
176# elif 1300 <= _MSC_VER
177# define _Alignas(a) __declspec (align (a))
178# endif
179# endif
180# if !defined HAVE_STDALIGN_H
181# if ((defined _Alignas \
182 && !(defined __cplusplus \
183 && (201103 <= __cplusplus || defined _MSC_VER))) \
184 || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__ \
185 && !defined __xlC__))
186# define alignas _Alignas
187# endif
188# endif
189
190# if defined _GL_STDALIGN_NEEDS_STDDEF
191# include <stddef.h>
136# endif 192# endif
137#endif]) 193#endif])
138]) 194])
195
196AC_DEFUN([gl_STDALIGN_H],
197[
198 AC_REQUIRE([gl_ALIGNASOF])
199 if test "$gl_cv_header_working_stdalign_h" = no; then
200 GL_GENERATE_STDALIGN_H=true
201 else
202 GL_GENERATE_STDALIGN_H=false
203 fi
204
205 gl_CHECK_NEXT_HEADERS([stdalign.h])
206 if test $ac_cv_header_stdalign_h = yes; then
207 HAVE_STDALIGN_H=1
208 else
209 HAVE_STDALIGN_H=0
210 fi
211 AC_SUBST([HAVE_STDALIGN_H])
212])