diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 14 | ||||
-rw-r--r-- | test/SemaCXX/c99-variable-length-array.cpp | 9 | ||||
-rw-r--r-- | www/cxx_compatibility.html | 7 |
6 files changed, 25 insertions, 28 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5b7b0c566c..da7601d0ec 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index a7527e7ccf..1aab65ebec 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -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; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index ecac7a212a..307be9d786 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -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 diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index b25d076359..ea2b2e6812 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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); diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp index 8a2e35b012..8a9bcb38cb 100644 --- a/test/SemaCXX/c99-variable-length-array.cpp +++ b/test/SemaCXX/c99-variable-length-array.cpp @@ -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 { }; diff --git a/www/cxx_compatibility.html b/www/cxx_compatibility.html index cfe3c0a60c..fe032403d7 100644 --- a/www/cxx_compatibility.html +++ b/www/cxx_compatibility.html @@ -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: |