From 62ae7ad99b00abe0d582a781d5154579e48108c3 Mon Sep 17 00:00:00 2001 From: MoonlightSentinel Date: Sun, 19 Apr 2020 11:53:20 +0200 Subject: [PATCH] Fix Issue 20748 - Deprecation for assert using shared type and checkaction=context --- src/core/internal/dassert.d | 21 ++++++++++++++++++++- test/exceptions/src/assert_fail.d | 7 +++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/core/internal/dassert.d b/src/core/internal/dassert.d index ff14840ca3..0b56d03ffc 100644 --- a/src/core/internal/dassert.d +++ b/src/core/internal/dassert.d @@ -75,7 +75,21 @@ private string miniFormat(V)(const ref V v) import core.internal.traits: isAggregateType; import core.stdc.stdio : sprintf; import core.stdc.string : strlen; - static if (is(V : bool)) + + static if (is(V == shared T, T)) + { + // Use atomics to avoid race conditions whenever possible + static if (__traits(compiles, atomicLoad(v))) + { + T tmp = cast(T) atomicLoad(v); + return miniFormat(tmp); + } + else + { // Fall back to a simple cast - we're violating the type system anyways + return miniFormat(*cast(T*) &v); + } + } + else static if (is(V == bool)) { return v ? "true" : "false"; } @@ -189,6 +203,11 @@ private string miniFormat(V)(const ref V v) } } +// This should be a local import in miniFormat but fails with a cyclic dependency error +// core.thread.osthread -> core.time -> object -> core.internal.array.capacity +// -> core.atomic -> core.thread -> core.thread.osthread +import core.atomic : atomicLoad; + // Inverts a comparison token for use in _d_assert_fail private string invertCompToken(string comp) { diff --git a/test/exceptions/src/assert_fail.d b/test/exceptions/src/assert_fail.d index 22dbf09e31..64a8352c7b 100644 --- a/test/exceptions/src/assert_fail.d +++ b/test/exceptions/src/assert_fail.d @@ -29,6 +29,7 @@ void testIntegers()() test(uint.min, uint.max, "0 != 4294967295"); test(long.min, long.max, "-9223372036854775808 != 9223372036854775807"); test(ulong.min, ulong.max, "0 != 18446744073709551615"); + test(shared(ulong).min, shared(ulong).max, "0 != 18446744073709551615"); int testFun() { return 1; } test(testFun(), 2, "1 != 2"); @@ -79,6 +80,9 @@ void testToString()() } test(new Foo("a"), new Foo("b"), "Foo(a) != Foo(b)"); + scope f = cast(shared) new Foo("a"); + test!"!="(f, f, "Foo(a) == Foo(a)"); + // Verifiy that the const toString is selected if present static struct Overloaded { @@ -135,6 +139,9 @@ void testStruct()() NoCopy n; test(_d_assert_fail!"!="(n, n), "NoCopy() == NoCopy()"); + + shared NoCopy sn; + test(_d_assert_fail!"!="(sn, sn), "NoCopy() == NoCopy()"); } void testAA()()