From fbf5f525756e51879578c2663643449a5c9c4040 Mon Sep 17 00:00:00 2001 From: rymrg <54061433+rymrg@users.noreply.github.com> Date: Mon, 25 Jan 2021 11:09:04 +0200 Subject: [PATCH] Fix issue 21578 - core.atomic.atomicFetchSub for pointers incorrectly calls wrong function from core.internal.atomic --- src/core/atomic.d | 48 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/core/atomic.d b/src/core/atomic.d index 06b6029d15..c70af402f4 100644 --- a/src/core/atomic.d +++ b/src/core/atomic.d @@ -196,7 +196,7 @@ T atomicFetchSub(MemoryOrder ms = MemoryOrder.seq, T)(ref T val, size_t mod) pur in (atomicValueIsProperlyAligned(val)) { static if (is(T == U*, U)) - return cast(T)core.internal.atomic.atomicFetchAdd!ms(cast(size_t*)&val, mod * U.sizeof); + return cast(T)core.internal.atomic.atomicFetchSub!ms(cast(size_t*)&val, mod * U.sizeof); else return core.internal.atomic.atomicFetchSub!ms(&val, cast(T)mod); } @@ -1143,6 +1143,29 @@ version (CoreUnittest) } } + @betterC pure nothrow @nogc unittest + { + byte[10] byteArray = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]; + ulong[10] ulongArray = [2, 4, 6, 8, 10, 12, 14, 16, 19, 20]; + + { + auto array = byteArray; + byte* ptr = &array[0]; + byte* prevPtr = atomicFetchAdd(ptr, 3); + assert(prevPtr == &array[0]); + assert(*prevPtr == 1); + assert(*ptr == 7); + } + { + auto array = ulongArray; + ulong* ptr = &array[0]; + ulong* prevPtr = atomicFetchAdd(ptr, 3); + assert(prevPtr == &array[0]); + assert(*prevPtr == 2); + assert(*ptr == 8); + } + } + @betterC pure nothrow @nogc @safe unittest { shared ubyte u8 = 1; @@ -1167,6 +1190,29 @@ version (CoreUnittest) } } + @betterC pure nothrow @nogc unittest + { + byte[10] byteArray = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]; + ulong[10] ulongArray = [2, 4, 6, 8, 10, 12, 14, 16, 19, 20]; + + { + auto array = byteArray; + byte* ptr = &array[5]; + byte* prevPtr = atomicFetchSub(ptr, 4); + assert(prevPtr == &array[5]); + assert(*prevPtr == 11); + assert(*ptr == 3); // https://issues.dlang.org/show_bug.cgi?id=21578 + } + { + auto array = ulongArray; + ulong* ptr = &array[5]; + ulong* prevPtr = atomicFetchSub(ptr, 4); + assert(prevPtr == &array[5]); + assert(*prevPtr == 12); + assert(*ptr == 4); // https://issues.dlang.org/show_bug.cgi?id=21578 + } + } + @betterC pure nothrow @nogc @safe unittest // issue 16651 { shared ulong a = 2;