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