]> granicus.if.org Git - clang/commitdiff
fix blocks to reject objc interfaces returned by value. Also,
authorChris Lattner <sabre@nondot.org>
Sat, 11 Apr 2009 19:27:54 +0000 (19:27 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 11 Apr 2009 19:27:54 +0000 (19:27 +0000)
a block without a prototype should still coerce a return in it to
use the declared return type.

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

lib/Sema/SemaExpr.cpp
test/SemaObjC/blocks.m

index dda8654b49bde2e5648d3e2ca74c63218db277a2..f2820df93e8dfe9a28ced6ec5196386311441435 100644 (file)
@@ -4655,11 +4655,18 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
 
     CurBlock->hasPrototype = true;
     CurBlock->isVariadic = false;
-    Type *RetTy = T.getTypePtr()->getAsFunctionType()->getResultType()
-      .getTypePtr();
+    
+    QualType RetTy = T.getTypePtr()->getAsFunctionType()->getResultType();
+    
+    // Do not allow returning a objc interface by-value.
+    if (RetTy->isObjCInterfaceType()) {
+      Diag(ParamInfo.getSourceRange().getBegin(),
+           diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy;
+      return;
+    }
 
     if (!RetTy->isDependentType())
-      CurBlock->ReturnType = RetTy;
+      CurBlock->ReturnType = RetTy.getTypePtr();
     return;
   }
 
@@ -4683,22 +4690,26 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
     for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
       CurBlock->Params.push_back(FTI.ArgInfo[i].Param.getAs<ParmVarDecl>());
     CurBlock->isVariadic = FTI.isVariadic;
-    QualType T = GetTypeForDeclarator (ParamInfo, CurScope);
-
-    Type* RetTy = T.getTypePtr()->getAsFunctionType()->getResultType()
-      .getTypePtr();
-
-    if (!RetTy->isDependentType())
-      CurBlock->ReturnType = RetTy;
   }
   CurBlock->TheDecl->setParams(Context, &CurBlock->Params[0], 
-                                        CurBlock->Params.size());
+                               CurBlock->Params.size());
 
   for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(),
        E = CurBlock->TheDecl->param_end(); AI != E; ++AI)
     // If this has an identifier, add it to the scope stack.
     if ((*AI)->getIdentifier())
       PushOnScopeChains(*AI, CurBlock->TheScope);
+
+  // Analyze the return type.
+  QualType T = GetTypeForDeclarator(ParamInfo, CurScope);
+  QualType RetTy = T->getAsFunctionType()->getResultType();
+  
+  // Do not allow returning a objc interface by-value.
+  if (RetTy->isObjCInterfaceType()) {
+    Diag(ParamInfo.getSourceRange().getBegin(),
+         diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy;
+  } else if (!RetTy->isDependentType())
+    CurBlock->ReturnType = RetTy.getTypePtr();
 }
 
 /// ActOnBlockError - If there is an error parsing a block, this callback
index b27d65d833ca7fefb3e49214bfb512b70ce9e534..544eddd507d487c3d2825e42f2e63caf3a987b59 100644 (file)
@@ -40,4 +40,7 @@ void foo7(id (^x)(int)) {
 
 void foo8() {
   void *P = ^(itf x) {};  // expected-error {{Objective-C interface type 'itf' cannot be passed by value}}
+  P = ^itf(int x) {};     // expected-error {{Objective-C interface type 'itf' cannot be returned by value}}
+  P = ^itf() {};          // expected-error {{Objective-C interface type 'itf' cannot be returned by value}}
+  P = ^itf{};             // expected-error {{Objective-C interface type 'itf' cannot be returned by value}}
 }