[PR c++/84702] ICE with default tmpl arg of overload set
[official-gcc.git] / gcc / testsuite / g++.dg / ext / builtin_alloca.C
blobe857502685a76c2316c9f869cc4724e63d6a914c
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 }
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)
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
25 static void* p;
27 // Verify that valid __builtin_alloca_with_align expressions are accepted.
28 void test_valid (int n)
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   };
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;
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 }; };
71 template <int 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.
86 template <int A>
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)
103   extern void f ();
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)
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" }
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.
163 template <int A>
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);
172 template <int A>
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);
180 template <int A>
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.
189 template <int A>
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);