From 6ccab97c17c17f38eb92c7fe02c766508875bd97 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 16 Dec 2010 01:14:37 +0000 Subject: [PATCH] Check for unexpanded parameter packs in friend declarations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121934 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 8 ++++---- include/clang/Sema/Sema.h | 8 +++++++- lib/Sema/SemaDecl.cpp | 4 ++++ lib/Sema/SemaDeclCXX.cpp | 9 +++++++++ test/CXX/temp/temp.decls/temp.variadic/p5.cpp | 4 ++++ 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 8095b94656..89755cba17 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1824,22 +1824,22 @@ def note_template_parameter_pack_here : Note< def err_unexpanded_parameter_pack_0 : Error< "%select{expression|base type|declaration type|data member type|bit-field " "size|static assertion|fixed underlying type|enumerator value|" - "using declaration}0 " + "using declaration|friend declaration|qualifier}0 " "contains an unexpanded parameter pack">; def err_unexpanded_parameter_pack_1 : Error< "%select{expression|base type|declaration type|data member type|bit-field " "size|static assertion|fixed underlying type|enumerator value|" - "using declaration}0 " + "using declaration|friend declaration|qualifier}0 " "contains unexpanded parameter pack %1">; def err_unexpanded_parameter_pack_2 : Error< "%select{expression|base type|declaration type|data member type|bit-field " "size|static assertion|fixed underlying type|enumerator value|" - "using declaration}0 " + "using declaration|friend declaration|qualifier}0 " "contains unexpanded parameter packs %1 and %2">; def err_unexpanded_parameter_pack_3_or_more : Error< "%select{expression|base type|declaration type|data member type|bit-field " "size|static assertion|fixed underlying type|enumerator value|" - "using declaration}0 " + "using declaration|friend declaration|qualifier}0 " "contains unexpanded parameter packs %1, %2, ...">; def err_unexpected_typedef : Error< diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index c48f40403c..9727807676 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3160,7 +3160,13 @@ public: UPPC_EnumeratorValue, /// \brief A using declaration. - UPPC_UsingDeclaration + UPPC_UsingDeclaration, + + /// \brief A friend declaration. + UPPC_FriendDeclaration, + + /// \brief A declaration qualifier. + UPPC_DeclarationQualifier }; /// \brief If the given type contains an unexpanded parameter pack, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c3384a5162..b46561851c 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2332,6 +2332,10 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, if (D.getCXXScopeSpec().isInvalid()) D.setInvalidType(); else if (D.getCXXScopeSpec().isSet()) { + if (DiagnoseUnexpandedParameterPack(D.getCXXScopeSpec(), + UPPC_DeclarationQualifier)) + return 0; + bool EnteringContext = !D.getDeclSpec().isFriendSpecified(); DC = computeDeclContext(D.getCXXScopeSpec(), EnteringContext); if (!DC) { diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 4a9abec583..0cf5f99b64 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -6383,6 +6383,9 @@ Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS, if (TheDeclarator.isInvalidType()) return 0; + if (DiagnoseUnexpandedParameterPack(Loc, TSI, UPPC_FriendDeclaration)) + return 0; + // This is definitely an error in C++98. It's probably meant to // be forbidden in C++0x, too, but the specification is just // poorly written. @@ -6482,6 +6485,12 @@ Decl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D, bool IsDefinition, DeclarationName Name = NameInfo.getName(); assert(Name); + // Check for unexpanded parameter packs. + if (DiagnoseUnexpandedParameterPack(Loc, TInfo, UPPC_FriendDeclaration) || + DiagnoseUnexpandedParameterPack(NameInfo, UPPC_FriendDeclaration) || + DiagnoseUnexpandedParameterPack(SS, UPPC_FriendDeclaration)) + return 0; + // The context we found the declaration in, or in which we should // create the declaration. DeclContext *DC; diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index a1c07c96fe..7e5aff6fb0 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp @@ -121,6 +121,10 @@ struct TestUnexpandedDecls : T{ using typename Types::type; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}} using Types::value; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}} using T::operator Types; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}} + + friend class Types::foo; // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}} + friend void friend_func(Types); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}} + friend void Types::other_friend_func(int); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}} }; // Test for diagnostics in the presence of multiple unexpanded -- 2.40.0