]> granicus.if.org Git - clang/commitdiff
Check for unexpanded parameter packs in various kinds of
authorDouglas Gregor <dgregor@apple.com>
Wed, 15 Dec 2010 23:18:36 +0000 (23:18 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 15 Dec 2010 23:18:36 +0000 (23:18 +0000)
declarations. This is a work in progress, as I go through the C++
declaration grammar to identify where unexpanded parameter packs can
occur.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121912 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 787a9b5aad3829f7982518b82036b4ba9189033e..78a7a17eb5e981aebebe3942084babeb605f3934 100644 (file)
@@ -1822,17 +1822,21 @@ def note_template_parameter_pack_here : Note<
   "parameter%select{| pack}1 declared here">;
   
 def err_unexpanded_parameter_pack_0 : Error<
-  "%select{expression|base type|declaration type|template argument}0 contains "
-  "unexpanded parameter pack">;
+  "%select{expression|base type|declaration type|data member type|bit-field "
+  "size}0 "
+  "contains unexpanded parameter pack">;
 def err_unexpanded_parameter_pack_1 : Error<
-  "%select{expression|base type|declaration type|template argument}0 contains "
-  "unexpanded parameter pack %1">;
+  "%select{expression|base type|declaration type|data member type|bit-field "
+  "size}0 "
+  "contains unexpanded parameter pack %1">;
 def err_unexpanded_parameter_pack_2 : Error<
-  "%select{expression|base type|declaration type|template argument}0 contains "
-  "unexpanded parameter packs %1 and %2">;
+  "%select{expression|base type|declaration type|data member type|bit-field "
+  "size}0 "
+  "contains unexpanded parameter packs %1 and %2">;
 def err_unexpanded_parameter_pack_3_or_more : Error<
-  "%select{expression|base type|declaration type|template argument}0 contains "
-  "unexpanded parameter packs %1, %2, ...">;
+  "%select{expression|base type|declaration type|data member type|bit-field "
+  "size}0 "
+  "contains unexpanded parameter packs %1, %2, ...">;
 
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
index 22e395cf9616902da8b0caf9404b4a436227100d..2dc09d339c4778416850a57ab38dc3c314cb7c98 100644 (file)
@@ -3135,10 +3135,20 @@ public:
   /// Note that the values of this enumeration line up with the first
   /// argument to the \c err_unexpanded_parameter_pack diagnostic.
   enum UnexpandedParameterPackContext {
+    /// \brief An arbitrary expression.
     UPPC_Expression = 0,
+
+    /// \brief The base type of a class type.
     UPPC_BaseType,
+
+    /// \brief The type of an arbitrary declaration.
     UPPC_DeclarationType,
-    UPPC_TemplateArgument
+
+    /// \brief The type of a data member.
+    UPPC_DataMemberType,
+
+    /// \brief The size of a bit-field.
+    UPPC_BitFieldWidth
   };
 
   /// \brief If the given type contains an unexpanded parameter pack,
index 0991e5a7093c2de00fb49498da7672634a99e8db..9dbbfaa733d3df02335a660aedc6dd6200fab948 100644 (file)
@@ -1123,8 +1123,15 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args,
   
   // Fill in the exception array.
   QualType *exnSlot = argSlot + numArgs;
-  for (unsigned i = 0, e = epi.NumExceptions; i != e; ++i)
+  for (unsigned i = 0, e = epi.NumExceptions; i != e; ++i) {
+    if (epi.Exceptions[i]->isDependentType())
+      setDependent();
+
+    if (epi.Exceptions[i]->containsUnexpandedParameterPack())
+      setContainsUnexpandedParameterPack();
+
     exnSlot[i] = epi.Exceptions[i];
+  }
 }
 
 
index 6182e8663b42eecd2cf6de48379dd6d07b10b538..5704cb5ad46949070f2cdb97f823e11cbb51e035 100644 (file)
@@ -6424,7 +6424,9 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
         << FieldName << FieldTy << BitWidth->getSourceRange();
     return Diag(FieldLoc, diag::err_not_integral_type_anon_bitfield)
       << FieldTy << BitWidth->getSourceRange();
-  }
+  } else if (DiagnoseUnexpandedParameterPack(const_cast<Expr *>(BitWidth),
+                                             UPPC_BitFieldWidth))
+    return true;
 
   // If the bit-width is type- or value-dependent, don't try to check
   // it now.
@@ -6499,9 +6501,17 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
 
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
   QualType T = TInfo->getType();
-  if (getLangOptions().CPlusPlus)
+  if (getLangOptions().CPlusPlus) {
     CheckExtraCXXDefaultArguments(D);
 
+    if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo,
+                                        UPPC_DataMemberType)) {
+      D.setInvalidType();
+      T = Context.IntTy;
+      TInfo = Context.getTrivialTypeSourceInfo(T, Loc);
+    }
+  }
+
   DiagnoseFunctionSpecifiers(D);
 
   if (D.getDeclSpec().isThreadSpecified())
index 760dc342db097a4ecc76bfa79ca8e7887aafd1ed..0e5c9c097981cb0b396673cd376e4045d051d99c 100644 (file)
@@ -96,11 +96,25 @@ struct TestPPName
   // ObjCObjectPointerType is uninteresting
 };
 
+// FIXME: Test for unexpanded parameter packs in each of the expression nodes.
+
 template<typename ... Types>
 void TestPPNameFunc(int i) {
   f(static_cast<Types>(i)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
 }
 
+// FIXME: Test for unexpanded parameter packs in declarations.
+template<typename... Types>
+struct TestUnexpandedDecls {
+  void member_function(Types);  // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+  void member_function () throw(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+  Types data_member;  // expected-error{{data member type contains unexpanded parameter pack 'Types'}}
+  static Types static_data_member; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+  unsigned bit_field : static_cast<Types>(0);  // expected-error{{bit-field size contains unexpanded parameter pack 'Types'}}
+};
+
+// Test for diagnostics in the presence of multiple unexpanded
+// parameter packs.
 template<typename T, typename U> struct pair;
 
 template<typename ...OuterTypes>
@@ -115,3 +129,4 @@ struct MemberTemplatePPNames {
     };
   };
 };
+