aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaStmt.cpp8
-rw-r--r--test/SemaObjCXX/blocks.mm26
2 files changed, 32 insertions, 2 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 1ecb4196b9..d3a22cdbb9 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/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/test/SemaObjCXX/blocks.mm b/test/SemaObjCXX/blocks.mm
index 6c2343df0e..c91fd103e1 100644
--- a/test/SemaObjCXX/blocks.mm
+++ b/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<typename T>
+ 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>(X);
+}