diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-11 19:27:54 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-11 19:27:54 +0000 |
commit | 9097af160e647df10829cdd548a06c84649f0231 (patch) | |
tree | 56166a6206eb3173ef437c4a891d2ea80b56242a | |
parent | 30bdc8762a0e9f69b0d3acf62859731cda07428f (diff) |
fix blocks to reject objc interfaces returned by value. Also,
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
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 33 | ||||
-rw-r--r-- | test/SemaObjC/blocks.m | 3 |
2 files changed, 25 insertions, 11 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index dda8654b49..f2820df93e 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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 diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m index b27d65d833..544eddd507 100644 --- a/test/SemaObjC/blocks.m +++ b/test/SemaObjC/blocks.m @@ -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}} } |