зеркало из https://github.com/microsoft/clang-1.git
Handle lambdas where the lambda-declarator is an explicit "(void)". PR13854.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164274 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
d6f80daa84
Коммит
7c3c6bca26
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -410,9 +410,15 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|||
= MethodTyInfo->getType()->getAs<FunctionType>()->getResultType()
|
||||
!= Context.DependentTy;
|
||||
|
||||
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())
|
||||
|
|
|
@ -229,3 +229,7 @@ namespace PR13860 {
|
|||
static_assert(sizeof(y), "");
|
||||
}
|
||||
}
|
||||
|
||||
namespace PR13854 {
|
||||
auto l = [](void){};
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче