forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			164 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
// RUN: %clang_cc1 -fsyntax-only -verify -Wvla-extension %s
 | 
						|
struct NonPOD {
 | 
						|
  NonPOD();
 | 
						|
};
 | 
						|
 | 
						|
struct NonPOD2 {
 | 
						|
  NonPOD np;
 | 
						|
};
 | 
						|
 | 
						|
struct POD {
 | 
						|
  int x;
 | 
						|
  int y;
 | 
						|
};
 | 
						|
 | 
						|
// We allow VLAs of POD types, only.
 | 
						|
void vla(int N) {
 | 
						|
  int array1[N]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
  POD array2[N]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
  NonPOD array3[N]; // expected-error{{variable length array of non-POD element type 'NonPOD'}}
 | 
						|
  NonPOD2 array4[N][3]; // expected-error{{variable length array of non-POD element type 'NonPOD2'}}
 | 
						|
}
 | 
						|
 | 
						|
/// Warn about VLAs in templates.
 | 
						|
template<typename T>
 | 
						|
void vla_in_template(int N, T t) {
 | 
						|
  int array1[N]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
}
 | 
						|
 | 
						|
struct HasConstantValue {
 | 
						|
  static const unsigned int value = 2;
 | 
						|
};
 | 
						|
 | 
						|
struct HasNonConstantValue {
 | 
						|
  static unsigned int value;
 | 
						|
};
 | 
						|
 | 
						|
template<typename T>
 | 
						|
void vla_in_template(T t) {
 | 
						|
  int array2[T::value]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
}
 | 
						|
 | 
						|
template void vla_in_template<HasConstantValue>(HasConstantValue);
 | 
						|
template void vla_in_template<HasNonConstantValue>(HasNonConstantValue); // expected-note{{instantiation of}}
 | 
						|
 | 
						|
template<typename T> struct X0 { };
 | 
						|
 | 
						|
// Cannot use any variably-modified type with a template parameter or
 | 
						|
// argument.
 | 
						|
void inst_with_vla(int N) {
 | 
						|
  int array[N]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
  X0<__typeof__(array)> x0a; // expected-error{{variably modified type 'typeof (array)' (aka 'int [N]') cannot be used as a template argument}}
 | 
						|
}
 | 
						|
 | 
						|
template<typename T>
 | 
						|
struct X1 {
 | 
						|
  template<int (&Array)[T::value]> // expected-error{{non-type template parameter of variably modified type 'int (&)[HasNonConstantValue::value]'}}  \
 | 
						|
  // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
  struct Inner {
 | 
						|
    
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
X1<HasConstantValue> x1a;
 | 
						|
X1<HasNonConstantValue> x1b; // expected-note{{in instantiation of}}
 | 
						|
 | 
						|
// Template argument deduction does not allow deducing a size from a VLA.
 | 
						|
// FIXME: This diagnostic should make it clear that the two 'N's are different entities!
 | 
						|
template<typename T, unsigned N>
 | 
						|
void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: could not match 'T [N]' against 'int [N]'}}
 | 
						|
 | 
						|
void test_accept_array(int N) {
 | 
						|
  int array[N]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
  accept_array(array); // expected-error{{no matching function for call to 'accept_array'}}
 | 
						|
}
 | 
						|
 | 
						|
// Variably-modified types cannot be used in local classes.
 | 
						|
void local_classes(int N) { // expected-note {{declared here}}
 | 
						|
  struct X {
 | 
						|
    int size;
 | 
						|
    int array[N]; // expected-error{{fields must have a constant size: 'variable length array in structure' extension will never be supported}} \
 | 
						|
                  // expected-error{{reference to local variable 'N' declared in enclosing function 'local_classes'}} \
 | 
						|
                  // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
namespace PR7206 {
 | 
						|
  void f(int x) {
 | 
						|
    struct edge_info {
 | 
						|
      float left;
 | 
						|
      float right;
 | 
						|
    };
 | 
						|
    struct edge_info edgeInfo[x]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
namespace rdar8020206 {
 | 
						|
  template<typename T>
 | 
						|
  void f(int i) {
 | 
						|
    const unsigned value = i;
 | 
						|
    int array[value * i]; // expected-warning 2{{variable length arrays are a C99 feature}}
 | 
						|
  }
 | 
						|
 | 
						|
  template void f<int>(int); // expected-note{{instantiation of}}
 | 
						|
}
 | 
						|
 | 
						|
namespace rdar8021385 {
 | 
						|
  typedef int my_int;
 | 
						|
  struct A { typedef int my_int; };
 | 
						|
  template<typename T>
 | 
						|
  struct B {
 | 
						|
    typedef typename T::my_int my_int;
 | 
						|
    void f0() {
 | 
						|
      int M = 4;
 | 
						|
      my_int a[M]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
    }
 | 
						|
  };
 | 
						|
  B<A> a;
 | 
						|
}
 | 
						|
 | 
						|
namespace PR8209 {
 | 
						|
  void f(int n) {
 | 
						|
    typedef int vla_type[n]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
    (void)new vla_type; // expected-error{{variably}}
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
namespace rdar8733881 { // rdar://8733881
 | 
						|
 | 
						|
static const int k_cVal3 = (int)(1000*0.2f);
 | 
						|
  int f() {
 | 
						|
    // Ok, fold to a constant size array as an extension.
 | 
						|
    char rgch[k_cVal3] = {0};
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
namespace PR11744 {
 | 
						|
  template<typename T> int f(int n) {
 | 
						|
    T arr[3][n]; // expected-warning 3 {{variable length arrays are a C99 feature}}
 | 
						|
    return 3;
 | 
						|
  }
 | 
						|
  int test = f<int>(0); // expected-note {{instantiation of}}
 | 
						|
}
 | 
						|
 | 
						|
namespace pr18633 {
 | 
						|
  struct A1 {
 | 
						|
    static const int sz;
 | 
						|
    static const int sz2;
 | 
						|
  };
 | 
						|
  const int A1::sz2 = 11;
 | 
						|
  template<typename T>
 | 
						|
  void func () {
 | 
						|
    int arr[A1::sz]; // expected-warning{{variable length arrays are a C99 feature}}
 | 
						|
  }
 | 
						|
  template<typename T>
 | 
						|
  void func2 () {
 | 
						|
    int arr[A1::sz2];
 | 
						|
  }
 | 
						|
  const int A1::sz = 12;
 | 
						|
  void func2() {
 | 
						|
    func<int>();
 | 
						|
    func2<int>();
 | 
						|
  }
 | 
						|
}
 |