[clang] [clang] Fix self-capturing `__block` variables (PR #89475)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 31 16:45:57 PDT 2024
================
@@ -2653,11 +2655,39 @@ const BlockByrefInfo &CodeGenFunction::getBlockByrefInfo(const VarDecl *D) {
info.FieldOffset = varOffset;
info.ByrefAlignment = std::max(varAlign, getPointerAlign());
+ // If we're initializing directly on the heap, then we should emit a
+ // no-op copy helper, both because we don't need a real one (the
+ // object will never move), and because a real one would break the
+ // pre-init _Block_object_assign.
+ info.ForceNoopCopy = D->needsInitOnHeap();
+
auto pair = BlockByrefInfos.insert({D, info});
assert(pair.second && "info was inserted recursively?");
return pair.first->second;
}
+void CodeGenFunction::emitByrefInitOnHeap(llvm::Value *P) {
+ // The object itself is initialized directly on the heap. But for ABI
+ // backwards compatibility reasons, we have to set up a fake byref struct on
+ // the stack (with the structural components initialized but not the object
+ // itself), then call _Block_object_assign to move it to the heap (which is
+ // safe because we forced a no-op copy helper), then call
+ // _Block_object_dispose to release the extra ref from _Block_object_assign.
+ //
+ // 'P' points to the fake byref struct.
+
+ BlockFieldFlags flags = BLOCK_FIELD_IS_BYREF;
+ // Ignored out-parameter. We'll use the forwarding pointer instead.
+ RawAddress out = CreateDefaultAlignTempAlloca(P->getType(), "initOnHeap.out");
+
+ llvm::Value *args[] = {Builder.CreateBitCast(out.getPointer(), VoidPtrTy),
+ Builder.CreateBitCast(P, VoidPtrTy),
----------------
ille-apple wrote:
Ah, this is an artifact of the change having originally been written in 2020. Looks like I can just drop the bitcast. I don't think address-space differences are possible.
https://github.com/llvm/llvm-project/pull/89475
More information about the cfe-commits
mailing list