From 59b982e1be3af0a1c6dc1564a9df8123404359cc Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 2 Feb 2016 23:58:56 +0000 Subject: [PATCH] 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 --- clang/lib/Sema/SemaDecl.cpp | 32 +++++++++++++----------- clang/lib/Sema/SemaLambda.cpp | 2 ++ clang/test/SemaCXX/cxx1y-deduced-return-type.cpp | 6 +++++ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ffd71e3..510e70a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 884add2..1a62f0d 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/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/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp b/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp index 225d234..e3f6f96 100644 --- a/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp +++ b/clang/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(); +} -- 2.7.4