[PATCH] D32210: [Sema][ObjC] Add support for attribute "noescape"
Akira Hatanaka via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 19 15:13:28 PDT 2017
ahatanak added a comment.
In https://reviews.llvm.org/D32210#730553, @jroelofs wrote:
> This doesn't forbid assigning them to block properties... is that intentional?
>
> typedef void (^Block)(int);
>
> @interface Foo
> @property Block B;
> @end
>
> void foo(Foo *f, Block __attribute__((noescape)) b) {
> f.B = b;
> }
>
No, it's not intentional. The code to check assignments of noescape blocks probably had to go to ActOnBinOp or BuildBinOp to forbid this too.
================
Comment at: include/clang/Basic/AttrDocs.td:122
+* Cannot be returned from a function
+* Cannot be captured by a block
+* Cannot be assigned to a variable
----------------
TheRealAdamKemp wrote:
> This may be too restrictive in some cases. Consider this:
>
> ```
> typedef void (^BlockTy)();
> void nonescapingFunc(__attribute__((noescape)) BlockTy);
>
> void callerFunc(__attribute__((noescape)) BlockTy block) {
> nonescapingFunc(^{ block(); });
> }
> ```
>
> It sounds like the above code would give an error, but the capturing block is also nonescaping, which means it should be allowed. This is a useful pattern, and disallowing it would make these attributes very cumbersome.
>
> The code could also be written like this:
>
> ```
> typedef void (^BlockTy)();
> void nonescapingFunc(__attribute__((noescape)) BlockTy);
>
> void callerFunc(__attribute__((noescape)) BlockTy block) {
> BlockTy wrapBlock = ^{
> block();
> };
> nonescapingFunc(wrapBlock);
> }
> ```
>
> Again, I would expect that to not give an error or at least be able to decorate the declaration of `wrapBlock` to indicate that it is also nonescaping (can this attribute be applied to locals or only function arguments?).
I didn't think forbidding capturing noescape blocks would be too restrictive in practice, but I see your point. If it's a common pattern, we probably shouldn't forbid that.
================
Comment at: lib/Sema/SemaChecking.cpp:2567
+ else
+ assert(FDecl->isVariadic() &&
+ "Called function expected to be variadic");
----------------
aaron.ballman wrote:
> What about functions that have no prototype (they're not variadic, but they accept any number of arguments)? Should include a test for this.
You are right, this assertion should check for functions without prototypes too.
https://reviews.llvm.org/D32210
More information about the cfe-commits
mailing list