From 24050c5f72785b936e7d6b8323f32084ae4e24d1 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Tue, 15 May 2018 05:00:53 +0000 Subject: [PATCH 1/2] Fix Issue 18848 - std.allocator: Regions are non-copyable, yet are passed around in examples This doesn't fix that non-copyable regions are still passed around in examples, so we still rely on NRVO to do its thing and elide the copy, but at least this will now catch wrong code that mistakenly copied Regions around. --- std/experimental/allocator/building_blocks/region.d | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/std/experimental/allocator/building_blocks/region.d b/std/experimental/allocator/building_blocks/region.d index b13991d1c4d..a28f60cb705 100644 --- a/std/experimental/allocator/building_blocks/region.d +++ b/std/experimental/allocator/building_blocks/region.d @@ -96,11 +96,6 @@ struct Region(ParentAllocator = NullAllocator, this(cast(ubyte[]) (parent.allocate(n.roundUpToAlignment(alignment)))); } - /* - TODO: The postblit of `BasicRegion` should be disabled because such objects - should not be copied around naively. - */ - /** If `ParentAllocator` is not $(REF_ALTTEXT `NullAllocator`, NullAllocator, std,experimental,allocator,building_blocks,null_allocator) and defines `deallocate`, the region defines a destructor that uses `ParentAllocator.deallocate` to free the @@ -113,6 +108,13 @@ struct Region(ParentAllocator = NullAllocator, parent.deallocate(_begin[0 .. _end - _begin]); } + /** + `Region` deallocates on destruction (see above), therefore is not copyable. + */ + static if (!is(ParentAllocator == NullAllocator) + && hasMember!(ParentAllocator, "deallocate")) + @disable this(this); + /** Rounds the given size to a multiple of the `alignment` */ From 711d971ccebae449ba664a2f8b334c61b9d83649 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Fri, 18 May 2018 04:32:18 +0000 Subject: [PATCH 2/2] free_list: Fix broken unittest Fix compilation error (previously, silent dangling pointer and double-free). --- std/experimental/allocator/building_blocks/free_list.d | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/std/experimental/allocator/building_blocks/free_list.d b/std/experimental/allocator/building_blocks/free_list.d index c93b412b3a8..cf0db67fe6c 100644 --- a/std/experimental/allocator/building_blocks/free_list.d +++ b/std/experimental/allocator/building_blocks/free_list.d @@ -790,8 +790,9 @@ struct ContiguousFreeList(ParentAllocator, import std.experimental.allocator.building_blocks.region : Region; import std.experimental.allocator.gc_allocator : GCAllocator; import std.typecons : Ternary; - alias A = ContiguousFreeList!(Region!GCAllocator, 0, 64); - auto a = A(Region!GCAllocator(1024 * 4), 1024); + alias A = ContiguousFreeList!(Region!GCAllocator*, 0, 64); + auto r = Region!GCAllocator(1024 * 4); + auto a = A(&r, 1024); assert((() nothrow @safe @nogc => a.empty)() == Ternary.yes);