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