Analyze the block captures just once before generating copy/dispose block helper functions and honor the inert __unsafe_unretained qualifier. This refactor fixes a bug where captures of ObjC __unsafe_unretained and class types were needlessly retained/released by the copy/dispose helper functions.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
clang/lib/CodeGen/CGBlocks.cpp | ||
---|---|---|
41 | Does this actually work? It's a hashtable, so I'm worried about the possibility of e.g. a bad set of collisions causing it to grow. Even if it works today, it seems like a dangerous assumption to make. If we're going to make SortedCaptures stick around, is there any way we can keep the Capture objects there and then have Captures just store pointers into it? We'd just have to build Captures after the sorting was complete; I don't know if that's possible. | |
clang/lib/CodeGen/CGBlocks.h | ||
248 | Please explain what this means in a comment — it's just whether the whole block itself is noescape, right? |
Build the map (Captures) after building the vector (SortedCaptures).
Also fix a minor bug where a BlockLayoutChunk wasn't being removed after being copied when the end of the header wasn't aligned (see test6 in CodeGenObjC/blocks.m), which was needed since CodeGenObjC/arc-captured-32bit-block-var-layout-2.m started failing after applying this patch.
clang/lib/CodeGen/CGBlocks.cpp | ||
---|---|---|
360–361 | "byref" | |
1954 | Should this be specific to whether this is trivial to copy? | |
2143 | Should this condition be specific to whether it's trivial *to destroy*? C++ types could be trivial to destroy but not to copy (and, theoretically, vice-versa). | |
clang/lib/CodeGen/CGBlocks.h | ||
267–268 | This comment is out-of-date, and it should also be updated to say that the values are pointers into SortedCaptures. | |
305 | We can use auto now, and this seems like a good place for it. |
clang/lib/CodeGen/CGBlocks.cpp | ||
---|---|---|
2143 | Adding the check here won't change anything since pushCaptureCleanup is a no-op if the type is trivial to destroy. But we can replace NeedsCopyDispose with NeedsCopy and NeedsDispose so that we can track whether copy and dispose helpers are needed separately and avoid emitting empty dispose helper functions. I'm not sure whether we should do that in this patch or in another patch. |
clang/lib/CodeGen/CGBlocks.cpp | ||
---|---|---|
2143 | Technically, it would save emitting a GEP, but I agree that that's probably not worth thinking about, so nevermind. Avoiding emitting the functions is probably best to do in a separate patch. The runtime does allow null pointers here even if the descriptor says that the helpers exist? |
clang/lib/CodeGen/CGBlocks.cpp | ||
---|---|---|
2143 | Yes, the runtime checks whether the copy/dispose helper function field is null before calling the function. |
Please explain what this means in a comment — it's just whether the whole block itself is noescape, right?