Jump to page: 1 2
Thread overview
[Issue 20802] [REG2.088.0] Link failure with writefln
May 06, 2020
Tim
Jan 10, 2023
Iain Buclaw
Feb 11
Spoov
Feb 18
Dlang Bot
Feb 18
Dlang Bot
Mar 01
Dlang Bot
May 06, 2020
https://issues.dlang.org/show_bug.cgi?id=20802

Tim <tim.dlang@t-online.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |link-failure

--
January 10, 2023
https://issues.dlang.org/show_bug.cgi?id=20802

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ibuclaw@gdcproject.org

--- Comment #1 from Iain Buclaw <ibuclaw@gdcproject.org> ---
Now:
---
issue20802.o: in function
`_D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv':
issue20802.d:(.text._D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv[_D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv]+0x19):
undefined reference to
`_D4core9exception__T15__switch_errorTZQsFNaNbNiNeAyamZv'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1

--
February 07
https://issues.dlang.org/show_bug.cgi?id=20802

Richard Cattermole <alphaglosined@gmail.com> changed:

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

--- Comment #2 from Richard Cattermole <alphaglosined@gmail.com> ---
Another more slimmed down version that was experienced by someone on the N.G.

```d
import std.uni, std.stdio;

void main() {
     auto c1 = CodepointSet('a','z'+1);
     writefln("%s", c1);
}
```

```
/dlang/dmd/linux/bin64/../../src/druntime/import/core/internal/switch_.d:189:
error: undefined reference to
'_D4core9exception__T15__switch_errorTZQsFNaNbNiNeAyamZv'
```

https://forum.dlang.org/post/nvjgpznfizkishhubcuz@forum.dlang.org

--
February 07
https://issues.dlang.org/show_bug.cgi?id=20802

Carl Sturtivant <sturtivant@gmail.com> changed:

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

--
February 11
https://issues.dlang.org/show_bug.cgi?id=20802

Spoov <spoov0.707@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |spoov0.707@gmail.com

--- Comment #3 from Spoov <spoov0.707@gmail.com> ---
The example can be simplified a bit, same error as in previous comment:

############ test.d ##############
import std.uni;
void main()
{
     CodepointSet('a', 'z');
     dstring s;
     decodeGrapheme(s);
}
##################################

Reducing std.uni yields the code below, same error as above:

#### phobos/std/uni/package.d ####
module std.uni;

enum TransformRes { goOn }

void writeAligned()()
{
    final switch (TransformRes.goOn) { case TransformRes.goOn: break; }
}

struct GcPolicy {}
alias CodepointSet = InversionList!GcPolicy;
struct InversionList(SP=GcPolicy)
{
    this()(uint[] intervals...)
    {
        sanitize();
    }

    void sanitize()
    {
        throw new Exception("");
        writeAligned();
    }
}

void decodeGrapheme(Input)(ref Input inp)
{
    final switch (TransformRes.goOn) { case TransformRes.goOn: break; }
}
##################################

A final switch generates a call to core.internal.switch_.__switch_error for
handling the default case.
core.internal.switch_.__switch_error calls core.exception.__switch_errorT.
Both functions are templates.

By default a D program links with libphobos2.a.
libphobos2.a contains sanitize and writeAligned but not __switch_error and
__switch_errorT.
This is because libphobos2.a gets build in release mode which causes the call
to __switch_error to be replaced with a ud2 instruction.

The linker error shows that __switch_error is present but __switch_errorT is missing.

In the compiler is this code
https://github.com/dlang/dmd/blob/8ab0636400d890a777889b3c84b09bcaa119fd57/compiler/src/dmd/dsymbolsem.d#L4666
which handles the case where a template that got instantiated from a non-root
module,
gets instantiated from a root module.
The code fixes the template instantiation, but misses the template
instantiations that are caused by it.
Because of this __switch_errorT is not emitted to the object file.

The following three files form a minimal example that reproduces the issue:

############# a.d ################
import b;
extern(C) void main() => bar!true;

############# b.d ################
void missing()() {}
void foo()() => missing();
void bar(bool b)() { version (Release) {} else foo(); }
enum fptr = &bar!false;

########## object.d ##############
// empty to make debugging simpler

$ dmd -c -version=Release b.d
$ dmd a.d b.o
a.o: In function `_D1b__T3fooZQfFNaNbNiNfZv':
a.d:(.text._D1b__T3fooZQfFNaNbNiNfZv[_D1b__T3fooZQfFNaNbNiNfZv]+0x5): undefined
reference to `_D1b__T7missingZQjFNaNbNiNfZv'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1

--
February 18
https://issues.dlang.org/show_bug.cgi?id=20802

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #4 from Dlang Bot <dlang-bot@dlang.rocks> ---
@tim-dlang created dlang/dmd pull request #16200 "Fix Bugzilla 20802 - Link failure with writefln" fixing this issue:

- Fix Bugzilla 20802 - Link failure with writefln

  The issue is caused by compiling druntime/phobos and the application
  with different flags. The template instance for __switch_errorT is not
  included in the build of druntime/phobos, because they are compiled
  with -release. DMD will also not include it in an application compiled
  without -release, because it assumes, that it is already in druntime.
  See comment https://issues.dlang.org/show_bug.cgi?id=20802#c3 by Spoov.

  As a workaround the template instance for __switch_errorT is now always
  instantiated in druntime.

https://github.com/dlang/dmd/pull/16200

--
February 18
https://issues.dlang.org/show_bug.cgi?id=20802

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #5 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #16200 "Fix Bugzilla 20802 - Link failure with writefln" was merged into stable:

- f4ee5234bccf21a4d2b5ca6d3962ccc3dd7a7d06 by Tim Schendekehl:
  Fix Bugzilla 20802 - Link failure with writefln

  The issue is caused by compiling druntime/phobos and the application
  with different flags. The template instance for __switch_errorT is not
  included in the build of druntime/phobos, because they are compiled
  with -release. DMD will also not include it in an application compiled
  without -release, because it assumes, that it is already in druntime.
  See comment https://issues.dlang.org/show_bug.cgi?id=20802#c3 by Spoov.

  The template instance for __switch_errorT is now always instantiated in
  druntime, so it is part of the ABI of druntime.

https://github.com/dlang/dmd/pull/16200

--
February 19
https://issues.dlang.org/show_bug.cgi?id=20802

--- Comment #6 from anonymous4 <dfj1esp02@sneakemail.com> ---
This looks like a rather fundamental collision between speculative instantiation and conditional compilation. __switch_errorT can't be in druntime unconditionally because its behavior changes depending on compilation options.

--
February 20
https://issues.dlang.org/show_bug.cgi?id=20802

--- Comment #7 from Iain Buclaw <ibuclaw@gdcproject.org> ---
(In reply to anonymous4 from comment #6)
> This looks like a rather fundamental collision between speculative instantiation and conditional compilation. __switch_errorT can't be in druntime unconditionally because its behavior changes depending on compilation options.
Because it's a weak symbol, any local instantiation would override the unconditional instantiation in druntime.

--
February 20
https://issues.dlang.org/show_bug.cgi?id=20802

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |puneet@coverify.org

--- Comment #8 from Iain Buclaw <ibuclaw@gdcproject.org> ---
*** Issue 23255 has been marked as a duplicate of this issue. ***

--
« First   ‹ Prev
1 2