Thread overview
[Issue 19937] object._d_assert_fail linker error if compiling with -checkaction=context
Jun 03, 2019
JR
Aug 03, 2019
Seb
Aug 03, 2019
Seb
Feb 24, 2020
Mathias LANG
Feb 24, 2020
Mathias LANG
Feb 24, 2020
Mathias LANG
Apr 10, 2020
Bastiaan Veelo
Mar 18, 2022
kdevel
Dec 17, 2022
Iain Buclaw
June 03, 2019
https://issues.dlang.org/show_bug.cgi?id=19937

--- Comment #1 from JR <zorael@gmail.com> ---
Apologies, I should mention Manjaro/Arch x86_64, dmd v2.086.0 from official repositories.

--
August 03, 2019
https://issues.dlang.org/show_bug.cgi?id=19937

Seb <greeenify@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |greeenify@gmail.com

--- Comment #2 from Seb <greeenify@gmail.com> ---
Demangled:

---
checkaction.o:checkaction.d:function const pure nothrow @nogc @trusted bool
std.uni.Trie!(std.uni.BitPacked!(bool, 1uL).BitPacked, dchar, 1114112uL,
std.uni.sliceBits!(13uL, 21uL).sliceBits, std.uni.sliceBits!(8uL,
13uL).sliceBits, std.uni.sliceBits!(0uL,
8uL).sliceBits).Trie.opIndex!().opIndex(dchar): error: undefined reference to
'pure nothrow @nogc @safe immutable(char)[] object._d_assert_fail!("<", ulong,
ulong)._d_assert_fail(ulong, ulong)'
---


Code generated from DMD looks like this:

```
inout pure nothrow @nogc @system BitPacked!(bool, 1LU) opIndex(ulong idx)
                        in
                        {
                                assert(idx < this.limit, _d_assert_fail(idx,
this.limit));
                        }
                        do
                        {
                                {
                                        {
                                                assert(idx < this.limit,
_d_assert_fail(idx, this.limit));
                                        }
                                }
                                return this.ptr.opIndex(this.ofs + idx);
                        }
```


...


```
_d_assert_fail!("<", ulong, ulong)
{
        pure nothrow @nogc @safe string _d_assert_fail(ulong a, ulong b)
        {
                import core.internal.dassert : invertCompToken,
miniFormatFakeAttributes, pureAlloc;
                string valA = miniFormatFakeAttributes(a);
                string valB = miniFormatFakeAttributes(b);
                enum string token = ">=";
                const const(ulong) totalLen = valA.length + 2LU + valB.length +
2LU;
                char[] buffer = cast(char[])pureAlloc(totalLen)[0..totalLen];
                ulong n = valA.length;
                buffer[0..n] = cast(const(char[]))valA;
                buffer[n++] = ' ';
                buffer[n..n + 2LU] = ">=";
                n += 2LU;
                buffer[n++] = ' ';
                buffer[n..n + valB.length] = cast(const(char[]))valB;
                return delegate () => cast(string)buffer();
        }

}
```

but it doesn't appear in the object file:

```
$ nm bar.o | grep assert_fail | ddemangle
0000000000000000 W pure nothrow @nogc @trusted immutable(char)[]
object._d_assert_fail!("<", uint, uint)._d_assert_fail(uint, uint).__lambda3()
0000000000000000 W pure nothrow @nogc @safe immutable(char)[]
object._d_assert_fail!("<", uint, uint)._d_assert_fail(uint, uint)
                 U pure nothrow @nogc @safe immutable(char)[]
object._d_assert_fail!("<", ulong, ulong)._d_assert_fail(ulong, ulong)
0000000000000000 W pure nothrow @nogc @trusted immutable(char)[]
object._d_assert_fail!(">=", uint, uint)._d_assert_fail(uint, uint).__lambda3()
0000000000000000 W pure nothrow @nogc @safe immutable(char)[]
object._d_assert_fail!(">=", uint, uint)._d_assert_fail(uint, uint)
```

DMD probably thinks that this assertion was already instantiated in Phobos (and thus should be part of the object file), but it is not as Phobos was build without -checkaction=context.

--
August 03, 2019
https://issues.dlang.org/show_bug.cgi?id=19937

--- Comment #3 from Seb <greeenify@gmail.com> ---
BTW a workaround is to do force the instantiation e.g. with the following hack:

```
cat << EOF > workaround.d
void test(ulong x, ulong y){
    assert(x < y);
}
EOF
```

```
dmd -checkaction=context -c workaround.d
dmd -checkaction=context workaround.o checkaction.d
```

--
February 24, 2020
https://issues.dlang.org/show_bug.cgi?id=19937

Mathias LANG <pro.mathias.lang@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pro.mathias.lang@gmail.com

--- Comment #4 from Mathias LANG <pro.mathias.lang@gmail.com> ---
I'm seeing this with anything that involves Vibe.d as well, with DMD v2.090.1.

--
February 24, 2020
https://issues.dlang.org/show_bug.cgi?id=19937

Mathias LANG <pro.mathias.lang@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|x86_64                      |All
                 OS|Linux                       |All
           Severity|enhancement                 |major

--
February 24, 2020
https://issues.dlang.org/show_bug.cgi?id=19937

--- Comment #5 from Mathias LANG <pro.mathias.lang@gmail.com> ---
@Seb: Thanks for the pointer. Unfortunately in the Vibe.d case it is nastier,
because the symbol takes a `ref` and a non-ref. Turns out `assert(x > y)` and
`assert(x > 0)` will generate different symbol (the former's second argument is
`ref` while the later is not, being a rvalue).

--
April 10, 2020
https://issues.dlang.org/show_bug.cgi?id=19937

Bastiaan Veelo <Bastiaan@Veelo.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Bastiaan@Veelo.net

--- Comment #6 from Bastiaan Veelo <Bastiaan@Veelo.net> ---
Assuming Seb's assessment of phobos being compiled without `-checkaction=context` is the root cause, here is another test case:

```
import std;
void main()
{
  wchar[] c;
  c.toUTF8;
}
```

Compiling this with `-checkaction=context` produces
```
Error 42: Symbol Undefined
__D4core8internal7dassert__T24miniFormatFakeAttributesTkZQBdFNaNbNiNfKxkZAya
```

The link error vanishes if the argument `-debug` or `-release` is added, or if the import is changed into `import std.utf;`. This happens for DMD64 D Compiler v2.091.0-dirty on Windows, couldn't reproduce this on run.dlang.io.

Bastiaan.

--
March 18, 2022
https://issues.dlang.org/show_bug.cgi?id=19937

kdevel <kdevel@vogtner.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kdevel@vogtner.de

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=19937

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P2

--