]> granicus.if.org Git - clang/commitdiff
Allow block returns in C++ with the form
authorDouglas Gregor <dgregor@apple.com>
Sun, 5 Jun 2011 05:14:41 +0000 (05:14 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sun, 5 Jun 2011 05:14:41 +0000 (05:14 +0000)
  return <expression> ;

in blocks with a 'void' result type, so long as <expression> has type
'void'. This follows the rules for C++ functions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132658 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaStmt.cpp
test/SemaObjCXX/blocks.mm

index 1ecb4196b9d5cb4355825ce600c9c2b36180163d..d3a22cdbb98c008a7b8ee7b583409690b91c5fbd 100644 (file)
@@ -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;
 
index 6c2343df0e09b74d763c2ab660e3b07654f3e0ad..c91fd103e1333cf039f9e70ce46c1939566a5218 100644 (file)
@@ -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);
+}