[PATCH] D50152: [CodeGen] Merge equivalent block copy/helper functions
Akira Hatanaka via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 9 07:50:10 PDT 2018
ahatanak added inline comments.
================
Comment at: lib/CodeGen/CGBlocks.cpp:1682
+ if (IsCopyHelper && Ctx.getBlockVarCopyInits(Var).CanThrow)
+ Name += "c";
+ }
----------------
rjmccall wrote:
> ahatanak wrote:
> > rjmccall wrote:
> > > I don't think you need to add `d` to the name of a copy helper. It's a bit weird, but while copying a `__block` variable can cause its copy helper to run, destroying it immediately afterwards can never cause its destroy helper to run. That's because a newly-copied `__block` variable always has a reference count of 2: the new reference in the copy and the forwarding reference from the original.
> > >
> > > I think that means you can just add a single letter which specifies whether the corresponding `__block` variable operation is known to be able to throw.
> > I added 'd' to the name of the copy helper functions only because IRGen generates different code depending on whether the destructor can throw or not.
> >
> > For example, if I compile the following code with -DTHROWS, IRGen uses 'invoke' (which jumps to the terminate block) for the calls to `_Block_object_dispose` on the EH path whereas it uses 'call' if the destructor doesn't throw.
> >
> > ```
> > struct S {
> > S();
> > #ifdef THROWS
> > ~S() noexcept(false);
> > #else
> > ~S() noexcept(true);
> > #endif
> > S(const S &);
> > int a;
> > };
> >
> > void test() {
> > __block S s0, s1, s2;
> > ^{ (void)s0, (void)s1; (void)s2; };
> > }
> > ```
> >
> > It seems like IRGen doesn't have to use 'invoke' when emitting a call to `_Block_object_dispose` even when the class has a destructor that can throw, if I understood your explanation correctly?
> Right. It's specifically only true when unwinding after a copy, which is very atypical for C++ code, but nonetheless it's true. We should make the call `nounwind` in these situations and leave a comment explaining why. Did my explanation make any sense?
Yes, it makes sense. Since the reference count is two after the `__block` variable is copied, calling `_Block_object_dispose` on it won't cause the destructor to be called.
Repository:
rC Clang
https://reviews.llvm.org/D50152
More information about the cfe-commits
mailing list