diff options
author | Mike Stump <mrs@apple.com> | 2009-02-04 22:31:32 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-02-04 22:31:32 +0000 |
commit | 98eb8a7a702b95183ed015706b1f1c66f5cb27a4 (patch) | |
tree | c8447654c9c0f9e1bb7655e0d01a6edf33fc347c /lib/Sema/SemaStmt.cpp | |
parent | 90350b6f815eecd9441119b1412695d33fb2b98f (diff) |
Add support for blocks with explicit return types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63784 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index cf26b90bc4..7697dbda00 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -731,8 +731,8 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { CurBlock->ReturnType = RetValExp->getType().getTypePtr(); } else CurBlock->ReturnType = Context.VoidTy.getTypePtr(); - return Owned(new ReturnStmt(ReturnLoc, RetValExp)); } + QualType FnRetType = QualType(CurBlock->ReturnType, 0); // 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 @@ -749,21 +749,22 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { if (!RetValExp) return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr)); - // we have a non-void block with an expression, continue checking - QualType RetValType = RetValExp->getType(); - - // For now, restrict multiple return statements in a block to have - // strict compatible types only. - QualType BlockQT = QualType(CurBlock->ReturnType, 0); - if (Context.getCanonicalType(BlockQT).getTypePtr() - != Context.getCanonicalType(RetValType).getTypePtr()) { - // FIXME: non-localizable string in diagnostic - DiagnoseAssignmentResult(Incompatible, ReturnLoc, BlockQT, - RetValType, RetValExp, "returning"); - return StmtError(); - } + if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) { + // we have a non-void block with an expression, continue checking + QualType RetValType = RetValExp->getType(); + + // 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. - if (RetValExp) CheckReturnStackAddr(RetValExp, BlockQT, ReturnLoc); + // In C++ the return statement is handled via a copy initialization. + // the C version of which boils down to CheckSingleAssignmentConstraints. + // FIXME: Leaks RetValExp. + if (PerformCopyInitialization(RetValExp, FnRetType, "returning")) + return StmtError(); + + if (RetValExp) CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc); + } return Owned(new ReturnStmt(ReturnLoc, RetValExp)); } |