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.

llvm-svn: 259609
This commit is contained in:
Richard Smith 2016-02-02 23:58:56 +00:00
parent 0d473d12fe
commit 59b982e1be
3 changed files with 26 additions and 14 deletions

View File

@ -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<AutoType>()) {
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<AutoType>()) {
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);

View File

@ -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<LambdaScopeInfo>(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,

View File

@ -496,3 +496,9 @@ namespace TrailingReturnTypeForConversionOperator {
}
};
};
namespace PR24989 {
auto x = [](auto){};
using T = decltype(x);
void (T::*p)(int) const = &T::operator();
}