Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Fix issue 21578 - core.atomic.atomicFetchSub for pointers incorrectly… #3343

Merged
merged 1 commit into from
Jan 27, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion src/core/atomic.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow... I'm sorry! That's an epic fail!

else
return core.internal.atomic.atomicFetchSub!ms(&val, cast(T)mod);
}
Expand Down Expand Up @@ -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);
rymrg marked this conversation as resolved.
Show resolved Hide resolved
}
{
auto array = ulongArray;
ulong* ptr = &array[0];
rymrg marked this conversation as resolved.
Show resolved Hide resolved
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;
Expand All @@ -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;
Expand Down