[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