r179962 - Disable VLA diagnostic in C++1y mode, and add some tests.
Richard Smith
richard-llvm at metafoo.co.uk
Sat Apr 20 16:28:26 PDT 2013
Author: rsmith
Date: Sat Apr 20 18:28:26 2013
New Revision: 179962
URL: http://llvm.org/viewvc/llvm-project?rev=179962&view=rev
Log:
Disable VLA diagnostic in C++1y mode, and add some tests.
Still to do here:
- we have a collection of syntactic accepts-invalids to diagnose
- support non-PODs in VLAs, including dynamic initialization /
destruction
- runtime checks (and throw std::bad_array_length) for bad bound
- support VLA capture by reference in lambdas
- properly support VLAs in range-based for (don't recompute bound)
Added:
cfe/trunk/test/SemaCXX/cxx1y-array-runtime-bound.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=179962&r1=179961&r2=179962&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Apr 20 18:28:26 2013
@@ -78,6 +78,9 @@ def ext_vla : Extension<"variable length
InGroup<VLAExtension>;
def warn_vla_used : Warning<"variable length array used">,
InGroup<VLA>, DefaultIgnore;
+def warn_cxx11_compat_array_of_runtime_bound : Warning<
+ "arrays of runtime bound are incompatible with C++ standards before C++1y">,
+ InGroup<CXXPre1yCompatPedantic>, DefaultIgnore;
def err_vla_non_pod : Error<"variable length array of non-POD element type %0">;
def err_vla_in_sfinae : Error<
"variable length array cannot be formed during template argument deduction">;
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=179962&r1=179961&r2=179962&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Sat Apr 20 18:28:26 2013
@@ -1978,6 +1978,8 @@ Sema::BuildCXXForRangeStmt(SourceLocatio
RangeLoc));
else if (const VariableArrayType *VAT =
dyn_cast<VariableArrayType>(UnqAT))
+ // FIXME: Need to build an OpaqueValueExpr for this rather than
+ // recomputing it!
BoundExpr = VAT->getSizeExpr();
else {
// Can't be a DependentSizedArrayType or an IncompleteArrayType since
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=179962&r1=179961&r2=179962&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Sat Apr 20 18:28:26 2013
@@ -1572,6 +1572,7 @@ QualType Sema::BuildArrayType(QualType T
if (!getLangOpts().C99) {
if (T->isVariableArrayType()) {
// Prohibit the use of non-POD types in VLAs.
+ // FIXME: C++1y allows this.
QualType BaseT = Context.getBaseElementType(T);
if (!T->isDependentType() &&
!BaseT.isPODType(Context) &&
@@ -1587,7 +1588,9 @@ QualType Sema::BuildArrayType(QualType T
}
// Just extwarn about VLAs.
else
- Diag(Loc, diag::ext_vla);
+ Diag(Loc, getLangOpts().CPlusPlus1y
+ ? diag::warn_cxx11_compat_array_of_runtime_bound
+ : diag::ext_vla);
} else if (ASM != ArrayType::Normal || Quals != 0)
Diag(Loc,
getLangOpts().CPlusPlus? diag::err_c99_array_usage_cxx
Added: cfe/trunk/test/SemaCXX/cxx1y-array-runtime-bound.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-array-runtime-bound.cpp?rev=179962&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-array-runtime-bound.cpp (added)
+++ cfe/trunk/test/SemaCXX/cxx1y-array-runtime-bound.cpp Sat Apr 20 18:28:26 2013
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -std=c++1y %s -verify -pedantic-errors
+
+// FIXME: many diagnostics here say 'variably modified type'.
+// catch this case and say 'array of runtime bound' instead.
+
+namespace std { struct type_info; }
+
+struct S {
+ int arr[__SIZE_MAX__ / 32];
+};
+S s[32]; // expected-error {{array is too large}}
+
+int n;
+int a[n]; // expected-error {{not allowed at file scope}}
+
+struct T {
+ int a[n]; // expected-error {{fields must have a constant size}}
+ static int b[n]; // expected-error {{not allowed at file scope}}
+};
+
+int g(int n, int a[n]);
+
+template<typename T> struct X {};
+template<int N, int[N]> struct Y {};
+template<int[n]> struct Z {}; // expected-error {{of variably modified type}}
+
+int f(int n) {
+ int arb[n]; // expected-note 3{{here}}
+ [arb] {} (); // expected-error {{cannot be captured}}
+
+ // FIXME: an array of runtime bound can be captured by reference.
+ [&arb] { // expected-error {{cannot be captured}}
+ // Capturing the array implicitly captures the bound, if we need it
+ // in a range-based for loop.
+ for (auto &n : arb) { } // expected-error {{cannot be captured}}
+ } ();
+
+ X<int[n]> x; // expected-error {{variably modified type}}
+
+ int arb_neg[-1]; // expected-error {{negative size}}
+ int arb_of_array[n][2];
+ int arr[3] = { 1, 2, 3, 4 }; // expected-error {{excess elements}}
+ char foo[4] = "fool"; // expected-error {{initializer-string for char array is too long}}
+
+ static int not_auto1[n]; // expected-error {{can not have 'static'}}
+ extern int not_auto2[n]; // expected-error {{can not have 'extern'}}
+ // FIXME: say 'thread_local' not 'static'.
+ thread_local int not_auto1[n]; // expected-error {{can not have 'static'}}
+
+ // FIXME: these should all be invalid.
+ auto &&ti1 = typeid(arb);
+ auto &&ti2 = typeid(int[n]);
+ auto &&so1 = sizeof(arb);
+ auto &&so2 = sizeof(int[n]);
+ auto *p = &arb;
+ decltype(arb) arb2;
+ int (*arbp)[n] = 0;
+ const int (&arbr)[n] = arbr; // expected-warning {{not yet bound}}
+ typedef int arbty[n];
+ int array_of_arb[2][n];
+
+ struct Dyn { Dyn() {} Dyn(int) {} ~Dyn() {} };
+
+ // FIXME: these should be valid.
+ int arb_dynamic[n] = { 1, 2, 3, 4 }; // expected-error {{may not be initialized}}
+ Dyn dyn[n]; // expected-error {{non-POD}}
+ Dyn dyn_init[n] = { 1, 2, 3, 4 }; // expected-error {{non-POD}}
+}
Modified: cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp?rev=179962&r1=179961&r2=179962&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp Sat Apr 20 18:28:26 2013
@@ -44,3 +44,8 @@ int k = 0b1001;
#ifdef CXX1Y
// expected-warning at -2 {{binary integer literals are incompatible with C++ standards before C++1y}}
#endif
+
+void f(int n) { int a[n]; }
+#ifdef CXX1Y
+// expected-warning at -2 {{arrays of runtime bound are incompatible with C++ standards before C++1y}}
+#endif
More information about the cfe-commits
mailing list