digitalmars.D.ldc - LDC2 Clobbering Local Variableswith std.typecons' nullable.
- LeqxLeqx (103/103) Aug 13 2021 I have encountered a very strange (apparent) error related to the
- kinke (5/6) Aug 13 2021 Might be, but you're using a version that's almost 4 years old.
- kinke (3/4) Aug 13 2021 2021-2018=3, my bad. :D - Still kind-of stone-age with a new
- kinke (5/6) Aug 13 2021 Since v2.097, it was just a deprecation before. And it makes all
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.
Aug 13 2021
On Saturday, 14 August 2021 at 03:13:00 UTC, LeqxLeqx wrote:Or is this a compiler bug?Might be, but you're using a version that's almost 4 years old. With run.dlang.io and its current LDC v1.26 (not the latest version either...), your testcase works with all optimization levels (line 36 needs a `.get()` since Phobos v2.096).
Aug 13 2021
On Saturday, 14 August 2021 at 03:41:33 UTC, kinke wrote:version that's almost 4 years old2021-2018=3, my bad. :D - Still kind-of stone-age with a new release every ~2 months. ;)
Aug 13 2021
On Saturday, 14 August 2021 at 03:41:33 UTC, kinke wrote:line 36 needs a `.get()` since Phobos v2.096Since v2.097, it was just a deprecation before. And it makes all the difference, i.e., v1.26.0 still fails (and segfaults with -O1) without the .get(). Interesting, will look into it in the near future.
Aug 13 2021
On Saturday, 14 August 2021 at 04:03:02 UTC, kinke wrote:On Saturday, 14 August 2021 at 03:41:33 UTC, kinke wrote:Oh, my bad. I didn't realize that apt repo was so far out of date. I'll install a newer version. Thank you very much!line 36 needs a `.get()` since Phobos v2.096Since v2.097, it was just a deprecation before. And it makes all the difference, i.e., v1.26.0 still fails (and segfaults with -O1) without the .get(). Interesting, will look into it in the near future.
Aug 13 2021
On Saturday, 14 August 2021 at 04:03:02 UTC, kinke wrote:Interesting, will look into it in the near future.Pretty bad, and not LDC-specific: https://issues.dlang.org/show_bug.cgi?id=22209
Aug 13 2021
On Saturday, 14 August 2021 at 04:21:21 UTC, kinke wrote:On Saturday, 14 August 2021 at 04:03:02 UTC, kinke wrote:Wow, that's something, eh? Thank you very much for analyzing this and getting to the root of the issue!Interesting, will look into it in the near future.Pretty bad, and not LDC-specific: https://issues.dlang.org/show_bug.cgi?id=22209
Aug 14 2021
On Saturday, 14 August 2021 at 18:09:27 UTC, LeqxLeqx wrote:On Saturday, 14 August 2021 at 04:21:21 UTC, kinke wrote:Yeah, memory corruption caused by the compiler is one of the worst things. Thanks for reporting and providing the testcase! The fix should land in DMD v2.098 / LDC v1.28.On Saturday, 14 August 2021 at 04:03:02 UTC, kinke wrote:Wow, that's something, eh? Thank you very much for analyzing this and getting to the root of the issue!Interesting, will look into it in the near future.Pretty bad, and not LDC-specific: https://issues.dlang.org/show_bug.cgi?id=22209
Aug 14 2021