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 // We disallow VLAs in templates 24 template<typename T> 25 void vla_in_template(int N, T t) { 26 int array1[N]; // expected-error{{variable length array cannot be used in a template definition}} 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-error{{variable length array cannot be used in a template instantiation}} 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{{variable length array cannot be used in a template instantiation}} 57 struct Inner { 58 59 }; 60 }; 61 62 X1<HasConstantValue> x1a; 63 X1<HasNonConstantValue> x1b; // expected-note{{in instantiation of}} 64 65 // Template argument deduction does not allow deducing a size from a VLA. 66 template<typename T, unsigned N> 67 void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: failed template argument deduction}} 68 69 void test_accept_array(int N) { 70 int array[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}} 71 accept_array(array); // expected-error{{no matching function for call to 'accept_array'}} 72 } 73 74 // Variably-modified types cannot be used in local classes. 75 void local_classes(int N) { 76 struct X { 77 int size; 78 int array[N]; // expected-error{{fields must have a constant size: 'variable length array in structure' extension will never be supported}} \ 79 // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}} 80 }; 81 } 82 83 namespace PR7206 { 84 void f(int x) { 85 struct edge_info { 86 float left; 87 float right; 88 }; 89 struct edge_info edgeInfo[x]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}} 90 } 91 } 92