diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 2 |
3 files changed, 16 insertions, 2 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 1e9f319d4f..cc94050a6f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/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/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index e8a61044b5..1255695016 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/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/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index d7bdbafaba..3dc8136b78 100644 --- a/lib/Sema/TreeTransform.h +++ b/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; |