[PATCH] D32210: [Sema][ObjC] Add support for attribute "noescape"
Akira Hatanaka via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 25 15:10:42 PDT 2017
ahatanak added inline comments.
================
Comment at: include/clang/Basic/AttrDocs.td:118
+ let Content = [{
+``noescape`` placed on a block parameter is used to inform the compiler that the block passed to a function cannot escape: that is, the block will not be invoked after the function returns. To ensure that the block does not escape, clang imposes the following restrictions on usage of non-escaping blocks:
+
----------------
aaron.ballman wrote:
> Please wrap to 80 columns.
>
> "block parameter" is a bit strange -- I assumed that meant parameter to a block, not a function parameter of block type. May want to clarify.
>
> Should also clarify "the block will not be invoked after the function returns." Does this code produce undefined behavior?
> ```
> typedef void (^BlockTy)();
> void nonescapingFunc(__attribute__((noescape)) BlockTy);
> void escapingFunc(BlockTy);
>
> void callerFunc(__attribute__((noescape)) BlockTy block) {
> nonescapingFunc(block); // OK
> escapingFunc(block); // error: parameter is not annotated with noescape
> }
>
> void f(void) {
> BlockTy Blk = ^{};
> callerFunc(Blk);
> Blk();
> }
> ```
The code above doesn't produce undefined behavior as long as escapingFunc doesn't cause the block to escape. It is OK to declare a variable to hold the block and invoke it later after callerFunc returns. If a block literal is directly passed to callerFunc, the block will not be invoked after the function returns.
```
void f(void) {
BlockTy Blk = ^{};
callerFunc(Blk); // Blk can be invoked after callerFunc returns.
Blk();
callerFunc(^{}); // the block passed cannot be invoked after callerFunc returns.
}```
https://reviews.llvm.org/D32210
More information about the cfe-commits
mailing list