From 1113bf1476ca66bac8a25bea4598daf6fb4bd598 Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Sat, 12 Mar 2016 00:22:50 +0100 Subject: [PATCH] fix Issue 15353 - ignore freeing during finalization --- changelog.dd | 7 +++++++ src/core/memory.d | 12 ++++++------ src/gc/gc.d | 19 ++++++++++++++++++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/changelog.dd b/changelog.dd index 3a5574d9366..483759021e9 100644 --- a/changelog.dd +++ b/changelog.dd @@ -7,6 +7,7 @@ $(BUGSTITLE Library Changes, $(LI $(RELATIVE_LINK2 aa-clear, A `clear` method has been added to associative arrays to remove all elements.)) +$(LI Calls to $(NCXREF memory, GC.free) are now ignored during finalization instead of throwing an InvalidMemoryOperationError, see $(BUGZILLA 15353).) ) $(BUGSTITLE Library Changes, @@ -42,6 +43,12 @@ Macros: COREMODREF = $2 XREF = $2 CXREF = $2 + OXREF = $2 + NXREF = $2 + NCXREF = $2 + NOXREF = $2 + + BUGZILLA = Bugzilla $0 BOOKTABLE = $+
$1
PRE =
$0
diff --git a/src/core/memory.d b/src/core/memory.d index 40b3a8f8d7d..22e2fe9b43e 100644 --- a/src/core/memory.d +++ b/src/core/memory.d @@ -552,12 +552,12 @@ struct GC /** - * Deallocates the memory referenced by p. If p is null, no action - * occurs. If p references memory not originally allocated by this - * garbage collector, or if it points to the interior of a memory block, - * no action will be taken. The block will not be finalized regardless - * of whether the FINALIZE attribute is set. If finalization is desired, - * use delete instead. + * Deallocates the memory referenced by p. If p is null, no action occurs. + * If p references memory not originally allocated by this garbage + * collector, if p points to the interior of a memory block, or if this + * method is called from a finalizer, no action will be taken. The block + * will not be finalized regardless of whether the FINALIZE attribute is + * set. If finalization is desired, use delete instead. * * Params: * p = A pointer to the root of a valid memory block or to null. diff --git a/src/gc/gc.d b/src/gc/gc.d index 16aec1e231a..dafe85c340e 100644 --- a/src/gc/gc.d +++ b/src/gc/gc.d @@ -813,7 +813,7 @@ struct GC */ void free(void *p) nothrow { - if (!p) + if (!p || inFinalizer) { return; } @@ -3250,6 +3250,23 @@ unittest // bugzilla 14467 assert(arr.capacity); } +unittest // bugzilla 15353 +{ + import core.memory : GC; + + static struct Foo + { + ~this() + { + GC.free(buf); // ignored in finalizer + } + + void* buf; + } + new Foo(GC.malloc(10)); + GC.collect(); +} + /* ============================ SENTINEL =============================== */