xref: /llvm-project/clang/test/SemaCXX/c99-variable-length-array.cpp (revision 9a414458ff9de0f3b7a04f7561ba28c68143f145)
1 // RUN: %clang_cc1 -fsyntax-only -verify -Wvla %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.
16 void vla(int N) {
17   int array1[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
18   POD array2[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
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>
25 void vla_in_template(int N, T t) {
26   int array1[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
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>
38 void vla_in_template(T t) {
39   int array2[T::value]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
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.
49 void inst_with_vla(int N) {
50   int array[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
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, accepted as an extension}}
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 template<typename T, unsigned N>
68 void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: failed template argument deduction}}
69 
70 void test_accept_array(int N) {
71   int array[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
72   accept_array(array); // expected-error{{no matching function for call to 'accept_array'}}
73 }
74 
75 // Variably-modified types cannot be used in local classes.
76 void local_classes(int N) {
77   struct X {
78     int size;
79     int array[N]; // expected-error{{fields must have a constant size: 'variable length array in structure' extension will never be supported}} \
80                   // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
81   };
82 }
83 
84 namespace PR7206 {
85   void f(int x) {
86     struct edge_info {
87       float left;
88       float right;
89     };
90     struct edge_info edgeInfo[x]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
91   }
92 }
93 
94 namespace rdar8020206 {
95   template<typename T>
96   void f(int i) {
97     const unsigned value = i;
98     int array[value * i]; // expected-warning 2{{variable length arrays are a C99 feature, accepted as an extension}}
99   }
100 
101   template void f<int>(int); // expected-note{{instantiation of}}
102 }
103 
104 namespace rdar8021385 {
105   typedef int my_int;
106   struct A { typedef int my_int; };
107   template<typename T>
108   struct B {
109     typedef typename T::my_int my_int;
110     void f0() {
111       int M = 4;
112       my_int a[M]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
113     }
114   };
115   B<A> a;
116 }
117