This error, however, is not very helpful, as it does not say anything about any error, just giving some context. The src/dmd/dtoh.d line is only an information message enabled by -vtls.
As the output of the command looks incomplete, it may be useful to run the command directly, instead of through portage. The output in a terminal of this command is:
src/dmd/target.d(122): called from here: defaultTargetOS()
src/dmd/dtoh.d(428): `warned` is thread local
Illegal instruction
Yikes, Illegal instruction, not the best thing to see. So, we have stumbled into an ICE bug. Let's start with the only information we know, src/dmd/target.d(122).
Target.OS defaultTargetOS()
{
version (Windows)
return Target.OS.Windows;
else version (linux)
return Target.OS.linux;
else version (OSX)
return Target.OS.OSX;
else version (FreeBSD)
return Target.OS.FreeBSD;
else version (OpenBSD)
return Target.OS.OpenBSD;
else version (Solaris)
return Target.OS.Solaris;
else version (DragonFlyBSD)
return Target.OS.DragonFlyBSD;
else
static assert(0, "unknown TARGET");
}
extern (C++) struct Target
{
/// Bit decoding of the Target.OS
enum OS : ubyte
{
/* These are mutually exclusive; one and only one is set.
,* Match spelling and casing of corresponding version identifiers
,*/
Freestanding = 0,
linux = 1,
Windows = 2,
OSX = 4,
OpenBSD = 8,
FreeBSD = 0x10,
Solaris = 0x20,
DragonFlyBSD = 0x40,
// Combination masks
all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
}
OS os = defaultTargetOS(); // (this is the line)
We have a struct Target that has a member os. Since D structs must have a compile time known default constructor, it means that defaultTargetOS() needs to be executed at compile time. The function is defined above, a glorified compile time if statement, that returns a Target.OS type. This is probably where the error resides, the compiler ran into a cycle of Target needing defaultTargetOS needing Target. To make sure let's start by making changes to the code.
We start small, only changing the defaultTargetOS's body to:
ubyte defaultTargetOS()
{
return 1;
}
// ...
OS os = cast(Target.OS)defaultTargetOS(); // (this is the line)
Now we get an erorr in another place, but this time it's an actual error:
src/dmd/mars.d(265): Error: cannot implicitly convert expression defaultTargetOS() of type ubyte to OS
This is something we can work it. Obviously, by changing the function, other places in the code now fail, needing the cast(Target.OS). Changing mars.d, which is the only other file referencing the function, we are finally able to build >dmd-2.097.
There is another way to achieve this result, since the error happens when calling the function at compile time,
we can just not call it:
OS os = OS.linux; // (this is the line)
This would accomplish the same thing, allbeit without platform compatibility, by changing a single line, more managable then 1 function and 2 files.
Although the same code appears in ldc2, its compilation succeds, for reasons I can't argue.
I am not asking for a change to be made (i.e. a new patch to be added), I just wanted to write down the reasons why that removal has been made, and possible fixes, for an easy future reference. The commit which introduced the breaking change is https://github.com/dlang/dmd/commit/f4bfbd7e008c05645b68af85a749ad13d593480b
2_083 has been removed as a valid DLANG_VERSION for dmd-2.097 and onward. This is done because there is a build failure:
This error, however, is not very helpful, as it does not say anything about any error, just giving some context. The
src/dmd/dtoh.d
line is only an information message enabled by-vtls
.As the output of the command looks incomplete, it may be useful to run the command directly, instead of through portage. The output in a terminal of this command is:
Yikes,
Illegal instruction
, not the best thing to see. So, we have stumbled into an ICE bug. Let's start with the only information we know,src/dmd/target.d(122)
.We have a struct
Target
that has a memberos
. Since D structs must have a compile time known default constructor, it means thatdefaultTargetOS()
needs to be executed at compile time. The function is defined above, a glorified compile time if statement, that returns aTarget.OS
type. This is probably where the error resides, the compiler ran into a cycle ofTarget
needingdefaultTargetOS
needingTarget
. To make sure let's start by making changes to the code.We start small, only changing the
defaultTargetOS
's body to:No, same error. Let's try to get rid of the type:
Now we get an erorr in another place, but this time it's an actual error:
This is something we can work it. Obviously, by changing the function, other places in the code now fail, needing the
cast(Target.OS)
. Changing mars.d, which is the only other file referencing the function, we are finally able to build >dmd-2.097.There is another way to achieve this result, since the error happens when calling the function at compile time, we can just not call it:
This would accomplish the same thing, allbeit without platform compatibility, by changing a single line, more managable then 1 function and 2 files.
Although the same code appears in ldc2, its compilation succeds, for reasons I can't argue.
I am not asking for a change to be made (i.e. a new patch to be added), I just wanted to write down the reasons why that removal has been made, and possible fixes, for an easy future reference. The commit which introduced the breaking change is https://github.com/dlang/dmd/commit/f4bfbd7e008c05645b68af85a749ad13d593480b