1 // PR middle-end/69780 - [4.9/5/6 Regression] ICE on
2 // __builtin_alloca_with_align with small alignment
4 // { dg-require-effective-target alloca }
6 #define CHAR_BIT __CHAR_BIT__
7 #define SIZE_MAX __SIZE_MAX__
8 #define UINT_MAX (__INT_MAX__ + 1U)
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)
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)
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)
27 // Verify that valid __builtin_alloca_with_align expressions are accepted.
28 void test_valid (int n)
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);
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);
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);
69 template <int A> struct X { enum { Align = A }; };
72 void test_valid_template (int n)
74 // Valid alignments are power of 2 positive multiples of CHAR_BIT.
75 p = __builtin_alloca_with_align (n, A);
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);
85 // Exercise the alignment in a dependent context.
87 void test_valid_template_dep (int n)
89 // Valid alignments are power of 2 positive multiples of CHAR_BIT.
90 p = __builtin_alloca_with_align (n, X<A>::Align);
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);
100 // Invalid size must be rejected (and not cause an ICE).
101 void test_arg1_non_int (int n)
105 p = __builtin_alloca_with_align ((void*)0, 32); // { dg-error "invalid conversion" }
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" }
112 // Non-integer alignment must be rejected.
113 void test_arg2_non_int (int n)
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 " }
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" }
123 // Integer alignment that's not a constant expression must be rejected.
124 void test_arg2_non_const (int n, int a1)
127 static volatile const int a3 = CHAR_BIT;
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" }
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)
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" } */
162 // Exercise invalid alignment specified by a template argument.
164 void test_invalid_template_1 (int n)
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" }
170 template void test_invalid_template_1<1>(int);
173 void test_invalid_template_7 (int n)
175 p = __builtin_alloca_with_align (n, A); // { dg-error "must be a constant integer" }
178 template void test_invalid_template_7<7>(int);
181 void test_invalid_template_9 (int n)
183 p = __builtin_alloca_with_align (n, A); // { dg-error "must be a constant integer" }
186 template void test_invalid_template_9<9>(int);
188 // Exercise invalid alignment specified by a template dependent argument.
190 void test_invalid_template_dep_1 (int n)
192 p = __builtin_alloca_with_align (n, X<A>::Align); // { dg-error "must be a constant integer" }
195 template void test_invalid_template_dep_1<1>(int);