diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-05-22 16:17:30 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-05-22 16:17:30 +0000 |
commit | 0fddb97901dbe36a8253dee29961cba8e0a87cf6 (patch) | |
tree | 2744155a000f164f9b0b3a59211a8272d2c5ac4d /test/SemaCXX/c99-variable-length-array.cpp | |
parent | e229b9dd546e7654e9b23664cc1b16be887b7770 (diff) |
Implement support for variable length arrays in C++. VLAs are limited
in several important ways:
- VLAs of non-POD types are not permitted.
- VLAs cannot be used in conjunction with C++ templates.
These restrictions are intended to keep VLAs out of the parts of the
C++ type system where they cause the most trouble. Fixes PR5678 and
<rdar://problem/8013618>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104443 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX/c99-variable-length-array.cpp')
-rw-r--r-- | test/SemaCXX/c99-variable-length-array.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp new file mode 100644 index 0000000000..a792951252 --- /dev/null +++ b/test/SemaCXX/c99-variable-length-array.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %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]; + POD array2[N]; + 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'}} +} + +// We disallow VLAs in templates +template<typename T> +void vla_in_template(int N, T t) { + int array1[N]; // expected-error{{variable length array cannot be used in a template definition}} +} + +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-error{{variable length array cannot be used in a template instantiation}} +} + +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]; + 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{{variable length array cannot be used in a template instantiation}} + 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. +template<typename T, unsigned N> +void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: failed template argument deduction}} + +void test_accept_array(int N) { + int array[N]; + 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) { + 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}} + }; +} |