diff options
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 32 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 12 | ||||
| -rw-r--r-- | clang/test/SemaCXX/lambda-expressions.cpp | 4 |
4 files changed, 31 insertions, 18 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4798b032df4..391a6d33b29 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -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); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 83dc86f575c..2dd5df1ea01 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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); diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 489c895c996..15cd2a73e7f 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -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()) diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 0a95680478d..babe743c65d 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -229,3 +229,7 @@ namespace PR13860 { static_assert(sizeof(y), ""); } } + +namespace PR13854 { + auto l = [](void){}; +} |

