169 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -Wvla-extension %s2// RUN: %clang_cc1 -fsyntax-only -verify -Wvla-extension %s -fexperimental-new-constant-interpreter3struct NonPOD {4 NonPOD();5};6 7struct NonPOD2 {8 NonPOD np;9};10 11struct 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.21void 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.29template<typename T>30void vla_in_template(int N, T t) {31 int array1[N]; // expected-warning{{variable length arrays in C++ are a Clang extension}}32}33 34struct HasConstantValue {35 static const unsigned int value = 2;36};37 38struct HasNonConstantValue {39 static unsigned int value;40};41 42template<typename T>43void vla_in_template(T t) {44 int array2[T::value]; // expected-warning{{variable length arrays in C++ are a Clang extension}}45}46 47template void vla_in_template<HasConstantValue>(HasConstantValue);48template void vla_in_template<HasNonConstantValue>(HasNonConstantValue); // expected-note{{instantiation of}}49 50template<typename T> struct X0 { };51 52// Cannot use any variably-modified type with a template parameter or53// argument.54void 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 59template<typename T>60struct 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 68X1<HasConstantValue> x1a;69X1<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!73template<typename T, unsigned N>74void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: could not match 'T[N]' against 'int[N]'}}75 76void 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.82void 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 91namespace 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 101namespace 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 111namespace 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 125namespace 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 132namespace rdar8733881 {133 134static 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 141namespace 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 149namespace 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