r327705 - Implement C++ DR727, which permits explicit specializations at class scope.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 16 06:36:57 PDT 2018
Author: rsmith
Date: Fri Mar 16 06:36:56 2018
New Revision: 327705
URL: http://llvm.org/viewvc/llvm-project?rev=327705&view=rev
Log:
Implement C++ DR727, which permits explicit specializations at class scope.
More generally, this permits a template to be specialized in any scope in which
it could be defined, so this also supersedes DR44 and DR374 (the latter of
which we previously only implemented in C++11 mode onwards due to unclarity as
to whether it was a DR).
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/ASTDumper.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/CXX/drs/dr0xx.cpp
cfe/trunk/test/CXX/drs/dr3xx.cpp
cfe/trunk/test/CXX/drs/dr7xx.cpp
cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp
cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
cfe/trunk/test/Misc/ast-dump-decl.cpp
cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
cfe/trunk/test/SemaCXX/cxx98-compat.cpp
cfe/trunk/test/SemaTemplate/class-template-spec.cpp
cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp
cfe/trunk/test/SemaTemplate/function-template-specialization.cpp
cfe/trunk/test/SemaTemplate/instantiate-method.cpp
cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp
cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp
cfe/trunk/www/cxx_dr_status.html
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Mar 16 06:36:56 2018
@@ -4144,42 +4144,20 @@ def note_explicit_specialization_declare
"explicit specialization declared here">;
def err_template_spec_decl_function_scope : Error<
"explicit specialization of %0 in function scope">;
-def err_template_spec_decl_class_scope : Error<
- "explicit specialization of %0 in class scope">;
def err_template_spec_decl_friend : Error<
"cannot declare an explicit specialization in a friend">;
-def err_template_spec_decl_out_of_scope_global : Error<
- "%select{class template|class template partial|variable template|"
- "variable template partial|function template|member function|"
- "static data member|member class|member enumeration}0 "
- "specialization of %1 must originally be declared in the global scope">;
-def err_template_spec_decl_out_of_scope : Error<
- "%select{class template|class template partial|variable template|"
- "variable template partial|function template|member "
- "function|static data member|member class|member enumeration}0 "
- "specialization of %1 must originally be declared in namespace %2">;
-def ext_template_spec_decl_out_of_scope : ExtWarn<
- "first declaration of %select{class template|class template partial|"
- "variable template|variable template partial|"
- "function template|member function|static data member|member class|"
- "member enumeration}0 specialization of %1 outside namespace %2 is a "
- "C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_template_spec_decl_out_of_scope : Warning<
- "%select{class template|class template partial|variable template|"
- "variable template partial|function template|member "
- "function|static data member|member class|member enumeration}0 "
- "specialization of %1 outside namespace %2 is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def err_template_spec_redecl_out_of_scope : Error<
"%select{class template|class template partial|variable template|"
"variable template partial|function template|member "
"function|static data member|member class|member enumeration}0 "
- "specialization of %1 not in a namespace enclosing %2">;
+ "specialization of %1 not in %select{a namespace enclosing %2|"
+ "class %2 or an enclosing namespace}3">;
def ext_ms_template_spec_redecl_out_of_scope: ExtWarn<
"%select{class template|class template partial|variable template|"
"variable template partial|function template|member "
"function|static data member|member class|member enumeration}0 "
- "specialization of %1 outside namespace enclosing %2 "
+ "specialization of %1 not in %select{a namespace enclosing %2|"
+ "class %2 or an enclosing namespace}3 "
"is a Microsoft extension">, InGroup<MicrosoftTemplate>;
def err_template_spec_redecl_global_scope : Error<
"%select{class template|class template partial|variable template|"
@@ -4201,11 +4179,6 @@ def err_template_spec_default_arg : Erro
def err_not_class_template_specialization : Error<
"cannot specialize a %select{dependent template|template template "
"parameter}0">;
-def err_function_specialization_in_class : Error<
- "cannot specialize a function %0 within class scope">;
-def ext_function_specialization_in_class : ExtWarn<
- "explicit specialization of %0 within class scope is a Microsoft extension">,
- InGroup<MicrosoftTemplate>;
def ext_explicit_specialization_storage_class : ExtWarn<
"explicit specialization cannot have a storage class">;
def err_explicit_specialization_inconsistent_storage_class : Error<
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Mar 16 06:36:56 2018
@@ -1849,8 +1849,8 @@ public:
void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S);
bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
- DeclarationName Name,
- SourceLocation Loc);
+ DeclarationName Name, SourceLocation Loc,
+ bool IsTemplateId);
void
diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
SourceLocation FallbackLoc,
Modified: cfe/trunk/lib/AST/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)
+++ cfe/trunk/lib/AST/ASTDumper.cpp Fri Mar 16 06:36:56 2018
@@ -1602,7 +1602,7 @@ void ASTDumper::VisitClassTemplatePartia
void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
const ClassScopeFunctionSpecializationDecl *D) {
- dumpDeclRef(D->getSpecialization());
+ dumpDecl(D->getSpecialization());
if (D->hasExplicitTemplateArgs())
dumpTemplateArgumentListInfo(D->templateArgs());
}
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Mar 16 06:36:56 2018
@@ -5231,10 +5231,13 @@ bool Sema::DiagnoseClassNameShadow(DeclC
///
/// \param Loc The location of the name of the entity being declared.
///
+/// \param IsTemplateId Whether the name is a (simple-)template-id, and thus
+/// we're declaring an explicit / partial specialization / instantiation.
+///
/// \returns true if we cannot safely recover from this error, false otherwise.
bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
DeclarationName Name,
- SourceLocation Loc) {
+ SourceLocation Loc, bool IsTemplateId) {
DeclContext *Cur = CurContext;
while (isa<LinkageSpecDecl>(Cur) || isa<CapturedDecl>(Cur))
Cur = Cur->getParent();
@@ -5261,8 +5264,9 @@ bool Sema::diagnoseQualifiedDeclaration(
}
// Check whether the qualifying scope encloses the scope of the original
- // declaration.
- if (!Cur->Encloses(DC)) {
+ // declaration. For a template-id, we perform the checks in
+ // CheckTemplateSpecializationScope.
+ if (!Cur->Encloses(DC) && !IsTemplateId) {
if (Cur->isRecord())
Diag(Loc, diag::err_member_qualification)
<< Name << SS.getRange();
@@ -5374,8 +5378,9 @@ NamedDecl *Sema::HandleDeclarator(Scope
return nullptr;
}
if (!D.getDeclSpec().isFriendSpecified()) {
- if (diagnoseQualifiedDeclaration(D.getCXXScopeSpec(), DC,
- Name, D.getIdentifierLoc())) {
+ if (diagnoseQualifiedDeclaration(
+ D.getCXXScopeSpec(), DC, Name, D.getIdentifierLoc(),
+ D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId)) {
if (DC->isRecord())
return nullptr;
@@ -8828,10 +8833,6 @@ Sema::ActOnFunctionDeclarator(Scope *S,
if (CurContext->isDependentContext() && CurContext->isRecord()
&& !isFriend) {
isDependentClassScopeExplicitSpecialization = true;
- Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ?
- diag::ext_function_specialization_in_class :
- diag::err_function_specialization_in_class)
- << NewFD->getDeclName();
} else if (!NewFD->isInvalidDecl() &&
CheckFunctionTemplateSpecialization(
NewFD, (HasExplicitTemplateArgs ? &TemplateArgs : nullptr),
@@ -9117,12 +9118,12 @@ Sema::ActOnFunctionDeclarator(Scope *S,
}
// Here we have an function template explicit specialization at class scope.
- // The actually specialization will be postponed to template instatiation
+ // The actual specialization will be postponed to template instatiation
// time via the ClassScopeFunctionSpecializationDecl node.
if (isDependentClassScopeExplicitSpecialization) {
ClassScopeFunctionSpecializationDecl *NewSpec =
ClassScopeFunctionSpecializationDecl::Create(
- Context, CurContext, SourceLocation(),
+ Context, CurContext, NewFD->getLocation(),
cast<CXXMethodDecl>(NewFD),
HasExplicitTemplateArgs, TemplateArgs);
CurContext->addDecl(NewSpec);
@@ -9633,16 +9634,16 @@ bool Sema::CheckFunctionDeclaration(Scop
Previous.clear();
Previous.addDecl(OldDecl);
- if (FunctionTemplateDecl *OldTemplateDecl
- = dyn_cast<FunctionTemplateDecl>(OldDecl)) {
+ if (FunctionTemplateDecl *OldTemplateDecl =
+ dyn_cast<FunctionTemplateDecl>(OldDecl)) {
auto *OldFD = OldTemplateDecl->getTemplatedDecl();
NewFD->setPreviousDeclaration(OldFD);
adjustDeclContextForDeclaratorDecl(NewFD, OldFD);
FunctionTemplateDecl *NewTemplateDecl
= NewFD->getDescribedFunctionTemplate();
assert(NewTemplateDecl && "Template/non-template mismatch");
- if (auto *Method = dyn_cast<CXXMethodDecl>(NewFD)) {
- Method->setAccess(OldTemplateDecl->getAccess());
+ if (NewFD->isCXXClassMember()) {
+ NewFD->setAccess(OldTemplateDecl->getAccess());
NewTemplateDecl->setAccess(OldTemplateDecl->getAccess());
}
@@ -9668,7 +9669,7 @@ bool Sema::CheckFunctionDeclaration(Scop
// This needs to happen first so that 'inline' propagates.
NewFD->setPreviousDeclaration(OldFD);
adjustDeclContextForDeclaratorDecl(NewFD, OldFD);
- if (isa<CXXMethodDecl>(NewFD))
+ if (NewFD->isCXXClassMember())
NewFD->setAccess(OldFD->getAccess());
}
}
@@ -14310,13 +14311,10 @@ CreateNewDecl:
if (SS.isNotEmpty()) {
if (SS.isSet()) {
// If this is either a declaration or a definition, check the
- // nested-name-specifier against the current context. We don't do this
- // for explicit specializations, because they have similar checking
- // (with more specific diagnostics) in the call to
- // CheckMemberSpecialization, below.
- if (!isMemberSpecialization &&
- (TUK == TUK_Definition || TUK == TUK_Declaration) &&
- diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc))
+ // nested-name-specifier against the current context.
+ if ((TUK == TUK_Definition || TUK == TUK_Declaration) &&
+ diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc,
+ isMemberSpecialization))
Invalid = true;
New->setQualifierInfo(SS.getWithLocInContext(Context));
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Mar 16 06:36:56 2018
@@ -3051,7 +3051,9 @@ Sema::ActOnCXXMemberDeclarator(Scope *S,
// int X::member;
// };
if (DeclContext *DC = computeDeclContext(SS, false))
- diagnoseQualifiedDeclaration(SS, DC, Name, D.getIdentifierLoc());
+ diagnoseQualifiedDeclaration(SS, DC, Name, D.getIdentifierLoc(),
+ D.getName().getKind() ==
+ UnqualifiedIdKind::IK_TemplateId);
else
Diag(D.getIdentifierLoc(), diag::err_member_qualification)
<< Name << SS.getRange();
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Mar 16 06:36:56 2018
@@ -1262,7 +1262,7 @@ Sema::CheckClassTemplate(Scope *S, unsig
if (RebuildTemplateParamsInCurrentInstantiation(TemplateParams))
Invalid = true;
} else if (TUK != TUK_Friend && TUK != TUK_Reference)
- diagnoseQualifiedDeclaration(SS, SemanticContext, Name, NameLoc);
+ diagnoseQualifiedDeclaration(SS, SemanticContext, Name, NameLoc, false);
LookupQualifiedName(Previous, SemanticContext);
} else {
@@ -7124,120 +7124,43 @@ static bool CheckTemplateSpecializationS
}
// C++ [temp.expl.spec]p2:
- // An explicit specialization shall be declared in the namespace
- // of which the template is a member, or, for member templates, in
- // the namespace of which the enclosing class or enclosing class
- // template is a member. An explicit specialization of a member
- // function, member class or static data member of a class
- // template shall be declared in the namespace of which the class
- // template is a member. Such a declaration may also be a
- // definition. If the declaration is not a definition, the
- // specialization may be defined later in the name- space in which
- // the explicit specialization was declared, or in a namespace
- // that encloses the one in which the explicit specialization was
- // declared.
+ // An explicit specialization may be declared in any scope in which
+ // the corresponding primary template may be defined.
if (S.CurContext->getRedeclContext()->isFunctionOrMethod()) {
S.Diag(Loc, diag::err_template_spec_decl_function_scope)
<< Specialized;
return true;
}
- if (S.CurContext->isRecord() && !IsPartialSpecialization) {
- if (S.getLangOpts().MicrosoftExt) {
- // Do not warn for class scope explicit specialization during
- // instantiation, warning was already emitted during pattern
- // semantic analysis.
- if (!S.inTemplateInstantiation())
- S.Diag(Loc, diag::ext_function_specialization_in_class)
- << Specialized;
- } else {
- S.Diag(Loc, diag::err_template_spec_decl_class_scope)
- << Specialized;
- return true;
- }
- }
-
- if (S.CurContext->isRecord() &&
- !S.CurContext->Equals(Specialized->getDeclContext())) {
- // Make sure that we're specializing in the right record context.
- // Otherwise, things can go horribly wrong.
- S.Diag(Loc, diag::err_template_spec_decl_class_scope)
- << Specialized;
- return true;
- }
-
// C++ [temp.class.spec]p6:
- // A class template partial specialization may be declared or redeclared
- // in any namespace scope in which its definition may be defined (14.5.1
- // and 14.5.2).
- DeclContext *SpecializedContext
- = Specialized->getDeclContext()->getEnclosingNamespaceContext();
- DeclContext *DC = S.CurContext->getEnclosingNamespaceContext();
-
- // Make sure that this redeclaration (or definition) occurs in an enclosing
- // namespace.
- // Note that HandleDeclarator() performs this check for explicit
- // specializations of function templates, static data members, and member
- // functions, so we skip the check here for those kinds of entities.
- // FIXME: HandleDeclarator's diagnostics aren't quite as good, though.
- // Should we refactor that check, so that it occurs later?
- if (!DC->Encloses(SpecializedContext) &&
- !(isa<FunctionTemplateDecl>(Specialized) ||
- isa<FunctionDecl>(Specialized) ||
- isa<VarTemplateDecl>(Specialized) ||
- isa<VarDecl>(Specialized))) {
+ // A class template partial specialization may be declared in any
+ // scope in which the primary template may be defined.
+ DeclContext *SpecializedContext =
+ Specialized->getDeclContext()->getRedeclContext();
+ DeclContext *DC = S.CurContext->getRedeclContext();
+
+ // Make sure that this redeclaration (or definition) occurs in the same
+ // scope or an enclosing namespace.
+ if (!(DC->isFileContext() ? DC->Encloses(SpecializedContext)
+ : DC->Equals(SpecializedContext))) {
if (isa<TranslationUnitDecl>(SpecializedContext))
S.Diag(Loc, diag::err_template_spec_redecl_global_scope)
<< EntityKind << Specialized;
- else if (isa<NamespaceDecl>(SpecializedContext)) {
+ else {
+ auto *ND = cast<NamedDecl>(SpecializedContext);
int Diag = diag::err_template_spec_redecl_out_of_scope;
- if (S.getLangOpts().MicrosoftExt)
+ if (S.getLangOpts().MicrosoftExt && !DC->isRecord())
Diag = diag::ext_ms_template_spec_redecl_out_of_scope;
S.Diag(Loc, Diag) << EntityKind << Specialized
- << cast<NamedDecl>(SpecializedContext);
- } else
- llvm_unreachable("unexpected namespace context for specialization");
+ << ND << isa<CXXRecordDecl>(ND);
+ }
S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
- } else if ((!PrevDecl ||
- getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared ||
- getTemplateSpecializationKind(PrevDecl) ==
- TSK_ImplicitInstantiation)) {
- // C++ [temp.exp.spec]p2:
- // An explicit specialization shall be declared in the namespace of which
- // the template is a member, or, for member templates, in the namespace
- // of which the enclosing class or enclosing class template is a member.
- // An explicit specialization of a member function, member class or
- // static data member of a class template shall be declared in the
- // namespace of which the class template is a member.
- //
- // C++11 [temp.expl.spec]p2:
- // An explicit specialization shall be declared in a namespace enclosing
- // the specialized template.
- // C++11 [temp.explicit]p3:
- // An explicit instantiation shall appear in an enclosing namespace of its
- // template.
- if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) {
- bool IsCPlusPlus11Extension = DC->Encloses(SpecializedContext);
- if (isa<TranslationUnitDecl>(SpecializedContext)) {
- assert(!IsCPlusPlus11Extension &&
- "DC encloses TU but isn't in enclosing namespace set");
- S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
- << EntityKind << Specialized;
- } else if (isa<NamespaceDecl>(SpecializedContext)) {
- int Diag;
- if (!IsCPlusPlus11Extension)
- Diag = diag::err_template_spec_decl_out_of_scope;
- else if (!S.getLangOpts().CPlusPlus11)
- Diag = diag::ext_template_spec_decl_out_of_scope;
- else
- Diag = diag::warn_cxx98_compat_template_spec_decl_out_of_scope;
- S.Diag(Loc, Diag)
- << EntityKind << Specialized << cast<NamedDecl>(SpecializedContext);
- }
- S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
- }
+ // Don't allow specializing in the wrong class during error recovery.
+ // Otherwise, things can go horribly wrong.
+ if (DC->isRecord())
+ return true;
}
return false;
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Mar 16 06:36:56 2018
@@ -1653,6 +1653,7 @@ Decl *TemplateDeclInstantiator::VisitFun
NameInfo, T, TInfo, D->getSourceRange().getEnd());
if (DGuide->isCopyDeductionCandidate())
cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate();
+ Function->setAccess(D->getAccess());
} else {
Function = FunctionDecl::Create(
SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo,
@@ -2711,6 +2712,8 @@ Decl *TemplateDeclInstantiator::VisitCla
assert(Specialization && "Class scope Specialization is null");
SemaRef.Context.setClassScopeSpecializationPattern(Specialization, OldFD);
+ // FIXME: If this is a definition, check for redefinition errors!
+
return NewFD;
}
Modified: cfe/trunk/test/CXX/drs/dr0xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr0xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr0xx.cpp Fri Mar 16 06:36:56 2018
@@ -499,10 +499,10 @@ namespace dr42 { // dr42: yes
// dr43: na
-namespace dr44 { // dr44: yes
+namespace dr44 { // dr44: sup 727
struct A {
template<int> void f();
- template<> void f<0>(); // expected-error {{explicit specialization of 'f' in class scope}}
+ template<> void f<0>();
};
}
Modified: cfe/trunk/test/CXX/drs/dr3xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr3xx.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr3xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr3xx.cpp Fri Mar 16 06:36:56 2018
@@ -925,7 +925,7 @@ namespace dr373 { // dr373: 5
using namespace A::B; // expected-error {{expected namespace name}}
}
-namespace dr374 { // dr374: yes c++11
+namespace dr374 { // dr374: yes
namespace N {
template<typename T> void f();
template<typename T> struct A { void f(); };
@@ -933,11 +933,6 @@ namespace dr374 { // dr374: yes c++11
template<> void N::f<char>() {}
template<> void N::A<char>::f() {}
template<> struct N::A<int> {};
-#if __cplusplus < 201103L
- // expected-error at -4 {{extension}} expected-note at -7 {{here}}
- // expected-error at -4 {{extension}} expected-note at -7 {{here}}
- // expected-error at -4 {{extension}} expected-note at -8 {{here}}
-#endif
}
// dr375: dup 345
Modified: cfe/trunk/test/CXX/drs/dr7xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr7xx.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr7xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr7xx.cpp Fri Mar 16 06:36:56 2018
@@ -3,6 +3,53 @@
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+namespace dr727 { // dr727: 7
+ struct A {
+ template<typename T> struct C; // expected-note 6{{here}}
+ template<typename T> void f(); // expected-note {{here}}
+ template<typename T> static int N; // expected-error 0-1{{C++14}} expected-note 6{{here}}
+
+ template<> struct C<int>;
+ template<> void f<int>();
+ template<> static int N<int>;
+
+ template<typename T> struct C<T*>;
+ template<typename T> static int N<T*>;
+
+ struct B {
+ template<> struct C<float>; // expected-error {{not in class 'A' or an enclosing namespace}}
+ template<> void f<float>(); // expected-error {{no function template matches}}
+ template<> static int N<float>; // expected-error {{not in class 'A' or an enclosing namespace}}
+
+ template<typename T> struct C<T**>; // expected-error {{not in class 'A' or an enclosing namespace}}
+ template<typename T> static int N<T**>; // expected-error {{not in class 'A' or an enclosing namespace}}
+
+ template<> struct A::C<double>; // expected-error {{not in class 'A' or an enclosing namespace}}
+ template<> void A::f<double>(); // expected-error {{no function template matches}} expected-error {{cannot have a qualified name}}
+ template<> static int A::N<double>; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}}
+
+ template<typename T> struct A::C<T***>; // expected-error {{not in class 'A' or an enclosing namespace}}
+ template<typename T> static int A::N<T***>; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}}
+ };
+ };
+
+ template<> struct A::C<char>;
+ template<> void A::f<char>();
+ template<> int A::N<char>;
+
+ template<typename T> struct A::C<T****>;
+ template<typename T> int A::N<T****>;
+
+ namespace C {
+ template<> struct A::C<long>; // expected-error {{not in class 'A' or an enclosing namespace}}
+ template<> void A::f<long>(); // expected-error {{not in class 'A' or an enclosing namespace}}
+ template<> int A::N<long>; // expected-error {{not in class 'A' or an enclosing namespace}}
+
+ template<typename T> struct A::C<T*****>; // expected-error {{not in class 'A' or an enclosing namespace}}
+ template<typename T> int A::N<T*****>; // expected-error {{not in class 'A' or an enclosing namespace}}
+ }
+}
+
namespace dr777 { // dr777: 3.7
#if __cplusplus >= 201103L
template <typename... T>
@@ -16,5 +63,3 @@ template <typename... T>
void h(int i = 0, T ...args, int j = 1) {}
#endif
}
-
-// expected-no-diagnostics
Modified: cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp Fri Mar 16 06:36:56 2018
@@ -101,7 +101,7 @@ namespace ExplicitInst {
struct X {
template<typename T> struct C {};
template<typename T> C(T) -> C<T>;
- template<> C(int) -> C<int>; // expected-error {{explicit specialization of '<deduction guide for C>' in class scope}}
+ template<> C(int) -> C<int>; // expected-error {{deduction guide cannot be explicitly specialized}}
extern template C(float) -> C<float>; // expected-error {{expected member name or ';'}}
template C(char) -> C<char>; // expected-error {{expected '<' after 'template'}}
};
Modified: cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp Fri Mar 16 06:36:56 2018
@@ -28,10 +28,8 @@ T pi1 = T(3.1415926535897932385); // exp
// Should recover as if specialization
template float pi1<float> = 1.0; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}}
-#ifndef FIXING
namespace expected_global {
- template<> double pi1<double> = 1.5; // expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}}
- template int pi1<int> = 10; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \
- expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}}
-}
+#ifndef FIXING
+ template int pi1<int> = 10; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} expected-error {{must occur at global scope}}
#endif
+}
Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp Fri Mar 16 06:36:56 2018
@@ -10,9 +10,6 @@ struct NonDefaultConstructible {
NonDefaultConstructible(int);
};
-// FIXME: The "must originally be declared in namespace" diagnostics throughout
-// this file are wrong.
-
// C++ [temp.expl.spec]p1:
// An explicit specialization of any of the following:
@@ -43,7 +40,7 @@ template<> void N0::f0(double) { }
struct X1 {
template<typename T> void f(T);
- template<> void f(int); // expected-error{{in class scope}}
+ template<> void f(int); // OK (DR727)
};
// -- class template
@@ -94,7 +91,7 @@ template<> struct N0::X0<volatile void>
// -- variable template [C++1y]
namespace N0 {
-template<typename T> int v0; // expected-note +{{here}}
+template<typename T> int v0; // expected-note 4{{explicitly specialized declaration is here}}
template<> extern int v0<char[1]>;
template<> extern int v0<char[2]>;
template<> extern int v0<char[5]>;
@@ -102,32 +99,32 @@ template<> extern int v0<char[6]>;
}
using N0::v0;
-template<typename T> int v1; // expected-note +{{here}}
+template<typename T> int v1; // expected-note 4{{explicitly specialized declaration is here}}
template<> extern int v1<char[3]>;
template<> extern int v1<char[4]>;
template<> extern int v1<char[7]>;
template<> extern int v1<char[8]>;
template<> int N0::v0<int[1]>;
-template<> int v0<int[2]>; // FIXME: ill-formed
+template<> int v0<int[2]>;
template<> int ::v1<int[3]>; // expected-warning {{extra qualification}}
template<> int v1<int[4]>;
template<> int N0::v0<char[1]>;
-template<> int v0<char[2]>; // FIXME: ill-formed
+template<> int v0<char[2]>;
template<> int ::v1<char[3]>; // expected-warning {{extra qualification}}
template<> int v1<char[4]>;
namespace N1 {
-template<> int N0::v0<int[5]>; // expected-error {{must originally be declared in namespace 'N0'}} expected-error {{does not enclose namespace}}
-template<> int v0<int[6]>; // expected-error {{must originally be declared in namespace 'N0'}}
-template<> int ::v1<int[7]>; // expected-error {{must originally be declared in the global scope}} expected-error {{cannot name the global scope}}
-template<> int v1<int[8]>; // expected-error {{must originally be declared in the global scope}}
-
-template<> int N0::v0<char[5]>; // expected-error {{does not enclose namespace 'N0'}}
-template<> int v0<char[6]>; // FIXME: ill-formed
-template<> int ::v1<char[7]>; // expected-error {{cannot name the global scope}}
-template<> int v1<char[8]>; // FIXME: ill-formed
+template<> int N0::v0<int[5]>; // expected-error {{not in a namespace enclosing 'N0'}}
+template<> int v0<int[6]>; // expected-error {{not in a namespace enclosing 'N0'}}
+template<> int ::v1<int[7]>; // expected-error {{must occur at global scope}}
+template<> int v1<int[8]>; // expected-error {{must occur at global scope}}
+
+template<> int N0::v0<char[5]>; // expected-error {{not in a namespace enclosing 'N0'}}
+template<> int v0<char[6]>; // expected-error {{not in a namespace enclosing 'N0'}}
+template<> int ::v1<char[7]>; // expected-error {{must occur at global scope}}
+template<> int v1<char[8]>; // expected-error {{must occur at global scope}}
}
// -- member function of a class template
Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp Fri Mar 16 06:36:56 2018
@@ -20,9 +20,6 @@ struct NonDefaultConstructible {
// -- function template
namespace N0 {
template<typename T> void f0(T) {
-#if __cplusplus <= 199711L
- // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
T t;
}
@@ -43,16 +40,13 @@ namespace N1 {
}
template<> void N0::f0(double);
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of function template specialization of 'f0' outside namespace 'N0' is a C++11 extension}}
-#endif
template<> void N0::f0(double) { }
struct X1 {
template<typename T> void f(T);
- template<> void f(int); // expected-error{{in class scope}}
+ template<> void f(int);
};
// -- class template
@@ -60,38 +54,20 @@ namespace N0 {
template<typename T>
struct X0 { // expected-note {{explicitly specialized declaration is here}}
-#if __cplusplus <= 199711L
-// expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
static T member;
-#if __cplusplus <= 199711L
- // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
void f1(T t) {
-#if __cplusplus <= 199711L
- // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
t = 17;
}
struct Inner : public T { }; // expected-note 2{{explicitly specialized declaration is here}}
-#if __cplusplus <= 199711L
- // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
template<typename U>
struct InnerTemplate : public T { }; // expected-note {{explicitly specialized declaration is here}}
-#if __cplusplus <= 199711L
- // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
- // expected-error at -4 {{base specifier must name a class}}
+ // expected-error at -1 {{base specifier must name a class}}
template<typename U>
void ft1(T t, U u);
-#if __cplusplus <= 199711L
- // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
};
}
@@ -105,9 +81,6 @@ void N0::X0<T>::ft1(T t, U u) {
template<typename T> T N0::X0<T>::member;
template<> struct N0::X0<void> { };
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of class template specialization of 'X0' outside namespace 'N0' is a C++11 extension}}
-#endif
N0::X0<void> test_X0;
namespace N1 {
@@ -124,9 +97,6 @@ template<> struct N0::X0<volatile void>
// -- member function of a class template
template<> void N0::X0<void*>::f1(void *) { }
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of member function specialization of 'f1' outside namespace 'N0' is a C++11 extension}}
-#endif
void test_spec(N0::X0<void*> xvp, void *vp) {
xvp.f1(vp);
@@ -160,9 +130,6 @@ NonDefaultConstructible &get_static_memb
}
template<> int N0::X0<int>::member;
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of static data member specialization of 'member' outside namespace 'N0' is a C++11 extension}}
-#endif
template<> float N0::X0<float>::member = 3.14f;
@@ -191,9 +158,6 @@ namespace N0 {
template<>
struct N0::X0<long>::Inner { };
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of member class specialization of 'Inner' outside namespace 'N0' is a C++11 extension}}
-#endif
template<>
struct N0::X0<float>::Inner { };
@@ -233,9 +197,6 @@ struct N0::X0<int>::InnerTemplate<long>
template<> template<>
struct N0::X0<int>::InnerTemplate<float> { };
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of class template specialization of 'InnerTemplate' outside namespace 'N0' is a C++11 extension}}
-#endif
namespace N1 {
template<> template<>
@@ -268,9 +229,6 @@ void N0::X0<void*>::ft1(void *, unsigned
template<> template<>
void N0::X0<void*>::ft1(void *, float) { }
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of function template specialization of 'ft1' outside namespace 'N0' is a C++11 extension}}
-#endif
namespace N1 {
template<> template<>
@@ -293,6 +251,6 @@ namespace PR8979 {
template<typename T, typename U> void f(Inner<T, U>&);
typedef Inner<OtherInner, OtherInner> MyInner;
- template<> void f(MyInner&); // expected-error{{cannot specialize a function 'f' within class scope}}
+ template<> void f(MyInner&);
};
}
Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp Fri Mar 16 06:36:56 2018
@@ -4,17 +4,9 @@
namespace N {
template<class T> class X; // expected-note {{'N::X' declared here}}
-#if __cplusplus <= 199711L
- // expected-note at -2 {{explicitly specialized declaration is here}}
-#endif
}
-// TODO: Don't add a namespace qualifier to the template if it would trigger
-// the warning about the specialization being outside of the namespace.
template<> class X<int> { /* ... */ }; // expected-error {{no template named 'X'; did you mean 'N::X'?}}
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of class template specialization of 'X' outside namespace 'N' is a C++11 extension}}
-#endif
namespace N {
Modified: cfe/trunk/test/Misc/ast-dump-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-decl.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/Misc/ast-dump-decl.cpp (original)
+++ cfe/trunk/test/Misc/ast-dump-decl.cpp Fri Mar 16 06:36:56 2018
@@ -360,7 +360,9 @@ class TestClassScopeFunctionSpecializati
template<> void foo<int>(int a) { }
};
// CHECK: ClassScopeFunctionSpecializationDecl
-// CHECK-NEXT: CXXMethod{{.*}} 'foo' 'void (int)'
+// CHECK-NEXT: CXXMethod{{.*}} foo 'void (int)'
+// CHECK-NEXT: ParmVarDecl
+// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: TemplateArgument{{.*}} 'int'
namespace TestTemplateTypeParmDecl {
Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Fri Mar 16 06:36:56 2018
@@ -489,7 +489,6 @@ void AfterClassBody() {
namespace PR24246 {
template <typename TX> struct A {
template <bool> struct largest_type_select;
- // expected-warning at +1 {{explicit specialization of 'largest_type_select' within class scope is a Microsoft extension}}
template <> struct largest_type_select<false> {
blah x; // expected-error {{unknown type name 'blah'}}
};
Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp Fri Mar 16 06:36:56 2018
@@ -15,8 +15,8 @@ class A {
template<typename T> static CONST T right<T,int> = 5;
template<typename T> CONST int right<int,T>; // expected-error {{member 'right' declared as a template}}
template<typename T> CONST float right<float,T> = 5; // expected-error {{member 'right' declared as a template}}
- template<> static CONST int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}}
- template<> static CONST float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}}
+ template<> static CONST int right<int,int> = 7;
+ template<> static CONST float right<float,int>;
template static CONST int right<int,int>; // expected-error {{expected '<' after 'template'}}
};
@@ -163,8 +163,8 @@ namespace constexpred {
template<typename T> constexpr int right<int,T>; // expected-error {{member 'right' declared as a template}} \
// expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
template<typename T> constexpr float right<float,T> = 5; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}}
- template<> static constexpr int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}}
- template<> static constexpr float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}}
+ template<> static constexpr int right<int,int> = 7;
+ template<> static constexpr float right<float,int>; // expected-error {{requires an initializer}}
template static constexpr int right<int,int>; // expected-error {{expected '<' after 'template'}}
};
}
Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp Fri Mar 16 06:36:56 2018
@@ -409,7 +409,7 @@ namespace nested {
#endif
float f1 = pi1a<float>;
- template<> double pi1a<double> = 5.2; // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}}
+ template<> double pi1a<double> = 5.2; // expected-error {{not in a namespace enclosing 'n1'}}
double d1 = pi1a<double>;
}
@@ -422,8 +422,7 @@ namespace nested {
#endif
float f1 = n1::pi1b<float>;
- template<> double n1::pi1b<double> = 5.2; // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \
- // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}}
+ template<> double n1::pi1b<double> = 5.2; // expected-error {{not in a namespace enclosing 'n1'}}
double d1 = n1::pi1b<double>;
}
}
Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Fri Mar 16 06:36:56 2018
@@ -185,9 +185,9 @@ namespace RedundantParensInAddressTempla
}
namespace TemplateSpecOutOfScopeNs {
- template<typename T> struct S {}; // expected-note {{here}}
+ template<typename T> struct S {};
}
-template<> struct TemplateSpecOutOfScopeNs::S<char> {}; // expected-warning {{class template specialization of 'S' outside namespace 'TemplateSpecOutOfScopeNs' is incompatible with C++98}}
+template<> struct TemplateSpecOutOfScopeNs::S<char> {};
struct Typename {
template<typename T> struct Inner {};
Modified: cfe/trunk/test/SemaTemplate/class-template-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-spec.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/class-template-spec.cpp (original)
+++ cfe/trunk/test/SemaTemplate/class-template-spec.cpp Fri Mar 16 06:36:56 2018
@@ -78,9 +78,6 @@ template<> struct ::A<double>;
namespace N {
template<typename T> struct B; // expected-note {{explicitly specialized}}
-#if __cplusplus <= 199711L
- // expected-note at -2 {{explicitly specialized}}
-#endif
template<> struct ::N::B<char>; // okay
template<> struct ::N::B<short>; // okay
@@ -92,9 +89,6 @@ namespace N {
template<> struct N::B<int> { }; // okay
template<> struct N::B<float> { };
-#if __cplusplus <= 199711L
-// expected-warning at -2 {{first declaration of class template specialization of 'B' outside namespace 'N' is a C++11 extension}}
-#endif
namespace M {
@@ -121,9 +115,9 @@ class Wibble<int> { }; // expected-error
namespace rdar9676205 {
template<typename T>
- struct X {
+ struct X { // expected-note {{here}}
template<typename U>
- struct X<U*> { // expected-error{{explicit specialization of 'X' in class scope}}
+ struct X<U*> { // expected-error{{partial specialization of 'X' not in a namespace enclosing}}
};
};
Modified: cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp (original)
+++ cfe/trunk/test/SemaTemplate/ext_ms_template_spec.cpp Fri Mar 16 06:36:56 2018
@@ -18,16 +18,16 @@ template <typename T> struct X {
namespace B {
template <>
-class A::ClassTemplate<int>; // expected-warning {{class template specialization of 'ClassTemplate' outside namespace enclosing 'A' is a Microsoft extension}}
+class A::ClassTemplate<int>; // expected-warning {{class template specialization of 'ClassTemplate' not in a namespace enclosing 'A' is a Microsoft extension}}
template <class T1>
-class A::ClassTemplatePartial<T1, T1 *> {}; // expected-warning {{class template partial specialization of 'ClassTemplatePartial' outside namespace enclosing 'A' is a Microsoft extension}}
+class A::ClassTemplatePartial<T1, T1 *> {}; // expected-warning {{class template partial specialization of 'ClassTemplatePartial' not in a namespace enclosing 'A' is a Microsoft extension}}
template <>
-struct A::X<int>::MemberClass; // expected-warning {{member class specialization of 'MemberClass' outside namespace enclosing 'A' is a Microsoft extension}}
+struct A::X<int>::MemberClass; // expected-warning {{member class specialization of 'MemberClass' not in class 'X' or an enclosing namespace is a Microsoft extension}}
template <>
-enum A::X<int>::MemberEnumeration; // expected-warning {{member enumeration specialization of 'MemberEnumeration' outside namespace enclosing 'A' is a Microsoft extension}} // expected-error {{ISO C++ forbids forward references to 'enum' types}}
+enum A::X<int>::MemberEnumeration; // expected-warning {{member enumeration specialization of 'MemberEnumeration' not in class 'X' or an enclosing namespace is a Microsoft extension}} // expected-error {{ISO C++ forbids forward references to 'enum' types}}
}
Modified: cfe/trunk/test/SemaTemplate/function-template-specialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/function-template-specialization.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/function-template-specialization.cpp (original)
+++ cfe/trunk/test/SemaTemplate/function-template-specialization.cpp Fri Mar 16 06:36:56 2018
@@ -54,5 +54,5 @@ class Foo {
// Don't crash here.
template<>
- static void Bar(const long& input) {} // expected-error{{explicit specialization of 'Bar' in class scope}}
+ static void Bar(const long& input) {} // expected-warning{{explicit specialization cannot have a storage class}}
};
Modified: cfe/trunk/test/SemaTemplate/instantiate-method.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-method.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-method.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-method.cpp Fri Mar 16 06:36:56 2018
@@ -185,7 +185,7 @@ namespace SameSignatureAfterInstantiatio
namespace PR22040 {
template <typename T> struct Foobar {
- template <> void bazqux(typename T::type) {} // expected-error {{cannot specialize a function 'bazqux' within class scope}} expected-error 2{{cannot be used prior to '::' because it has no members}}
+ template <> void bazqux(typename T::type) {} // expected-error 2{{cannot be used prior to '::' because it has no members}}
};
void test() {
Modified: cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp (original)
+++ cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp Fri Mar 16 06:36:56 2018
@@ -1,18 +1,15 @@
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s
+// expected-no-diagnostics
class A {
public:
template<class U> A(U p) {}
- template<> A(int p) {
- // expected-warning at -1 {{explicit specialization of 'A' within class scope is a Microsoft extension}}
- }
+ template<> A(int p) {}
template<class U> void f(U p) {}
- template<> void f(int p) {
- // expected-warning at -1 {{explicit specialization of 'f' within class scope is a Microsoft extension}}
- }
+ template<> void f(int p) {}
void f(int p) {}
};
@@ -28,14 +25,11 @@ void test1() {
template<class T> class B {
public:
template<class U> B(U p) {}
- template<> B(int p) {
- // expected-warning at -1 {{explicit specialization of 'B<T>' within class scope is a Microsoft extension}}
- }
+ template<> B(int p) {}
template<class U> void f(U p) { T y = 9; }
template<> void f(int p) {
- // expected-warning at -1 {{explicit specialization of 'f' within class scope is a Microsoft extension}}
T a = 3;
}
@@ -56,9 +50,7 @@ namespace PR12709 {
template<bool b> void specialized_member_template() {}
- template<> void specialized_member_template<false>() {
- // expected-warning at -1 {{explicit specialization of 'specialized_member_template' within class scope is a Microsoft extension}}
- }
+ template<> void specialized_member_template<false>() {}
};
void f() { TemplateClass<int> t; }
@@ -67,8 +59,8 @@ namespace PR12709 {
namespace Duplicates {
template<typename T> struct A {
template<typename U> void f();
- template<> void f<int>() {} // expected-warning {{Microsoft extension}}
- template<> void f<T>() {} // expected-warning {{Microsoft extension}}
+ template<> void f<int>() {}
+ template<> void f<T>() {}
};
// FIXME: We should diagnose the duplicate explicit specialization definitions
@@ -81,6 +73,6 @@ struct S {
template <int>
int f(int = 0);
template <>
- int f<0>(int); // expected-warning {{Microsoft extension}}
+ int f<0>(int);
};
}
Modified: cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp Fri Mar 16 06:36:56 2018
@@ -7,17 +7,11 @@ template<typename T> struct vector;
namespace N {
namespace M {
template<typename T> struct A;
-#if __cplusplus <= 199711L // C++03 or earlier modes
- // expected-note at -2{{explicitly specialized declaration is here}}
-#endif
}
}
template<typename T>
struct N::M::A<T*> { };
-#if __cplusplus <= 199711L
-// expected-warning at -2{{first declaration of class template partial specialization of 'A' outside namespace 'M' is a C++11 extension}}
-#endif
// C++ [temp.class.spec]p9
// bullet 1, as amended by DR1315
Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=327705&r1=327704&r2=327705&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Fri Mar 16 06:36:56 2018
@@ -303,7 +303,7 @@
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#44">44</a></td>
<td>CD1</td>
<td>Member specializations</td>
- <td class="full" align="center">Yes</td>
+ <td class="svn" align="center">Superseded by <a href="#727">727</a></td>
</tr>
<tr id="45">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45">45</a></td>
@@ -2285,7 +2285,7 @@ of class templates</td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374">374</a></td>
<td>CD2</td>
<td>Can explicit specialization outside namespace use qualified name?</td>
- <td class="full" align="center">Yes (C++11 onwards)</td>
+ <td class="full" align="center">Yes</td>
</tr>
<tr id="375">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#375">375</a></td>
@@ -4387,7 +4387,7 @@ and <I>POD class</I></td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#727">727</a></td>
<td>C++17</td>
<td>In-class explicit specializations</td>
- <td class="none" align="center">Unknown</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr class="open" id="728">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#728">728</a></td>
More information about the cfe-commits
mailing list