From: Richard Smith Date: Tue, 2 Feb 2016 23:58:56 +0000 (+0000) Subject: PR24989: Stop trying to use the C++11 rules for lambda return type inference in X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e08674e1c5ed78603f1d527e0fee5d089ce4d99;p=clang PR24989: Stop trying to use the C++11 rules for lambda return type inference in C++14 generic lambdas. It conflicts with the C++14 return type deduction mechanism, and results in us failing to actually deduce the lambda's return type in some cases. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@259609 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ffd71e38c6..510e70aedb 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -11131,22 +11131,26 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (FD) { FD->setBody(Body); - if (getLangOpts().CPlusPlus14 && !FD->isInvalidDecl() && Body && - !FD->isDependentContext() && FD->getReturnType()->isUndeducedType()) { - // If the function has a deduced result type but contains no 'return' - // statements, the result type as written must be exactly 'auto', and - // the deduced result type is 'void'. - if (!FD->getReturnType()->getAs()) { - Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto) - << FD->getReturnType(); - FD->setInvalidDecl(); - } else { - // Substitute 'void' for the 'auto' in the type. - TypeLoc ResultType = getReturnTypeLoc(FD); - Context.adjustDeducedFunctionResultType( - FD, SubstAutoType(ResultType.getType(), Context.VoidTy)); + if (getLangOpts().CPlusPlus14) { + if (!FD->isInvalidDecl() && Body && !FD->isDependentContext() && + FD->getReturnType()->isUndeducedType()) { + // If the function has a deduced result type but contains no 'return' + // statements, the result type as written must be exactly 'auto', and + // the deduced result type is 'void'. + if (!FD->getReturnType()->getAs()) { + Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto) + << FD->getReturnType(); + FD->setInvalidDecl(); + } else { + // Substitute 'void' for the 'auto' in the type. + TypeLoc ResultType = getReturnTypeLoc(FD); + Context.adjustDeducedFunctionResultType( + FD, SubstAutoType(ResultType.getType(), Context.VoidTy)); + } } } else if (getLangOpts().CPlusPlus11 && isLambdaCallOperator(FD)) { + // In C++11, we don't use 'auto' deduction rules for lambda call + // operators because we don't support return type deduction. auto *LSI = getCurLambda(); if (LSI->HasImplicitReturnType) { deduceClosureReturnType(*LSI); diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 884add26e4..1a62f0dfcb 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -617,6 +617,8 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) { assert(CSI.HasImplicitReturnType); // If it was ever a placeholder, it had to been deduced to DependentTy. assert(CSI.ReturnType.isNull() || !CSI.ReturnType->isUndeducedType()); + assert((!isa(CSI) || !getLangOpts().CPlusPlus14) && + "lambda expressions use auto deduction in C++14 onwards"); // C++ core issue 975: // If a lambda-expression does not include a trailing-return-type, diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp index 225d2348cc..e3f6f96801 100644 --- a/test/SemaCXX/cxx1y-deduced-return-type.cpp +++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -496,3 +496,9 @@ namespace TrailingReturnTypeForConversionOperator { } }; }; + +namespace PR24989 { + auto x = [](auto){}; + using T = decltype(x); + void (T::*p)(int) const = &T::operator(); +}