================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits