1// RUN: %clang_cc1 -fsyntax-only -verify -Wvla-extension %s
2struct NonPOD {
3  NonPOD();
4};
5
6struct NonPOD2 {
7  NonPOD np;
8};
9
10struct POD {
11  int x;
12  int y;
13};
14
15// We allow VLAs of POD types, only.
16void 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.
24template<typename T>
25void vla_in_template(int N, T t) {
26  int array1[N]; // expected-warning{{variable length arrays are a C99 feature}}
27}
28
29struct HasConstantValue {
30  static const unsigned int value = 2;
31};
32
33struct HasNonConstantValue {
34  static unsigned int value;
35};
36
37template<typename T>
38void vla_in_template(T t) {
39  int array2[T::value]; // expected-warning{{variable length arrays are a C99 feature}}
40}
41
42template void vla_in_template<HasConstantValue>(HasConstantValue);
43template void vla_in_template<HasNonConstantValue>(HasNonConstantValue); // expected-note{{instantiation of}}
44
45template<typename T> struct X0 { };
46
47// Cannot use any variably-modified type with a template parameter or
48// argument.
49void 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
54template<typename T>
55struct 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
63X1<HasConstantValue> x1a;
64X1<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!
68template<typename T, unsigned N>
69void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: could not match 'T [N]' against 'int [N]'}}
70
71void 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.
77void 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
86namespace PR7206 {
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
96namespace rdar8020206 {
97  template<typename T>
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
106namespace 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;
112    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
120namespace PR8209 {
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
127namespace rdar8733881 { // rdar://8733881
128
129static const int k_cVal3 = (int)(1000*0.2f);
130  int f() {
131    // Ok, fold to a constant size array as an extension.
132    char rgch[k_cVal3] = {0};
133  }
134}
135
136namespace PR11744 {
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
144namespace 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>
151  void func () {
152    int arr[A1::sz]; // expected-warning{{variable length arrays are a C99 feature}}
153  }
154  template<typename T>
155  void func2 () {
156    int arr[A1::sz2];
157  }
158  const int A1::sz = 12;
159  void func2() {
160    func<int>();
161    func2<int>();
162  }
163}
164