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

Commit

Permalink
Fix Issue 19635 - -checkaction=context not working with attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
wilzbach committed Mar 7, 2019
1 parent d551653 commit 1de725f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 10 deletions.
33 changes: 28 additions & 5 deletions src/core/internal/dassert.d
Expand Up @@ -37,7 +37,7 @@ private template getPrintfFormat(T)
Minimalistic formatting for use in _d_assert_fail to keep the compilation
overhead small and avoid the use of Phobos.
*/
auto miniFormat(V)(auto ref V v)
auto miniFormat(V)(V v)
{
import core.stdc.stdio : sprintf;
import core.stdc.string : strlen;
Expand All @@ -49,14 +49,14 @@ auto miniFormat(V)(auto ref V v)
{
enum printfFormat = getPrintfFormat!V;
char[20] val;
sprintf(val.ptr, printfFormat, v);
return val.idup[0 .. strlen(val.ptr)];
auto len = sprintf(&val[0], printfFormat, v);
return val.idup[0 .. len];
}
else static if (__traits(isFloating, V))
{
char[60] val;
sprintf(val.ptr, "%g", v);
return val.idup[0 .. strlen(val.ptr)];
auto len = sprintf(&val[0], "%g", v);
return val.idup[0 .. len];
}
else static if (__traits(compiles, { string s = V.init.toString(); }))
{
Expand Down Expand Up @@ -153,3 +153,26 @@ string invertCompToken(string comp)
}
}

private auto assumeFakeAttributes(T)(T t) @trusted
{
import core.internal.traits : Parameters, ReturnType;
alias RT = ReturnType!T;
alias P = Parameters!T;
alias type = RT function(P) nothrow @nogc @safe pure;
return cast(type) t;
}

auto miniFormatFakeAttributes(T)(T t)
{
alias miniT = miniFormat!T;
return assumeFakeAttributes(&miniT)(t);
}

auto pureAlloc(size_t t)
{
static auto alloc(size_t len)
{
return new ubyte[len];
}
return assumeFakeAttributes(&alloc)(t);
}
28 changes: 23 additions & 5 deletions src/object.d
Expand Up @@ -4819,11 +4819,29 @@ TTo[] __ArrayCast(TFrom, TTo)(TFrom[] from) @nogc pure @trusted
}

// Allows customized assert error messages
string _d_assert_fail(string comp, A, B)(A a, B b)
string _d_assert_fail(string comp, A, B)(A a, B b) @nogc @safe nothrow pure
{
import core.internal.dassert : invertCompToken, miniFormat;
auto valA = miniFormat(a);
auto valB = miniFormat(b);
import core.internal.dassert : invertCompToken, miniFormatFakeAttributes, pureAlloc;
/*
The program will be terminated after the assertion error message has
been printed and its not considered part of the "main" program.
Also, catching an AssertError is Undefined Behavior
Hence, we can fake purity and @nogc-ness here.
*/

auto valA = miniFormatFakeAttributes(a);
auto valB = miniFormatFakeAttributes(b);
enum token = invertCompToken(comp);
return valA ~ " " ~ token ~ " " ~ valB;

const totalLen = valA.length + token.length + valB.length + 2;
char[] buffer = cast(char[]) pureAlloc(totalLen)[0 .. totalLen];
// @nogc-concat of "<valA> <comp> <valB>"
auto n = valA.length;
buffer[0 .. n] = valA;
buffer[n++] = ' ';
buffer[n .. n + token.length] = token;
n += token.length;
buffer[n++] = ' ';
buffer[n .. n + valB.length] = valB;
return buffer;
}
8 changes: 8 additions & 0 deletions test/exceptions/src/assert_fail.d
Expand Up @@ -112,6 +112,13 @@ void testAA()()
test!"in"("foo", ["bar": true], `"foo" !in ["bar": true]`);
}


void testAttributes() @safe pure @nogc nothrow
{
int a;
assert(a == 0);
}

void main()
{
testIntegers();
Expand All @@ -122,5 +129,6 @@ void main()
testArray();
testStruct();
testAA();
testAttributes();
fprintf(stderr, "success.\n");
}

0 comments on commit 1de725f

Please sign in to comment.