[cfe-commits] r104471 - in /cfe/trunk: 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

Douglas Gregor dgregor at apple.com
Sun May 23 12:57:01 PDT 2010


Author: dgregor
Date: Sun May 23 14:57:01 2010
New Revision: 104471

URL: http://llvm.org/viewvc/llvm-project?rev=104471&view=rev
Log:
It turns out that people love using VLAs in templates, too. Weaken our
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).

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

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=104471&r1=104470&r2=104471&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun May 23 14:57:01 2010
@@ -41,9 +41,8 @@
   "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<

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=104471&r1=104470&r2=104471&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sun May 23 14:57:01 2010
@@ -277,6 +277,9 @@
 /// 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;

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=104471&r1=104470&r2=104471&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sun May 23 14:57:01 2010
@@ -534,6 +534,14 @@
 /// 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 @@
       // 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

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=104471&r1=104470&r2=104471&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Sun May 23 14:57:01 2010
@@ -716,15 +716,11 @@
           << 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);

Modified: cfe/trunk/test/SemaCXX/c99-variable-length-array.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/c99-variable-length-array.cpp?rev=104471&r1=104470&r2=104471&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/c99-variable-length-array.cpp (original)
+++ cfe/trunk/test/SemaCXX/c99-variable-length-array.cpp Sun May 23 14:57:01 2010
@@ -20,10 +20,10 @@
   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 @@
 
 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 @@
 
 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 {
     
   };

Modified: cfe/trunk/www/cxx_compatibility.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_compatibility.html?rev=104471&r1=104470&r2=104471&view=diff
==============================================================================
--- cfe/trunk/www/cxx_compatibility.html (original)
+++ cfe/trunk/www/cxx_compatibility.html Sun May 23 14:57:01 2010
@@ -53,11 +53,8 @@
   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:
 





More information about the cfe-commits mailing list