]> granicus.if.org Git - clang/commitdiff
It turns out that people love using VLAs in templates, too. Weaken our
authorDouglas Gregor <dgregor@apple.com>
Sun, 23 May 2010 19:57:01 +0000 (19:57 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sun, 23 May 2010 19:57:01 +0000 (19:57 +0000)
VLA restrictions so that one can use VLAs in templates (even
accidentally), but not as part of a non-type template parameter (which
would be very bad).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104471 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/Type.cpp
lib/Sema/SemaTemplate.cpp
lib/Sema/SemaType.cpp
test/SemaCXX/c99-variable-length-array.cpp
www/cxx_compatibility.html

index 5b7b0c566cc5e27b4039eb7f75f4e2aa723dbb94..da7601d0ec45903ffa416e0ae22c2856927ad5f0 100644 (file)
@@ -41,9 +41,8 @@ def ext_vla : Extension<
   "variable length arrays are a C99 feature, accepted as an extension">,
   InGroup<VLA>;
 def err_vla_non_pod : Error<"variable length array of non-POD element type %0">;
-def err_vla_in_template : Error<
-  "variable length array cannot be used in a template %select{definition|"
-  "instantiation}0">;
+def err_vla_in_sfinae : Error<
+  "variable length array cannot be formed during template argument deduction">;
 def err_array_star_in_function_definition : Error<
   "variable length array must be bound in function definition">;
 def err_vla_decl_in_file_scope : Error<
index a7527e7ccfa8c533c877a1e86165d39b6896dd7c..1aab65ebec55a5a406215668b6b7c805084926d9 100644 (file)
@@ -277,6 +277,9 @@ QualType Type::getPointeeType() const {
 /// array types and types that contain variable array types in their
 /// declarator
 bool Type::isVariablyModifiedType() const {
+  // FIXME: We should really keep a "variably modified" bit in Type, rather
+  // than walking the type hierarchy to recompute it.
+  
   // A VLA is a variably modified type.
   if (isVariableArrayType())
     return true;
index ecac7a212a53fd202e31537d1e1fd665ab5f08ab..307be9d78658b7eee7cd95f99264c9ac0a8c9717 100644 (file)
@@ -534,6 +534,14 @@ void Sema::ActOnTypeParameterDefault(DeclPtrTy TypeParam,
 /// otherwise, produces a diagnostic and returns a NULL type.
 QualType
 Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
+  // We don't allow variably-modified types as the type of non-type template
+  // parameters.
+  if (T->isVariablyModifiedType()) {
+    Diag(Loc, diag::err_variably_modified_nontype_template_param)
+      << T;
+    return QualType();
+  }
+
   // C++ [temp.param]p4:
   //
   // A non-type template-parameter shall have one of the following
@@ -553,13 +561,6 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
       // assume that it is well-formed.
       T->isDependentType())
     return T;
-  // We don't allow variably-modified types as the type of non-type template
-  // parameters.
-  else if (T->isVariablyModifiedType()) {
-    Diag(Loc, diag::err_variably_modified_nontype_template_param)
-      << T;
-    return QualType();
-  }
   // C++ [temp.param]p8:
   //
   //   A non-type template-parameter of type "array of T" or
index b25d0763591f7173b9da17bf0f32316ea0836cad..ea2b2e681250fdd07bf8d8b00d35e6081a2bfb29 100644 (file)
@@ -716,15 +716,11 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
           << Context.getBaseElementType(T);
         return QualType();
       } 
-      // Prohibit the use of VLAs in template instantiations, since we don't
-      // want them to accidentally be used. This means that we handle VLAs in
-      // C-like contexts, but still ban them from C++-specific contexts.
-      // And, since we check template definitions early, prohibit them there,
-      // too.
-      else if (CurContext->isDependentContext() ||
-               ActiveTemplateInstantiations.size())
-        Diag(Loc, diag::err_vla_in_template)
-          << !CurContext->isDependentContext();
+      // Prohibit the use of VLAs during template argument deduction.
+      else if (isSFINAEContext()) {
+        Diag(Loc, diag::err_vla_in_sfinae);
+        return QualType();
+      }
       // Just extwarn about VLAs.
       else
         Diag(Loc, diag::ext_vla);
index 8a2e35b012fc055dbf149434dae87b7c1ce77266..8a9bcb38cbff51859479923a334a3f12734b853b 100644 (file)
@@ -20,10 +20,10 @@ void vla(int N) {
   NonPOD2 array4[N][3]; // expected-error{{variable length array of non-POD element type 'NonPOD2'}}
 }
 
-// We disallow VLAs in templates
+/// Warn about 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}}
+  int array1[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
 }
 
 struct HasConstantValue {
@@ -36,7 +36,7 @@ struct HasNonConstantValue {
 
 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}}
+  int array2[T::value]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
 }
 
 template void vla_in_template<HasConstantValue>(HasConstantValue);
@@ -53,7 +53,8 @@ void inst_with_vla(int N) {
 
 template<typename T>
 struct X1 {
-  template<int (&Array)[T::value]> // expected-error{{variable length array cannot be used in a template instantiation}}
+  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, accepted as an extension}}
   struct Inner {
     
   };
index cfe3c0a60c9608f09fa72cbfc0902d550084f22a..fe032403d7c7aa9613f3eafbc6e384797feee098 100644 (file)
@@ -53,11 +53,8 @@ compatibility with GNU C and C99 programs:</p>
   user-declared constructors or destructors, base classes, or any
   members if non-POD type. All C types are POD types.</li>
 
-  <li>Variable length arrays cannot be used in conjunction with
-  templates. For example, one cannot use a variable length array
-  inside a template or use a variable length array type in a template
-  argument.</li>
-</ul>
+  <li>Variable length arrays cannot be used as the type of a non-type
+template parameter.</li> </ul>
 
 <p>If your code uses variable length arrays in a manner that Clang doesn't support, there are several ways to fix your code: