111
|
1 // PR middle-end/69780 - [4.9/5/6 Regression] ICE on
|
|
2 // __builtin_alloca_with_align with small alignment
|
|
3 // { dg-do compile }
|
|
4 // { dg-require-effective-target alloca }
|
|
5
|
|
6 #define CHAR_BIT __CHAR_BIT__
|
|
7 #define SIZE_MAX __SIZE_MAX__
|
|
8 #define UINT_MAX (__INT_MAX__ + 1U)
|
|
9
|
|
10 /* The largest valid alignment is undocumented and subject to change
|
|
11 but for the purposes of white box testing we rely on knowing that
|
|
12 it happens to be defined to (UINT_MAX >> 1) + 1. */
|
|
13 #define ALIGN_MAX ((UINT_MAX >> 1) + 1)
|
|
14
|
|
15 #if UINT_MAX < SIZE_MAX
|
|
16 /* Define a constant to exercise an alignment that is valid a power
|
|
17 of 2 in excess of the maximum. */
|
|
18 # define MAX_X_2 (ALIGN_MAX << 1)
|
|
19 #else
|
|
20 /* For targets where UINT_MAX is the same as SIZE_MAX, use an invalid
|
|
21 alignment that's less than the maximum to elicit the same errors. */
|
|
22 # define MAX_X_2 (ALIGN_MAX + 1)
|
|
23 #endif
|
|
24
|
|
25 static void* p;
|
|
26
|
|
27 // Verify that valid __builtin_alloca_with_align expressions are accepted.
|
|
28 void test_valid (int n)
|
|
29 {
|
|
30 enum {
|
|
31 A1 = CHAR_BIT * 1,
|
|
32 A2 = CHAR_BIT * 2,
|
|
33 A4 = CHAR_BIT * 4,
|
|
34 A8 = CHAR_BIT * 8,
|
|
35 A16 = CHAR_BIT * 16,
|
|
36 A32 = CHAR_BIT * 32
|
|
37 };
|
|
38
|
|
39 const int a1 = A1;
|
|
40 const int a2 = A2;
|
|
41 const int a4 = A4;
|
|
42 const int a8 = A8;
|
|
43 const int a16 = A16;
|
|
44 const int a32 = A32;
|
|
45
|
|
46 // Valid alignments are power of 2 positive multiples of CHAR_BIT.
|
|
47 p = __builtin_alloca_with_align (n, CHAR_BIT * 1);
|
|
48 p = __builtin_alloca_with_align (n, CHAR_BIT * 2);
|
|
49 p = __builtin_alloca_with_align (n, CHAR_BIT * 4);
|
|
50 p = __builtin_alloca_with_align (n, CHAR_BIT * 8);
|
|
51 p = __builtin_alloca_with_align (n, CHAR_BIT * 16);
|
|
52 p = __builtin_alloca_with_align (n, CHAR_BIT * 32);
|
|
53
|
|
54 p = __builtin_alloca_with_align (n, A1);
|
|
55 p = __builtin_alloca_with_align (n, A2);
|
|
56 p = __builtin_alloca_with_align (n, A4);
|
|
57 p = __builtin_alloca_with_align (n, A8);
|
|
58 p = __builtin_alloca_with_align (n, A16);
|
|
59 p = __builtin_alloca_with_align (n, A32);
|
|
60
|
|
61 p = __builtin_alloca_with_align (n, a1);
|
|
62 p = __builtin_alloca_with_align (n, a2);
|
|
63 p = __builtin_alloca_with_align (n, a4);
|
|
64 p = __builtin_alloca_with_align (n, a8);
|
|
65 p = __builtin_alloca_with_align (n, a16);
|
|
66 p = __builtin_alloca_with_align (n, a32);
|
|
67 }
|
|
68
|
|
69 template <int A> struct X { enum { Align = A }; };
|
|
70
|
|
71 template <int A>
|
|
72 void test_valid_template (int n)
|
|
73 {
|
|
74 // Valid alignments are power of 2 positive multiples of CHAR_BIT.
|
|
75 p = __builtin_alloca_with_align (n, A);
|
|
76 }
|
|
77
|
|
78 template void test_valid_template<CHAR_BIT>(int);
|
|
79 template void test_valid_template<CHAR_BIT * 2>(int);
|
|
80 template void test_valid_template<CHAR_BIT * 4>(int);
|
|
81 template void test_valid_template<CHAR_BIT * 8>(int);
|
|
82 template void test_valid_template<CHAR_BIT * 16>(int);
|
|
83 template void test_valid_template<CHAR_BIT * 32>(int);
|
|
84
|
|
85 // Exercise the alignment in a dependent context.
|
|
86 template <int A>
|
|
87 void test_valid_template_dep (int n)
|
|
88 {
|
|
89 // Valid alignments are power of 2 positive multiples of CHAR_BIT.
|
|
90 p = __builtin_alloca_with_align (n, X<A>::Align);
|
|
91 }
|
|
92
|
|
93 template void test_valid_template_dep<CHAR_BIT>(int);
|
|
94 template void test_valid_template_dep<CHAR_BIT * 2>(int);
|
|
95 template void test_valid_template_dep<CHAR_BIT * 4>(int);
|
|
96 template void test_valid_template_dep<CHAR_BIT * 8>(int);
|
|
97 template void test_valid_template_dep<CHAR_BIT * 16>(int);
|
|
98 template void test_valid_template_dep<CHAR_BIT * 32>(int);
|
|
99
|
|
100 // Invalid size must be rejected (and not cause an ICE).
|
|
101 void test_arg1_non_int (int n)
|
|
102 {
|
|
103 extern void f ();
|
|
104
|
|
105 p = __builtin_alloca_with_align ((void*)0, 32); // { dg-error "invalid conversion" }
|
|
106
|
|
107 p = __builtin_alloca_with_align ("", 32); // { dg-error "invalid conversion" }
|
|
108 p = __builtin_alloca_with_align (L"", 32); // { dg-error "invalid conversion" }
|
|
109 p = __builtin_alloca_with_align (f, 32); // { dg-error "invalid conversion" }
|
|
110 }
|
|
111
|
|
112 // Non-integer alignment must be rejected.
|
|
113 void test_arg2_non_int (int n)
|
|
114 {
|
|
115 // Verify the full text of the diagnostic just once.
|
|
116 p = __builtin_alloca_with_align (n, 0.0); // { dg-error "second argument to function .__builtin_alloca_with_align. must be a constant integer power of 2 between .8. and " }
|
|
117
|
|
118 p = __builtin_alloca_with_align (n, (void*)0); // { dg-error "invalid conversion|must be a constant integer" }
|
|
119 p = __builtin_alloca_with_align (n, ""); // { dg-error "invalid conversion|must be a constant integer" }
|
|
120 p = __builtin_alloca_with_align (n, L""); // { dg-error "invalid conversion|must be a constant integer" }
|
|
121 }
|
|
122
|
|
123 // Integer alignment that's not a constant expression must be rejected.
|
|
124 void test_arg2_non_const (int n, int a1)
|
|
125 {
|
|
126 extern const int a2;
|
|
127 static volatile const int a3 = CHAR_BIT;
|
|
128
|
|
129 p = __builtin_alloca_with_align (n, a1); // { dg-error "must be a constant integer" }
|
|
130 p = __builtin_alloca_with_align (n, a2); // { dg-error "must be a constant integer" }
|
|
131 p = __builtin_alloca_with_align (n, a3); // { dg-error "must be a constant integer" }
|
|
132 }
|
|
133
|
|
134 // Constant integer alignment that's not a power of 2 positive multiple
|
|
135 // of CHAR_BIT must be rejected.
|
|
136 void test_arg2_non_pow2 (int n)
|
|
137 {
|
|
138 p = __builtin_alloca_with_align (n, 0); // { dg-error "must be a constant integer" }
|
|
139 p = __builtin_alloca_with_align (n, 1); // { dg-error "must be a constant integer" }
|
|
140 p = __builtin_alloca_with_align (n, 2); // { dg-error "must be a constant integer" }
|
|
141 p = __builtin_alloca_with_align (n, 3); // { dg-error "must be a constant integer" }
|
|
142 p = __builtin_alloca_with_align (n, 4); // { dg-error "must be a constant integer" }
|
|
143 p = __builtin_alloca_with_align (n, 5); // { dg-error "must be a constant integer" }
|
|
144 p = __builtin_alloca_with_align (n, 6); // { dg-error "must be a constant integer" }
|
|
145 p = __builtin_alloca_with_align (n, 7); // { dg-error "must be a constant integer" }
|
|
146 p = __builtin_alloca_with_align (n, 9); // { dg-error "must be a constant integer" }
|
|
147 p = __builtin_alloca_with_align (n, 10); // { dg-error "must be a constant integer" }
|
|
148 p = __builtin_alloca_with_align (n, 11); // { dg-error "must be a constant integer" }
|
|
149 p = __builtin_alloca_with_align (n, 12); // { dg-error "must be a constant integer" }
|
|
150 p = __builtin_alloca_with_align (n, 13); // { dg-error "must be a constant integer" }
|
|
151 p = __builtin_alloca_with_align (n, 14); // { dg-error "must be a constant integer" }
|
|
152 p = __builtin_alloca_with_align (n, 15); // { dg-error "must be a constant integer" }
|
|
153 p = __builtin_alloca_with_align (n, 17); // { dg-error "must be a constant integer" }
|
|
154 p = __builtin_alloca_with_align (n, 31); // { dg-error "must be a constant integer" }
|
|
155 p = __builtin_alloca_with_align (n, 33); // { dg-error "must be a constant integer" }
|
|
156 p = __builtin_alloca_with_align (n, 63); // { dg-error "must be a constant integer" }
|
|
157 p = __builtin_alloca_with_align (n, 65); // { dg-error "must be a constant integer" }
|
|
158 p = __builtin_alloca_with_align (n, SIZE_MAX); /* { dg-error "must be a constant integer" } */
|
|
159 p = __builtin_alloca_with_align (n, MAX_X_2); /* { dg-error "must be a constant integer" } */
|
|
160 }
|
|
161
|
|
162 // Exercise invalid alignment specified by a template argument.
|
|
163 template <int A>
|
|
164 void test_invalid_template_1 (int n)
|
|
165 {
|
|
166 // Valid alignments are power of 2 positive multiples of CHAR_BIT.
|
|
167 p = __builtin_alloca_with_align (n, A); // { dg-error "must be a constant integer" }
|
|
168 }
|
|
169
|
|
170 template void test_invalid_template_1<1>(int);
|
|
171
|
|
172 template <int A>
|
|
173 void test_invalid_template_7 (int n)
|
|
174 {
|
|
175 p = __builtin_alloca_with_align (n, A); // { dg-error "must be a constant integer" }
|
|
176 }
|
|
177
|
|
178 template void test_invalid_template_7<7>(int);
|
|
179
|
|
180 template <int A>
|
|
181 void test_invalid_template_9 (int n)
|
|
182 {
|
|
183 p = __builtin_alloca_with_align (n, A); // { dg-error "must be a constant integer" }
|
|
184 }
|
|
185
|
|
186 template void test_invalid_template_9<9>(int);
|
|
187
|
|
188 // Exercise invalid alignment specified by a template dependent argument.
|
|
189 template <int A>
|
|
190 void test_invalid_template_dep_1 (int n)
|
|
191 {
|
|
192 p = __builtin_alloca_with_align (n, X<A>::Align); // { dg-error "must be a constant integer" }
|
|
193 }
|
|
194
|
|
195 template void test_invalid_template_dep_1<1>(int);
|