]> granicus.if.org Git - clang/commitdiff
Check for unexpanded parameter packs in friend declarations.
authorDouglas Gregor <dgregor@apple.com>
Thu, 16 Dec 2010 01:14:37 +0000 (01:14 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 16 Dec 2010 01:14:37 +0000 (01:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121934 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
test/CXX/temp/temp.decls/temp.variadic/p5.cpp

index 8095b946565ed9e98b31f90e0c61b8898b60ccc0..89755cba17b33fd3fd104d768364d0592107dc68 100644 (file)
@@ -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<
index c48f40403c1147e0051e6f760a9d22fb3c2178ed..97278076764cc62b7e8f5f381b122fdf7baef03f 100644 (file)
@@ -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,
index c3384a51628b8ed06199f19a4906ec23d41a9374..b46561851cd0fcef2153cd3a3ed4a5561edfef6e 100644 (file)
@@ -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) {
index 4a9abec5838de62120d89be62603903af6512b3c..0cf5f99b6448b77b6cedf7156304b93ff167b326 100644 (file)
@@ -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;
index a1c07c96fe7c99d80b3faba9199b46f8e56afdd1..7e5aff6fb0bb43cd3f7d1f52c982249dc4353f79 100644 (file)
@@ -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