1 // RUN: %clang_cc1 -fsyntax-only -verify -Wvla-extension %s
2 struct NonPOD {
3   NonPOD();
4 };
5 
6 struct NonPOD2 {
7   NonPOD np;
8 };
9 
10 struct POD {
11   int x;
12   int y;
13 };
14 
15 // We allow VLAs of POD types, only.
vla(int N)16 void vla(int N) {
17   int array1[N]; // expected-warning{{variable length arrays are a C99 feature}}
18   POD array2[N]; // expected-warning{{variable length arrays are a C99 feature}}
19   NonPOD array3[N]; // expected-error{{variable length array of non-POD element type 'NonPOD'}}
20   NonPOD2 array4[N][3]; // expected-error{{variable length array of non-POD element type 'NonPOD2'}}
21 }
22 
23 /// Warn about VLAs in templates.
24 template<typename T>
vla_in_template(int N,T t)25 void vla_in_template(int N, T t) {
26   int array1[N]; // expected-warning{{variable length arrays are a C99 feature}}
27 }
28 
29 struct HasConstantValue {
30   static const unsigned int value = 2;
31 };
32 
33 struct HasNonConstantValue {
34   static unsigned int value;
35 };
36 
37 template<typename T>
vla_in_template(T t)38 void vla_in_template(T t) {
39   int array2[T::value]; // expected-warning{{variable length arrays are a C99 feature}}
40 }
41 
42 template void vla_in_template<HasConstantValue>(HasConstantValue);
43 template void vla_in_template<HasNonConstantValue>(HasNonConstantValue); // expected-note{{instantiation of}}
44 
45 template<typename T> struct X0 { };
46 
47 // Cannot use any variably-modified type with a template parameter or
48 // argument.
inst_with_vla(int N)49 void inst_with_vla(int N) {
50   int array[N]; // expected-warning{{variable length arrays are a C99 feature}}
51   X0<__typeof__(array)> x0a; // expected-error{{variably modified type 'typeof (array)' (aka 'int [N]') cannot be used as a template argument}}
52 }
53 
54 template<typename T>
55 struct X1 {
56   template<int (&Array)[T::value]> // expected-error{{non-type template parameter of variably modified type 'int (&)[HasNonConstantValue::value]'}}  \
57   // expected-warning{{variable length arrays are a C99 feature}}
58   struct Inner {
59 
60   };
61 };
62 
63 X1<HasConstantValue> x1a;
64 X1<HasNonConstantValue> x1b; // expected-note{{in instantiation of}}
65 
66 // Template argument deduction does not allow deducing a size from a VLA.
67 // FIXME: This diagnostic should make it clear that the two 'N's are different entities!
68 template<typename T, unsigned N>
69 void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: could not match 'T [N]' against 'int [N]'}}
70 
test_accept_array(int N)71 void test_accept_array(int N) {
72   int array[N]; // expected-warning{{variable length arrays are a C99 feature}}
73   accept_array(array); // expected-error{{no matching function for call to 'accept_array'}}
74 }
75 
76 // Variably-modified types cannot be used in local classes.
local_classes(int N)77 void local_classes(int N) { // expected-note {{declared here}}
78   struct X {
79     int size;
80     int array[N]; // expected-error{{fields must have a constant size: 'variable length array in structure' extension will never be supported}} \
81                   // expected-error{{reference to local variable 'N' declared in enclosing function 'local_classes'}} \
82                   // expected-warning{{variable length arrays are a C99 feature}}
83   };
84 }
85 
86 namespace PR7206 {
f(int x)87   void f(int x) {
88     struct edge_info {
89       float left;
90       float right;
91     };
92     struct edge_info edgeInfo[x]; // expected-warning{{variable length arrays are a C99 feature}}
93   }
94 }
95 
96 namespace rdar8020206 {
97   template<typename T>
f(int i)98   void f(int i) {
99     const unsigned value = i;
100     int array[value * i]; // expected-warning 2{{variable length arrays are a C99 feature}}
101   }
102 
103   template void f<int>(int); // expected-note{{instantiation of}}
104 }
105 
106 namespace rdar8021385 {
107   typedef int my_int;
108   struct A { typedef int my_int; };
109   template<typename T>
110   struct B {
111     typedef typename T::my_int my_int;
f0rdar8021385::B112     void f0() {
113       int M = 4;
114       my_int a[M]; // expected-warning{{variable length arrays are a C99 feature}}
115     }
116   };
117   B<A> a;
118 }
119 
120 namespace PR8209 {
f(int n)121   void f(int n) {
122     typedef int vla_type[n]; // expected-warning{{variable length arrays are a C99 feature}}
123     (void)new vla_type; // expected-error{{variably}}
124   }
125 }
126 
127 namespace rdar8733881 { // rdar://8733881
128 
129 static const int k_cVal3 = (int)(1000*0.2f);
f()130   int f() {
131     // Ok, fold to a constant size array as an extension.
132     char rgch[k_cVal3] = {0};
133   }
134 }
135 
136 namespace PR11744 {
f(int n)137   template<typename T> int f(int n) {
138     T arr[3][n]; // expected-warning 3 {{variable length arrays are a C99 feature}}
139     return 3;
140   }
141   int test = f<int>(0); // expected-note {{instantiation of}}
142 }
143 
144 namespace pr18633 {
145   struct A1 {
146     static const int sz;
147     static const int sz2;
148   };
149   const int A1::sz2 = 11;
150   template<typename T>
func()151   void func () {
152     int arr[A1::sz]; // expected-warning{{variable length arrays are a C99 feature}}
153   }
154   template<typename T>
func2()155   void func2 () {
156     int arr[A1::sz2];
157   }
158   const int A1::sz = 12;
func2()159   void func2() {
160     func<int>();
161     func2<int>();
162   }
163 }
164