[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