diff options
author | John McCall <rjmccall@apple.com> | 2011-08-17 22:09:46 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-08-17 22:09:46 +0000 |
commit | 0a7efe1142d241678c91bf93ee6adb51289863a4 (patch) | |
tree | b6886eef2a70f765aa372065e0db563c85f2d0b0 /lib/Sema/SemaStmt.cpp | |
parent | 5d6a4ad65726c1825134800cfb7cb5e81b4dc0f3 (diff) |
Reorganize the return-type vs. expression checking code in
block returns; no functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137884 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 60 |
1 files changed, 30 insertions, 30 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 8303616db4..9c87a3f323 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1740,49 +1740,49 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // Otherwise, verify that this result type matches the previous one. We are // pickier with blocks than for normal functions because we don't have GCC // compatibility to worry about here. - ReturnStmt *Result = 0; const VarDecl *NRVOCandidate = 0; - if (CurBlock->ReturnType->isVoidType()) { - if (RetValExp && !RetValExp->isTypeDependent() && - (!getLangOptions().CPlusPlus || !RetValExp->getType()->isVoidType())) { + if (FnRetType->isDependentType()) { + // Delay processing for now. TODO: there are lots of dependent + // types we can conclusively prove aren't void. + } else if (FnRetType->isVoidType()) { + if (RetValExp && + !(getLangOptions().CPlusPlus && + (RetValExp->isTypeDependent() || + RetValExp->getType()->isVoidType()))) { Diag(ReturnLoc, diag::err_return_block_has_expr); RetValExp = 0; } } else if (!RetValExp) { - if (!CurBlock->ReturnType->isDependentType()) - return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr)); - } else { - if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) { - // we have a non-void block with an expression, continue checking - - // C99 6.8.6.4p3(136): The return statement is not an assignment. The - // overlap restriction of subclause 6.5.16.1 does not apply to the case of - // function return. - - // In C++ the return statement is handled via a copy initialization. - // the C version of which boils down to CheckSingleAssignmentConstraints. - NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false); - InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc, - FnRetType, + return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr)); + } else if (!RetValExp->isTypeDependent()) { + // we have a non-void block with an expression, continue checking + + // C99 6.8.6.4p3(136): The return statement is not an assignment. The + // overlap restriction of subclause 6.5.16.1 does not apply to the case of + // function return. + + // In C++ the return statement is handled via a copy initialization. + // the C version of which boils down to CheckSingleAssignmentConstraints. + NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false); + InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc, + FnRetType, NRVOCandidate != 0); - ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate, - FnRetType, RetValExp); - if (Res.isInvalid()) { - // FIXME: Cleanup temporaries here, anyway? - return StmtError(); - } - RetValExp = Res.take(); - - if (RetValExp) - CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc); + ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate, + FnRetType, RetValExp); + if (Res.isInvalid()) { + // FIXME: Cleanup temporaries here, anyway? + return StmtError(); } + RetValExp = Res.take(); + CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc); } if (RetValExp) { CheckImplicitConversions(RetValExp, ReturnLoc); RetValExp = MaybeCreateExprWithCleanups(RetValExp); } - Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate); + ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, + NRVOCandidate); // If we need to check for the named return value optimization, save the // return statement in our scope for later processing. |