[PATCH] D38118: [CodeGen][ObjC] Build the global block structure before emitting the body of global block invoke functions

Akira Hatanaka via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 20 20:53:10 PDT 2017


ahatanak created this revision.

This patch fixes an infinite loop in IRGen that occurs when compiling the following code:

  void FUNC2() {
    static void (^const block1)(int) = ^(int a){
      if (a--)
        block1(a);
    };
  
  When IRGen visits the call to "block1", it knows that it always calls the block defined in Func2 enclosing the call (because "block1" is const qualified), so it tries to emit the reference to "block1" as a constant and calls CodeGenModule::GetAddrOfGlobalBlock to get the address of the block. CodeGenModule::GetAddrOfGlobalBlock checks whether the block has already been emitted (calling getAddrOfGlobalBlockIfEmitted). If the block hasn't been emitted, it starts generating the block invoke function, which causes the infinite loop.
  
  I believe this happens because clang's constant folding got smarter (see commit log of r290661, for example) and the call "refExpr->EvaluateAsRValue" in CodeGenFunction::tryEmitAsConstant returns true now as a result.
  
  This patch prevents the infinite loop by building the global block in GenerateBlockFunction before it emits the IR of the body of the function.
  
  rdar://problem/34541684


https://reviews.llvm.org/D38118

Files:
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGen/mangle-blocks.c
  test/CodeGenObjC/local-static-block.m
  test/CodeGenObjC/mangle-blocks.m

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38118.116135.patch
Type: text/x-patch
Size: 6693 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170921/4cbf09c5/attachment.bin>


More information about the cfe-commits mailing list