1 /* Verify that __builtin_has_attribute detects attributes aligned
2 and packed in various forms of array dereferencing and indirection
3 expressions correspondingly to __alignof__.
5 { dg-options "-Wall -Wno-unused -ftrack-macro-expansion=0" }
6 { dg-require-effective-target size24plus } */
8 #define ATTR(...) __attribute__ ((__VA_ARGS__))
9 #define ALIGN(N) ATTR (aligned (N))
11 #define Assert(expr) typedef int _Assert [1 - 2 * !(expr)]
13 /* Verify that __builtin_has_attribute (EXPR, align (ALIGN)) returns
14 the EXPECTed result. When EXPECT is true, verify that the EXPression
15 has the expected ALIGNment. */
16 #define A3(expect, expr, align) do { \
17 Assert (!expect || __alignof__ (expr) == align); \
18 Assert (expect == __builtin_has_attribute (expr, aligned (align))); \
21 #define A(expect, expr) \
22 Assert (expect == __builtin_has_attribute (expr, aligned)) \
24 enum { PA = __alignof__ (void*) };
26 /* Define pointer to pointer types, with different alignments
27 at each level of indirection. */
28 typedef struct S8
{ char a
[8]; } S8
;
29 typedef ALIGN (8) S8 I8
;
30 typedef ALIGN (16) I8
*P16_I8
;
31 typedef P16_I8
*P_P16_I8
;
32 typedef ALIGN (32) P_P16_I8
*P32_P_P16_I8
;
33 typedef P32_P_P16_I8
*P_P32_P_P16_I8
;
34 typedef ALIGN (64) P_P32_P_P16_I8
*P64_P_P32_P_P16_I8
;
36 Assert ( 8 == __alignof__ (I8
));
37 Assert (16 == __alignof__ (P16_I8
));
38 Assert (PA
== __alignof__ (P_P16_I8
));
39 Assert (32 == __alignof__ (P32_P_P16_I8
));
40 Assert (PA
== __alignof__ (P_P32_P_P16_I8
));
41 Assert (64 == __alignof__ (P64_P_P32_P_P16_I8
));
44 /* Similar to the pointer of pointers above, define array of array
45 types, with different alignments at each level of indirection. */
46 typedef struct S64
{ char a
[64]; } S64
;
47 typedef ALIGN (64) S64 I64
;
48 typedef ALIGN (32) I64 A32_I64
[3];
49 typedef A32_I64 A_A32_I64
[5];
50 typedef ALIGN (16) A_A32_I64 A16_A_A32_I64
[7];
51 typedef A16_A_A32_I64 A_A16_A_A32_I64
[11];
52 typedef ALIGN (8) A_A16_A_A32_I64 A8_A_A16_A_A32_I64
[13];
54 Assert (64 == __alignof__ (I64
));
55 Assert (32 == __alignof__ (A32_I64
));
56 /* With no explicit alignment, an array of overaligned elements
57 is considered to have the alignment of its elements. */
58 Assert (32 == __alignof__ (A_A32_I64
));
59 Assert (16 == __alignof__ (A16_A_A32_I64
));
60 Assert (16 == __alignof__ (A_A16_A_A32_I64
));
61 Assert ( 8 == __alignof__ (A8_A_A16_A_A32_I64
));
64 void test_arrays (void)
66 /* Verify that the aligned attribute on each of the composite types
67 is detected corresponding to the result of __alignof__. */
68 A (1, (*(A8_A_A16_A_A32_I64
*)0));
69 A3 (1, (*(A8_A_A16_A_A32_I64
*)0), 8);
70 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0], 8);
71 /* GCC propagates the user-align bit from element types to their
72 arrays but it doesn't propagate the attribute itself. The built-in
73 considers both the bit and the attribute so it succeeds below even
74 though the referenced type isn't declared with the attribute. */
75 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0], 8);
76 A3 (1, (*(A8_A_A16_A_A32_I64
*)0)[0], 16);
77 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0], 32);
78 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0][1], 8);
79 A3 (1, (*(A8_A_A16_A_A32_I64
*)0)[0][1], 16);
80 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0][1], 32);
81 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0][1][2], 16);
82 A3 (1, (*(A8_A_A16_A_A32_I64
*)0)[0][1][2], 32);
83 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0][1][2], 64);
84 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0][1][2][3], 16);
85 A3 (1, (*(A8_A_A16_A_A32_I64
*)0)[0][1][2][3], 32);
86 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0][1][2][3], 64);
87 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0][1][2][3][4], 32);
88 A3 (1, (*(A8_A_A16_A_A32_I64
*)0)[0][1][2][3][4], 64);
89 A3 (0, (*(A8_A_A16_A_A32_I64
*)0)[0][1][2][3][4], 128);
98 A3 (0, a
[0][1][2], 16);
99 A3 (1, a
[0][1][2], 32);
100 A3 (0, a
[0][1][2], 64);
101 A3 (0, a
[0][1][2][3], 16);
102 A3 (1, a
[0][1][2][3], 32);
103 A3 (0, a
[0][1][2][3], 64);
104 A3 (0, a
[0][1][2][3][4], 32);
105 A3 (1, a
[0][1][2][3][4], 64);
106 A3 (0, a
[0][1][2][3][4], 128);
109 void test_pointers (void)
111 /* Verify that the aligned attribute on each of the composite pointer
112 types is detected corresponding to the result of __alignof__. */
123 A3 (0, P_P16_I8
, 16);
126 A3 (0, P32_P_P16_I8
, 8);
127 A3 (0, P32_P_P16_I8
, 16);
128 A3 (1, P32_P_P16_I8
, 32);
130 A (0, P_P32_P_P16_I8
);
132 A (1, P64_P_P32_P_P16_I8
);
133 A3 (0, P64_P_P32_P_P16_I8
, 8);
134 A3 (0, P64_P_P32_P_P16_I8
, 16);
135 A3 (0, P64_P_P32_P_P16_I8
, 32);
136 A3 (1, P64_P_P32_P_P16_I8
, 64);
139 /* Verify that the attribute on each of the composite types is detected
140 in the type of each of the indirection expressions. */
142 A3 (1, *(P16_I8
)0, 8);
143 A3 (0, *(P16_I8
)0, 16);
146 A3 (0, *(P_P16_I8
)0, 8);
147 A3 (1, *(P_P16_I8
)0, 16);
149 A (0, *(P32_P_P16_I8
)0);
150 A3 (0, *(P32_P_P16_I8
)0, 8);
151 A3 (0, *(P32_P_P16_I8
)0, 16);
152 A3 (0, *(P32_P_P16_I8
)0, 32);
154 A (1, *(P_P32_P_P16_I8
)0);
155 A3 (1, *(P_P32_P_P16_I8
)0, 32);
157 A (0, *(P64_P_P32_P_P16_I8
)0);
159 /* Verify that the attribute on each of the composite types is detected
160 in the type of each of the subscipting expressions. */
161 A (1, ((P16_I8
)0)[0]);
162 A3 (1, ((P16_I8
)0)[1], 8);
163 A3 (0, ((P16_I8
)0)[2], 16);
165 A (1, ((P_P16_I8
)0)[3]);
166 A3 (0, ((P_P16_I8
)0)[4], 8);
167 A3 (1, ((P_P16_I8
)0)[5], 16);
169 A (0, ((P32_P_P16_I8
)0)[6]);
170 A3 (0, ((P32_P_P16_I8
)0)[7], 8);
171 A3 (0, ((P32_P_P16_I8
)0)[8], 16);
172 A3 (0, ((P32_P_P16_I8
)0)[9], 32);
174 A (1, ((P_P32_P_P16_I8
)0)[10]);
175 A3 (1, ((P_P32_P_P16_I8
)0)[11], 32);
177 A (0, ((P64_P_P32_P_P16_I8
)0)[12]);
180 /* Verify that the attribute on each of the composite types is detected
181 in the type of each of the subscipting expression involving variables. */
185 P_P16_I8 p_p16_i8
= &p16_i8
;
186 P32_P_P16_I8 p32_p_p16_i8
= &p_p16_i8
;
187 P_P32_P_P16_I8 p_p32_p_p16_i8
= &p32_p_p16_i8
;
188 P64_P_P32_P_P16_I8 p64_p_p32_p_p16_i8
= &p_p32_p_p16_i8
;
191 A3 (1, p16_i8
[1], 8);
192 A3 (0, p16_i8
[2], 16);
195 A3 (0, p_p16_i8
[4], 8);
196 A3 (1, p_p16_i8
[5], 16);
198 A (0, p32_p_p16_i8
[6]);
199 A3 (0, p32_p_p16_i8
[7], 8);
200 A3 (0, p32_p_p16_i8
[8], 16);
201 A3 (0, p32_p_p16_i8
[9], 32);
203 A (1, p_p32_p_p16_i8
[10]);
204 A3 (1, p_p32_p_p16_i8
[11], 32);
207 A (1, p_p16_i8
[0][1]);
208 A3 (1, p_p16_i8
[1][2], 8);
209 A3 (0, p_p16_i8
[2][3], 16);
212 A (0, p64_p_p32_p_p16_i8
[0]);
214 A (1, p64_p_p32_p_p16_i8
[0][1]);
215 A3 (0, p64_p_p32_p_p16_i8
[0][2], 16);
216 A3 (1, p64_p_p32_p_p16_i8
[0][3], 32);
217 A3 (0, p64_p_p32_p_p16_i8
[0][4], 64);
219 A (0, p64_p_p32_p_p16_i8
[0][1][2]);
221 A (1, p64_p_p32_p_p16_i8
[0][1][2][3]);
222 A3 (0, p64_p_p32_p_p16_i8
[0][1][2][4], 8);
223 A3 (1, p64_p_p32_p_p16_i8
[0][1][2][4], 16);
224 A3 (0, p64_p_p32_p_p16_i8
[0][1][2][4], 32);
226 A (1, p64_p_p32_p_p16_i8
[0][1][2][3][4]);
227 A3 (1, p64_p_p32_p_p16_i8
[0][1][2][3][5], 8);
228 A3 (0, p64_p_p32_p_p16_i8
[0][1][2][4][6], 16);
231 /* Same as above but using the indirection expression. */
232 A (0, *p64_p_p32_p_p16_i8
);
234 A (1, **p64_p_p32_p_p16_i8
);
235 A3 (0, **p64_p_p32_p_p16_i8
, 16);
236 A3 (1, **p64_p_p32_p_p16_i8
, 32);
237 A3 (0, **p64_p_p32_p_p16_i8
, 64);
239 A (0, ***p64_p_p32_p_p16_i8
);
241 A (1, ****p64_p_p32_p_p16_i8
);
242 A3 (0, ****p64_p_p32_p_p16_i8
, 8);
243 A3 (1, ****p64_p_p32_p_p16_i8
, 16);
244 A3 (0, ****p64_p_p32_p_p16_i8
, 32);
246 A (1, *****p64_p_p32_p_p16_i8
);
247 A3 (1, *****p64_p_p32_p_p16_i8
, 8);
248 A3 (0, *****p64_p_p32_p_p16_i8
, 16);
254 P16_I8
f_P16_I8 (void);
255 P_P16_I8
f_P_P16_I8 (void);
256 P32_P_P16_I8
f_P32_P_P16_I8 (void);
257 P_P32_P_P16_I8
f_P_P32_P_P16_I8 (void);
258 P64_P_P32_P_P16_I8
f_P64_P_P32_P_P16_I8 (void);
260 void test_function_call (void)
262 /* Verify that the aligned attribute on each of the composite pointer
263 types returned by the functions is detected corresponding to
264 the result of __alignof__. */
273 A3 (0, f_P16_I8 (), 8);
274 A3 (1, f_P16_I8 (), 16);
275 A3 (0, f_P16_I8 (), 32);
278 A3 (1, *f_P16_I8 (), 8);
279 A3 (0, *f_P16_I8 (), 16);
281 A (0, f_P_P16_I8 ());
283 A (1, *f_P_P16_I8 ());
284 A3 (0, *f_P_P16_I8 (), 8);
285 A3 (1, *f_P_P16_I8 (), 16);
286 A3 (0, *f_P_P16_I8 (), 32);
288 A (1, **f_P_P16_I8 ());
289 A3 (1, **f_P_P16_I8 (), 8);
290 A3 (0, **f_P_P16_I8 (), 16);
291 A3 (0, **f_P_P16_I8 (), 32);
295 void test_compound_literal (void)
305 A3 (0, (I64
){ }, 16);
306 A3 (0, (I64
){ }, 32);
307 A3 (1, (I64
){ }, 64);
309 A (1, (A32_I64
){ 0 });
310 A3 (0, (A32_I64
){ 0 }, 8);
311 A3 (0, (A32_I64
){ 0 }, 16);
312 A3 (1, (A32_I64
){ 0 }, 32);
313 A3 (0, (A32_I64
){ 0 }, 64);
315 A (1, ((A32_I64
){ 0 })[0]);
316 A3 (0, ((A32_I64
){ 0 })[0], 8);
317 A3 (0, ((A32_I64
){ 0 })[0], 16);
318 A3 (0, ((A32_I64
){ 0 })[0], 32);
319 A3 (1, ((A32_I64
){ 0 })[0], 64);
323 void test_ternary_expression (int i
)
325 A (0, (0 ? (S8
){ } : (S8
){ }));
327 A (1, (1 ? (I8
){ } : (I8
){ }));
328 A3 (1, (2 ? (I8
){ } : (I8
){ }), 8);
329 A3 (0, (3 ? (I8
){ } : (I8
){ }), 16);
331 A (1, (4 ? (I64
){ } : (I64
){ }));
332 A3 (0, (5 ? (I64
){ } : (I64
){ }), 8);
333 A3 (0, (6 ? (I64
){ } : (I64
){ }), 16);
334 A3 (0, (7 ? (I64
){ } : (I64
){ }), 32);
335 A3 (1, (8 ? (I64
){ } : (I64
){ }), 64);
338 /* Suppress -Wc++-compat warning: converting an array compound literal
339 to a pointer is ill-formed in C++ */
340 # pragma GCC diagnostic ignored "-Wc++-compat"
342 A (0, (9 ? (A32_I64
){ } : (A32_I64
){ }));
343 A3 (0, (i
? (A32_I64
){ } : (A32_I64
){ }), 8);
344 A3 (0, (i
++ ? (A32_I64
){ } : (A32_I64
){ }), 16);
345 A3 (0, (++i
? (A32_I64
){ } : (A32_I64
){ }), 32);
346 A3 (0, (!i
? (A32_I64
){ } : (A32_I64
){ }), 64);
348 A (1, (0 ? (A32_I64
){ } : (A32_I64
){ })[0]);
349 A3 (0, (1 ? (A32_I64
){ } : (A32_I64
){ })[1], 8);
350 A3 (0, (2 ? (A32_I64
){ } : (A32_I64
){ })[2], 16);
351 A3 (0, (3 ? (A32_I64
){ } : (A32_I64
){ })[3], 32);
352 A3 (1, (3 ? (A32_I64
){ } : (A32_I64
){ })[i
], 64);
357 void test_comma_expression (int i
)
360 /* In C++, the type of the comma expressions whose operand is an array
361 is the array itself with any attributes it was defined with. */
364 /* In C, the type of the comma expressions whose operand is an array
365 is a pointer type that does not include any attributes the array
368 /* Suppress -Wc++-compat warning: converting an array compound literal
369 to a pointer is ill-formed in C++
370 G++ accepts the conversion in unevaluated contexts without a warning. */
371 # pragma GCC diagnostic ignored "-Wc++-compat"
377 A3 (1, (1, (I8
){ }), 8);
378 A3 (0, (2, (I8
){ }), 16);
380 A (1, (3, (I64
){ }));
381 A3 (0, (4, (I64
){ }), 8);
382 A3 (0, (5, (I64
){ }), 16);
383 A3 (0, (6, (I64
){ }), 32);
384 A3 (1, (7, (I64
){ }), 64);
386 A (R
, (8, (A32_I64
){ }));
387 A3 (0, (9, (A32_I64
){ }), 8);
388 A3 (0, ((void)0, (A32_I64
){ }), 16);
389 A3 (R
, ((I64
){ },(A32_I64
){ }), 32);
390 A3 (0, (0, (A32_I64
){ }), 64);
392 A (1, (1, ((A32_I64
){ })[0]));
393 A3 (0, (2, ((A32_I64
){ })[0]), 8);
394 A3 (0, (i
++, ((A32_I64
){ })[0]), 16);
395 A3 (0, (++i
, ((A32_I64
){ })[0]), 32);
396 A3 (1, (i
= 0, ((A32_I64
){ })[0]), 64);