From 7f139d8103c432123ec62c7b74d04d4360c9c86b Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sun, 5 Jun 2011 05:14:41 +0000 Subject: [PATCH] Allow block returns in C++ with the form return ; in blocks with a 'void' result type, so long as has type 'void'. This follows the rules for C++ functions. llvm-svn: 132658 --- clang/lib/Sema/SemaStmt.cpp | 8 ++++++-- clang/test/SemaObjCXX/blocks.mm | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 1ecb4196b9d5..d3a22cdbb98c 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1617,13 +1617,17 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // compatibility to worry about here. ReturnStmt *Result = 0; if (CurBlock->ReturnType->isVoidType()) { - if (RetValExp) { + if (RetValExp && !RetValExp->isTypeDependent() && + (!getLangOptions().CPlusPlus || !RetValExp->getType()->isVoidType())) { Diag(ReturnLoc, diag::err_return_block_has_expr); RetValExp = 0; } Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0); } else if (!RetValExp) { - return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr)); + if (!CurBlock->ReturnType->isDependentType()) + return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr)); + + Result = new (Context) ReturnStmt(ReturnLoc, 0, 0); } else { const VarDecl *NRVOCandidate = 0; diff --git a/clang/test/SemaObjCXX/blocks.mm b/clang/test/SemaObjCXX/blocks.mm index 6c2343df0e09..c91fd103e133 100644 --- a/clang/test/SemaObjCXX/blocks.mm +++ b/clang/test/SemaObjCXX/blocks.mm @@ -118,3 +118,29 @@ void f(int (^bl)(A* a)); // expected-note {{candidate function not viable: no kn void g() { f(^(B* b) { return 0; }); // expected-error {{no matching function for call to 'f'}} } + +namespace DependentReturn { + template + void f(T t) { + (void)^(T u) { + if (t != u) + return t + u; + else + return; + }; + + (void)^(T u) { + if (t == u) + return; + else + return t + u; + }; + } + + struct X { }; + void operator+(X, X); + bool operator==(X, X); + bool operator!=(X, X); + + template void f(X); +}