From 62ae7ad99b00abe0d582a781d5154579e48108c3 Mon Sep 17 00:00:00 2001 From: MoonlightSentinel Date: Sun, 19 Apr 2020 11:53:20 +0200 Subject: [PATCH 1/2] 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()() From a045839291d07a9366d42920f1cf30b030d9fc35 Mon Sep 17 00:00:00 2001 From: MoonlightSentinel Date: Sun, 19 Apr 2020 13:54:52 +0200 Subject: [PATCH 2/2] Fix Issue 20750 - checkaction=context segfaults for null references --- src/core/internal/dassert.d | 19 +++++++++++++------ test/exceptions/src/assert_fail.d | 3 +++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/core/internal/dassert.d b/src/core/internal/dassert.d index ff14840ca3..1aa730186a 100644 --- a/src/core/internal/dassert.d +++ b/src/core/internal/dassert.d @@ -97,14 +97,21 @@ private string miniFormat(V)(const ref V v) { return "`null`"; } - else static if (__traits(compiles, { string s = v.toString(); })) - { - return v.toString(); - } - // Non-const toString(), e.g. classes inheriting from Object + // toString() isn't always const, e.g. classes inheriting from Object else static if (__traits(compiles, { string s = V.init.toString(); })) { - return (cast() v).toString(); + // Object references / struct pointers may be null + static if (is(V == class) || is(V == interface) || is(V == U*, U)) + { + if (v is null) + return "`null`"; + } + + // Prefer const overload of toString + static if (__traits(compiles, { string s = v.toString(); })) + return v.toString(); + else + return (cast() v).toString(); } // Static arrays or slices (but not aggregates with `alias this`) else static if (is(V : U[], U) && !isAggregateType!V) diff --git a/test/exceptions/src/assert_fail.d b/test/exceptions/src/assert_fail.d index 22dbf09e31..5513c08630 100644 --- a/test/exceptions/src/assert_fail.d +++ b/test/exceptions/src/assert_fail.d @@ -94,6 +94,9 @@ void testToString()() } test!"!="(Overloaded(), Overloaded(), "Const == Const"); + + Foo fnull = null; + test!"!is"(fnull, fnull, "`null` is `null`"); }