]> granicus.if.org Git - clang/commitdiff
Handle lambdas where the lambda-declarator is an explicit "(void)". PR13854.
authorEli Friedman <eli.friedman@gmail.com>
Thu, 20 Sep 2012 01:40:23 +0000 (01:40 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 20 Sep 2012 01:40:23 +0000 (01:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164274 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaLambda.cpp
test/SemaCXX/lambda-expressions.cpp

index 4798b032df44e85e38bfb0a5749ca49e15745c60..391a6d33b295be2f932306bdd7ad855e1e901f9a 100644 (file)
@@ -1273,6 +1273,7 @@ public:
                                      MultiTemplateParamsArg TemplateParamLists,
                                      bool &AddToScope);
   bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
+  void checkVoidParamDecl(ParmVarDecl *Param);
 
   bool CheckConstexprFunctionDecl(const FunctionDecl *FD);
   bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body);
index 83dc86f575c3efa161f3236637e0627a26cef10a..2dd5df1ea01fd4745b69d0b66052b9bc143c52f4 100644 (file)
@@ -5128,6 +5128,22 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
   }
 }
 
+void Sema::checkVoidParamDecl(ParmVarDecl *Param) {
+  // In C++, the empty parameter-type-list must be spelled "void"; a
+  // typedef of void is not permitted.
+  if (getLangOpts().CPlusPlus &&
+      Param->getType().getUnqualifiedType() != Context.VoidTy) {
+    bool IsTypeAlias = false;
+    if (const TypedefType *TT = Param->getType()->getAs<TypedefType>())
+      IsTypeAlias = isa<TypeAliasDecl>(TT->getDecl());
+    else if (const TemplateSpecializationType *TST =
+               Param->getType()->getAs<TemplateSpecializationType>())
+      IsTypeAlias = TST->isTypeAlias();
+    Diag(Param->getLocation(), diag::err_param_typedef_of_void)
+      << IsTypeAlias;
+  }
+}
+
 NamedDecl*
 Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
                               TypeSourceInfo *TInfo, LookupResult &Previous,
@@ -5477,21 +5493,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
         FTI.ArgInfo[0].Param &&
         cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
       // Empty arg list, don't push any params.
-      ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[0].Param);
-
-      // In C++, the empty parameter-type-list must be spelled "void"; a
-      // typedef of void is not permitted.
-      if (getLangOpts().CPlusPlus &&
-          Param->getType().getUnqualifiedType() != Context.VoidTy) {
-        bool IsTypeAlias = false;
-        if (const TypedefType *TT = Param->getType()->getAs<TypedefType>())
-          IsTypeAlias = isa<TypeAliasDecl>(TT->getDecl());
-        else if (const TemplateSpecializationType *TST =
-                   Param->getType()->getAs<TemplateSpecializationType>())
-          IsTypeAlias = TST->isTypeAlias();
-        Diag(Param->getLocation(), diag::err_param_typedef_of_void)
-          << IsTypeAlias;
-      }
+      checkVoidParamDecl(cast<ParmVarDecl>(FTI.ArgInfo[0].Param));
     } else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
       for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
         ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
index 489c895c99680bd14d097a6a0520d3fe279634f9..15cd2a73e7f7d77b004533e201051022b171ec83 100644 (file)
@@ -410,9 +410,15 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
       = MethodTyInfo->getType()->getAs<FunctionType>()->getResultType() 
                                                         != Context.DependentTy;
 
-    Params.reserve(FTI.NumArgs);
-    for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
-      Params.push_back(cast<ParmVarDecl>(FTI.ArgInfo[i].Param));
+    if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
+        cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
+      // Empty arg list, don't push any params.
+      checkVoidParamDecl(cast<ParmVarDecl>(FTI.ArgInfo[0].Param));
+    } else {
+      Params.reserve(FTI.NumArgs);
+      for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
+        Params.push_back(cast<ParmVarDecl>(FTI.ArgInfo[i].Param));
+    }
 
     // Check for unexpanded parameter packs in the method type.
     if (MethodTyInfo->getType()->containsUnexpandedParameterPack())
index 0a95680478d19ac02b5ae9d00b34a305f357abac..babe743c65db34ec5d7570a2192559783df354ff 100644 (file)
@@ -229,3 +229,7 @@ namespace PR13860 {
     static_assert(sizeof(y), "");
   }
 }
+
+namespace PR13854 {
+  auto l = [](void){};
+}