145
|
1 /* Verify __builtin_has_attribute return value for types.
|
|
2 { dg-do compile }
|
|
3 { dg-options "-Wall -ftrack-macro-expansion=0" }
|
|
4 { dg-options "-Wall -Wno-narrowing -Wno-unused-local-typedefs -ftrack-macro-expansion=0" { target c++ } } */
|
|
5
|
|
6 #define ATTR(...) __attribute__ ((__VA_ARGS__))
|
|
7
|
|
8 #define A(expect, sym, attr) \
|
|
9 typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)]
|
|
10
|
|
11 struct ATTR (packed) Packed { char c; int i; };
|
|
12
|
|
13 void fvoid (void);
|
|
14 struct Packed fpacked (void);
|
|
15
|
|
16 union OrdinaryUnion { void *p; int i; };
|
|
17 union ATTR (transparent_union) TransparentUnion { void *p; int i; };
|
|
18
|
|
19 /* Exercise __builtin_has_attribute with the first argument that
|
|
20 is a type. */
|
|
21
|
|
22 void test_type (int n)
|
|
23 {
|
|
24 /* Verify both forms of the attribute spelling. Unlike the attribute
|
|
25 keyword that can be spelled three ways (with either leading or
|
|
26 trailing underscores, or with both), attribute names can only be
|
|
27 spelled two ways. */
|
|
28 A (0, int, aligned);
|
|
29 A (0, int, __aligned__);
|
|
30
|
|
31 A (0, int, aligned (1));
|
|
32 A (0, int, aligned (2));
|
|
33 A (0, int[1], aligned);
|
|
34 A (0, int[1], aligned (2));
|
|
35 A (0, int[n], aligned);
|
|
36 A (0, int[n], aligned (4));
|
|
37
|
|
38 /* Again, verify both forms of the attribute spelling. */
|
|
39 A (1, ATTR (aligned) char, aligned);
|
|
40 A (1, ATTR (aligned (2)) short, aligned);
|
|
41 A (1, ATTR (aligned (4)) int, __aligned__);
|
|
42
|
|
43 A (0, int ATTR (aligned (4)), aligned (2));
|
|
44 A (0, int ATTR (aligned (2)), aligned (4));
|
|
45 /* GCC retains both attributes when the type is defined in the builtin. */
|
|
46 A (1, int ATTR (aligned (2), aligned (4)), aligned (2));
|
|
47 A (1, int ATTR (aligned (2), aligned (4)), aligned (4));
|
|
48 /* The following fails due to bug 87524.
|
|
49 A (1, int ATTR (aligned (4), aligned (2))), aligned (4)); */
|
|
50 A (0, int ATTR (aligned (4), aligned (2)), aligned (8));
|
|
51
|
|
52 A (1, int ATTR (aligned (8)), aligned (1 + 7));
|
|
53
|
|
54 enum { eight = 8 };
|
|
55 A (1, int ATTR (aligned (8)), aligned (eight));
|
|
56 A (1, int ATTR (aligned (eight)), aligned (1 + 7));
|
|
57
|
|
58 struct NotPacked { char c; int i; };
|
|
59 A (0, struct NotPacked, packed);
|
|
60 A (1, struct Packed, packed);
|
|
61
|
|
62 /* Exercise types returned from a function. */
|
|
63 A (0, fvoid (), packed);
|
|
64 A (1, fpacked (), packed);
|
|
65
|
|
66 struct ATTR (aligned (2), packed) Aligned2Packed { char c; int i; };
|
|
67 A (1, struct Aligned2Packed, aligned);
|
|
68 A (1, struct Aligned2Packed, aligned (2));
|
|
69 A (0, struct Aligned2Packed, aligned (4));
|
|
70 A (1, struct Aligned2Packed, packed);
|
|
71
|
|
72 A (0, int, may_alias);
|
|
73 A (1, ATTR (may_alias) int, may_alias);
|
|
74
|
|
75 A (0, char, warn_if_not_aligned (1));
|
|
76 A (0, char, warn_if_not_aligned (2));
|
|
77
|
|
78 A (1, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned);
|
|
79 A (0, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned (1));
|
|
80 A (1, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned (2));
|
|
81 A (0, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned (4));
|
|
82
|
|
83 A (0, union OrdinaryUnion, transparent_union);
|
|
84
|
|
85 A (1, union TransparentUnion, transparent_union);
|
|
86 A (1, const union TransparentUnion, transparent_union);
|
|
87 }
|
|
88
|
|
89 /* Exercise __builtin_has_attribute with the first argument that
|
|
90 is a typedef. */
|
|
91
|
|
92 void test_typedef (int n)
|
|
93 {
|
|
94 typedef char A1[1];
|
|
95 A (0, A1, aligned);
|
|
96 A (0, A1, aligned (1));
|
|
97 A (0, A1, aligned (2));
|
|
98
|
|
99 typedef char An[n];
|
|
100 A (0, An, aligned);
|
|
101 A (0, An, aligned (1));
|
|
102 A (0, An, aligned (2));
|
|
103
|
|
104 typedef ATTR (aligned (8)) short AI8;
|
|
105 A (1, AI8, aligned);
|
|
106 A (0, AI8, aligned (4));
|
|
107 A (1, AI8, aligned (8));
|
|
108 A (0, AI8, aligned (16));
|
|
109
|
|
110 A (1, const AI8, aligned);
|
|
111 A (1, const volatile AI8, aligned);
|
|
112
|
|
113 typedef ATTR (aligned (2), aligned (8), aligned (16)) int AI16;
|
|
114 A (1, AI16, aligned);
|
|
115 A (0, AI16, aligned (1));
|
|
116 A (0, AI16, aligned (2));
|
|
117 A (0, AI16, aligned (4));
|
|
118 A (0, AI16, aligned (8));
|
|
119 A (1, AI16, aligned (16));
|
|
120 A (0, AI16, aligned (32));
|
|
121
|
|
122 typedef const AI16 CAI16;
|
|
123 A (1, CAI16, aligned);
|
|
124 A (0, CAI16, aligned (1));
|
|
125 A (1, CAI16, aligned (16));
|
|
126
|
|
127 typedef int I;
|
|
128 A (0, I, may_alias);
|
|
129 A (0, AI8, may_alias);
|
|
130
|
|
131 typedef ATTR (may_alias) int MAI;
|
|
132 A (1, MAI, may_alias);
|
|
133
|
|
134 typedef ATTR (aligned (4), may_alias) char A4MAC;
|
|
135 A (0, A4MAC, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */
|
|
136 A (0, A4MAC, aligned (1));
|
|
137 A (0, A4MAC, aligned (2));
|
|
138 A (1, A4MAC, aligned (4));
|
|
139 A (0, A4MAC, aligned (8));
|
|
140 A (1, A4MAC, may_alias);
|
|
141
|
|
142 typedef ATTR (may_alias, aligned (8)) char A8MAC;
|
|
143 A (1, A8MAC, aligned);
|
|
144 A (0, A8MAC, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */
|
|
145 A (0, A8MAC, aligned (1));
|
|
146 A (0, A8MAC, aligned (2));
|
|
147 A (0, A8MAC, aligned (4));
|
|
148 A (1, A8MAC, aligned (8));
|
|
149 A (0, A8MAC, aligned (16));
|
|
150 A (1, A8MAC, may_alias);
|
|
151
|
|
152 typedef ATTR (may_alias) const AI8 CMAI8;
|
|
153 A (1, CMAI8, aligned);
|
|
154 A (1, CMAI8, may_alias);
|
|
155 A (0, CMAI8, aligned (4));
|
|
156 A (1, CMAI8, aligned (8));
|
|
157
|
|
158 typedef void Fnull (void*, void*, void*);
|
|
159 A (0, Fnull, nonnull);
|
|
160 A (0, Fnull, nonnull (1));
|
|
161 A (0, Fnull, nonnull (2));
|
|
162 A (0, Fnull, nonnull (3));
|
|
163
|
|
164 typedef ATTR (nonnull) Fnull Fnonnull;
|
|
165 A (1, Fnonnull, nonnull);
|
|
166 A (1, Fnonnull, nonnull (1));
|
|
167 A (1, Fnonnull, nonnull (2));
|
|
168 A (1, Fnonnull, nonnull (3));
|
|
169
|
|
170 typedef ATTR (nonnull (2)) void Fnonnull_2 (void*, void*, void*);
|
|
171 A (0, Fnonnull_2, nonnull);
|
|
172 A (0, Fnonnull_2, nonnull (1));
|
|
173 A (1, Fnonnull_2, nonnull (2));
|
|
174 A (0, Fnonnull_2, nonnull (3));
|
|
175
|
|
176 typedef ATTR (nonnull (1), nonnull (2), nonnull (3))
|
|
177 void Fnonnull_1_2_3 (void*, void*, void*);
|
|
178
|
|
179 /* The following fails because the built-in doesn't recognize that
|
|
180 a single nonnull with no arguments is the same as one nonnull for
|
|
181 each function parameter. Disable the testing for now.
|
|
182 A (1, Fnonnull_1_2_3, nonnull);
|
|
183 */
|
|
184 A (1, Fnonnull_1_2_3, nonnull (1));
|
|
185 A (1, Fnonnull_1_2_3, nonnull (2));
|
|
186 A (1, Fnonnull_1_2_3, nonnull (3));
|
|
187
|
|
188 typedef void Freturns (void);
|
|
189 A (0, Fnull, noreturn);
|
|
190 A (0, Freturns, noreturn);
|
|
191
|
|
192 typedef ATTR (warn_if_not_aligned (8)) char CWA8;
|
|
193 A (0, CWA8, warn_if_not_aligned (2));
|
|
194 A (0, CWA8, warn_if_not_aligned (4));
|
|
195 A (1, CWA8, warn_if_not_aligned (8));
|
|
196 A (0, CWA8, warn_if_not_aligned (16));
|
|
197
|
|
198 typedef union OrdinaryUnion OrdUnion;
|
|
199 A (0, OrdUnion, transparent_union);
|
|
200
|
|
201 /* The attribute is ignored on typedefs but GCC fails to diagnose
|
|
202 it (see bug ). */
|
|
203 typedef union ATTR (transparent_union)
|
|
204 OrdinaryUnion TransUnion; /* { dg-warning "\\\[-Wattributes" "pr87578" { xfail { ! { c++ } } } } */
|
|
205 A (0, TransUnion, transparent_union);
|
|
206 }
|