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