From: Richard Smith Date: Fri, 26 Jul 2013 22:53:54 +0000 (+0000) Subject: PR16708: If a lambda has an implicit return type, don't get confused if its return... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec0808decc682f76e411eed7206a82a34b87dd7d;p=clang PR16708: If a lambda has an implicit return type, don't get confused if its return type has already been determined to be a type containing an 'auto'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187266 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 5502a041d2..7feb96f6a6 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -2368,23 +2368,8 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // For blocks/lambdas with implicit return types, we check each return // statement individually, and deduce the common return type when the block // or lambda is completed. - if (AutoType *AT = - FnRetType.isNull() ? 0 : FnRetType->getContainedAutoType()) { - // In C++1y, the return type may involve 'auto'. - FunctionDecl *FD = cast(CurCap)->CallOperator; - if (CurContext->isDependentContext()) { - // C++1y [dcl.spec.auto]p12: - // Return type deduction [...] occurs when the definition is - // instantiated even if the function body contains a return - // statement with a non-type-dependent operand. - CurCap->ReturnType = FnRetType = Context.DependentTy; - } else if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) { - FD->setInvalidDecl(); - return StmtError(); - } else - CurCap->ReturnType = FnRetType = FD->getResultType(); - } else if (CurCap->HasImplicitReturnType) { - // FIXME: Fold this into the 'auto' codepath above. + if (CurCap->HasImplicitReturnType) { + // FIXME: Fold this into the 'auto' codepath below. if (RetValExp && !isa(RetValExp)) { ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp); if (Result.isInvalid()) @@ -2411,6 +2396,21 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // make sure we provide a return type now for better error recovery. if (CurCap->ReturnType.isNull()) CurCap->ReturnType = FnRetType; + } else if (AutoType *AT = + FnRetType.isNull() ? 0 : FnRetType->getContainedAutoType()) { + // In C++1y, the return type may involve 'auto'. + FunctionDecl *FD = cast(CurCap)->CallOperator; + if (CurContext->isDependentContext()) { + // C++1y [dcl.spec.auto]p12: + // Return type deduction [...] occurs when the definition is + // instantiated even if the function body contains a return + // statement with a non-type-dependent operand. + CurCap->ReturnType = FnRetType = Context.DependentTy; + } else if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) { + FD->setInvalidDecl(); + return StmtError(); + } else + CurCap->ReturnType = FnRetType = FD->getResultType(); } assert(!FnRetType.isNull()); diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp index 83c5215d74..8736afe4b0 100644 --- a/test/SemaCXX/lambda-expressions.cpp +++ b/test/SemaCXX/lambda-expressions.cpp @@ -243,3 +243,11 @@ namespace PR13854 { namespace PR14518 { auto f = [](void) { return __func__; }; // no-warning } + +namespace PR16708 { + auto L = []() { + auto ret = 0; + return ret; + return 0; + }; +}