Skip to content

Commit

Permalink
Merge pull request #5706 from BBasile/issue-16512
Browse files Browse the repository at this point in the history
fix issue 16512 - Nullify the argument passed to allocator.dispose
  • Loading branch information
andralex committed Sep 8, 2017
2 parents 54cd27d + 920f6b3 commit 2b0ae1f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .dscanner.ini
Expand Up @@ -60,7 +60,7 @@ label_var_same_name_check="enabled"
; Checks for lines longer than 120 characters
long_line_check="enabled"
; Checks for assignment to auto-ref function parameters
auto_ref_assignment_check="enabled"
auto_ref_assignment_check="disabled"
; Checks for incorrect infinite range definitions
incorrect_infinite_range_check="enabled"
; Checks for asserts that are always true
Expand Down
37 changes: 33 additions & 4 deletions std/experimental/allocator/package.d
Expand Up @@ -1731,17 +1731,19 @@ reference, or an entire array. It is assumed the respective entities had been
allocated with the same allocator.
*/
void dispose(A, T)(auto ref A alloc, T* p)
void dispose(A, T)(auto ref A alloc, auto ref T* p)
{
static if (hasElaborateDestructor!T)
{
destroy(*p);
}
alloc.deallocate((cast(void*) p)[0 .. T.sizeof]);
static if (__traits(isRef, p))
p = null;
}

/// Ditto
void dispose(A, T)(auto ref A alloc, T p)
void dispose(A, T)(auto ref A alloc, auto ref T p)
if (is(T == class) || is(T == interface))
{
if (!p) return;
Expand All @@ -1760,10 +1762,12 @@ if (is(T == class) || is(T == interface))
auto support = (cast(void*) ob)[0 .. typeid(ob).initializer.length];
destroy(p);
alloc.deallocate(support);
static if (__traits(isRef, p))
p = null;
}

/// Ditto
void dispose(A, T)(auto ref A alloc, T[] array)
void dispose(A, T)(auto ref A alloc, auto ref T[] array)
{
static if (hasElaborateDestructor!(typeof(array[0])))
{
Expand All @@ -1773,6 +1777,8 @@ void dispose(A, T)(auto ref A alloc, T[] array)
}
}
alloc.deallocate(array);
static if (__traits(isRef, array))
array = null;
}

@system unittest
Expand Down Expand Up @@ -1813,6 +1819,27 @@ void dispose(A, T)(auto ref A alloc, T[] array)
theAllocator.dispose(arr);
}

@system unittest //bugzilla 16512
{
import std.experimental.allocator.mallocator : Mallocator;

int* i = Mallocator.instance.make!int(0);
Mallocator.instance.dispose(i);
assert(i is null);

Object o = Mallocator.instance.make!Object();
Mallocator.instance.dispose(o);
assert(o is null);

uint* u = Mallocator.instance.make!uint(0);
Mallocator.instance.dispose((){return u;}());
assert(u !is null);

uint[] ua = Mallocator.instance.makeArray!uint([0,1,2]);
Mallocator.instance.dispose(ua);
assert(ua is null);
}

@system unittest //bugzilla 15721
{
import std.experimental.allocator.mallocator : Mallocator;
Expand Down Expand Up @@ -1886,7 +1913,7 @@ T = element type of an element of the multidimensional array
alloc = the allocator used for getting memory
array = the multidimensional array that is to be deallocated
*/
void disposeMultidimensionalArray(T, Allocator)(auto ref Allocator alloc, T[] array)
void disposeMultidimensionalArray(T, Allocator)(auto ref Allocator alloc, auto ref T[] array)
{
static if (isArray!T)
{
Expand All @@ -1895,6 +1922,8 @@ void disposeMultidimensionalArray(T, Allocator)(auto ref Allocator alloc, T[] ar
}

dispose(alloc, array);
static if (__traits(isRef, array))
array = null;
}

///
Expand Down

0 comments on commit 2b0ae1f

Please sign in to comment.