LDC2 Clobbering Local Variableswith std.typecons' nullable.

LeqxLeqx mitchelldlarson at protonmail.ch
Sat Aug 14 03:13:00 UTC 2021


I have encountered a very strange (apparent) error related to the 
use of std.typecons' nullable and unions. I appear to be able to 
clobber the immediately preceding stack variable to a function 
call if that function makes use of an implicit cast from a 
nullable wrapped struct to the unwrapped struct where the struct 
contains a union type which contains an array. Sorry for how 
strange these requirements are, but I cannot seem to replicate 
the issue without all of these. See this code:

```D
// Arbitrary union with at least one array member.
union MyUnion
{
   int[] _array;
}

// Struct with the above union and at least one other member.
struct MyStruct
{
   private int _int; // required (for some reason)
   private MyUnion _MyUnion;
}

void main()
{
   import std.stdio : writefln;

   // setting local `myLocal' to something not null and then 
invoking
   // my method (defined below) `clobber' appears to set the value 
to
   // null.

   string myLocal = "NOT NULL";
   writefln("myLocal (before clobber): `%s'.", myLocal);
   clobber();
   writefln("myLocal (after clobber):  `%s'.", myLocal);
}

MyStruct clobber()
{
   import std.typecons : nullable;

   // create a new struct and return it.
   // Must use the implicit cast. Using `.get' doesn't induce the 
bug

   auto ret = nullable(MyStruct());
   return ret;
}
```

The output of this program when compiled under ldc2 is:
```
myLocal (before clobber): `NOT NULL'.
myLocal (after clobber):  `'.

```

Oddly enough, for `-O1` and above, the output is the more correct:
```
myLocal (before clobber): `NOT NULL'.
myLocal (after clobber):  `NOT NULL'.
```
(of note, for `-O1` but not `-O0` or `-O2` and above, the program 
terminates with a SIGSEV)

Further, when compiled by GDC, the output appears correct.

I'm running all of this on Debian Buster and the below is the 
output of my `ldc2 --version`:
```
LDC - the LLVM D compiler (1.12.0):
   based on DMD v2.082.1 and LLVM 6.0.1
   built with LDC - the LLVM D compiler (1.12.0)
   Default target: x86_64-pc-linux-gnu
   Host CPU: ivybridge
   http://dlang.org - http://wiki.dlang.org/LDC

   Registered Targets:
     aarch64    - AArch64 (little endian)
     aarch64_be - AArch64 (big endian)
     amdgcn     - AMD GCN GPUs
     arm        - ARM
     arm64      - ARM64 (little endian)
     armeb      - ARM (big endian)
     avr        - Atmel AVR Microcontroller
     bpf        - BPF (host endian)
     bpfeb      - BPF (big endian)
     bpfel      - BPF (little endian)
     hexagon    - Hexagon
     lanai      - Lanai
     mips       - Mips
     mips64     - Mips64 [experimental]
     mips64el   - Mips64el [experimental]
     mipsel     - Mipsel
     msp430     - MSP430 [experimental]
     nvptx      - NVIDIA PTX 32-bit
     nvptx64    - NVIDIA PTX 64-bit
     ppc32      - PowerPC 32
     ppc64      - PowerPC 64
     ppc64le    - PowerPC 64 LE
     r600       - AMD GPUs HD2XXX-HD6XXX
     sparc      - Sparc
     sparcel    - Sparc LE
     sparcv9    - Sparc V9
     systemz    - SystemZ
     thumb      - Thumb
     thumbeb    - Thumb (big endian)
     wasm32     - WebAssembly 32-bit
     wasm64     - WebAssembly 64-bit
     x86        - 32-bit X86: Pentium-Pro and above
     x86-64     - 64-bit X86: EM64T and AMD64
     xcore      - XCore
```

Am I crazy? Or is this a compiler bug?

Any and all assistance would be much appreciated.


More information about the digitalmars-d-ldc mailing list