summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-12-03 17:47:53 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-12-03 17:47:53 +0000
commitdd5eb9df0cd248bc20fdca01f007f7119633a7d7 (patch)
treec356b1607c20723349636ca119cae1a3dd635681 /clang/lib
parent71ba18c1e08ea0a323974be32bebffeaa60808da (diff)
downloadbcm5719-llvm-dd5eb9df0cd248bc20fdca01f007f7119633a7d7.tar.gz
bcm5719-llvm-dd5eb9df0cd248bc20fdca01f007f7119633a7d7.zip
If block literal return type is not specified, return type of the block is
inferred from return types. All the return statements have to agree about the type. // rdar://10466373 llvm-svn: 145774
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp4
-rw-r--r--clang/lib/Sema/SemaStmt.cpp12
-rw-r--r--clang/lib/Sema/TreeTransform.h2
3 files changed, 16 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 1e9f319d4f7..cc94050a6f9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -8715,8 +8715,10 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
// return type. TODO: what should we do with declarators like:
// ^ * { ... }
// If the answer is "apply template argument deduction"....
- if (RetTy != Context.DependentTy)
+ if (RetTy != Context.DependentTy) {
CurBlock->ReturnType = RetTy;
+ CurBlock->TheDecl->setBlockMissingReturnType(false);
+ }
// Push block parameters from the declarator if we had them.
SmallVector<ParmVarDecl*, 8> Params;
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index e8a61044b5d..1255695016d 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -1809,6 +1809,16 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
} else if (!RetValExp) {
return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));
} else if (!RetValExp->isTypeDependent()) {
+ if (CurBlock->TheDecl->blockMissingReturnType()) {
+ // when block's return type is not specified, all return types
+ // must strictly match.
+ if (Context.getCanonicalType(FnRetType) !=
+ Context.getCanonicalType(RetValExp->getType())) {
+ Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)
+ << RetValExp->getType() << FnRetType;
+ return StmtError();
+ }
+ }
// 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
@@ -1820,7 +1830,7 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
FnRetType,
- NRVOCandidate != 0);
+ NRVOCandidate != 0);
ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
FnRetType, RetValExp);
if (Res.isInvalid()) {
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index d7bdbafaba1..3dc8136b787 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -8118,6 +8118,8 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
// in above, CapturesCXXThis need be set here from the block
// expression.
blockScope->CapturesCXXThis = oldBlock->capturesCXXThis();
+ blockScope->TheDecl->setBlockMissingReturnType(
+ oldBlock->blockMissingReturnType());
SmallVector<ParmVarDecl*, 4> params;
SmallVector<QualType, 4> paramTypes;
OpenPOWER on IntegriCloud