From: David Majnemer Date: Tue, 25 Jun 2013 22:08:55 +0000 (+0000) Subject: Implement DR21 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=87b12b2e92c1670e551d66938a4c0a055b18b03a;p=clang Implement DR21 A default template-argument shall not be specified in a friend template declaration. Interestingly, we properly handled default template arguments on friend class members but not on just friend classes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184882 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 82de36908c..6d8c790580 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -4938,6 +4938,7 @@ public: TPC_ClassTemplate, TPC_FunctionTemplate, TPC_ClassTemplateMember, + TPC_FriendClassTemplate, TPC_FriendFunctionTemplate, TPC_FriendFunctionTemplateDefinition, TPC_TypeAliasTemplate diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 88b24a1702..6c0658f05f 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1033,13 +1033,14 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // template declaration. Skip this check for a friend in a dependent // context, because the template parameter list might be dependent. if (!(TUK == TUK_Friend && CurContext->isDependentContext()) && - CheckTemplateParameterList(TemplateParams, - PrevClassTemplate? PrevClassTemplate->getTemplateParameters() : 0, - (SS.isSet() && SemanticContext && - SemanticContext->isRecord() && - SemanticContext->isDependentContext()) - ? TPC_ClassTemplateMember - : TPC_ClassTemplate)) + CheckTemplateParameterList( + TemplateParams, + PrevClassTemplate ? PrevClassTemplate->getTemplateParameters() : 0, + (SS.isSet() && SemanticContext && SemanticContext->isRecord() && + SemanticContext->isDependentContext()) + ? TPC_ClassTemplateMember + : TUK == TUK_Friend ? TPC_FriendClassTemplate + : TPC_ClassTemplate)) Invalid = true; if (SS.isSet()) { @@ -1187,6 +1188,7 @@ static bool DiagnoseDefaultTemplateArgument(Sema &S, << DefArgRange; return true; + case Sema::TPC_FriendClassTemplate: case Sema::TPC_FriendFunctionTemplate: // C++ [temp.param]p9: // A default template-argument shall not be specified in a diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp index c51e8c82e4..e00264102e 100644 --- a/test/CXX/drs/dr0xx.cpp +++ b/test/CXX/drs/dr0xx.cpp @@ -223,12 +223,11 @@ namespace dr20 { // dr20: yes X x = f(); // expected-error {{private}} } -namespace dr21 { // dr21: no +namespace dr21 { // dr21: yes template struct A; struct X { - // FIXME: We should reject these, per [temp.param]p9. - template friend struct A; - template friend struct B; + template friend struct A; // expected-error {{default template argument not permitted on a friend template}} + template friend struct B; // expected-error {{default template argument not permitted on a friend template}} }; } diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html index eda94fb38a..dd8c7d233f 100644 --- a/www/cxx_dr_status.html +++ b/www/cxx_dr_status.html @@ -164,7 +164,7 @@ 21 TC1 Can a default argument for a template parameter appear in a friend declaration? - No + Yes 22