Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -Wvla-extension %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}}
     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.
     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}}
     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}}
     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}}
     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}}
     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 // FIXME: This diagnostic should make it clear that the two 'N's are different entities!
     68 template<typename T, unsigned N>
     69 void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: could not match 'T [N]' against 'int [N]'}}
     70 
     71 void 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.
     77 void 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 
     86 namespace 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 
     96 namespace 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 
    106 namespace 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 
    120 namespace 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 
    127 namespace rdar8733881 { // rdar://8733881
    128 
    129 static 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 
    136 namespace 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