Unexpected static assert bypass
(1.38.0, 1.39.0-beta1)
Two lines of code only, file assertion_test_main.d:
static assert(false, "some assertion failed");
import core.stdc.stdatomic;
Trying to compile:
> ldc2 -c assertion_test_main.d
assertion_test_main.d(1): Error: static assert: "some assertion failed"
But if compiler called with --mtriple=:
> ldc2 --mtriple=riscv32-unknown-newlib-elf -c assertion_test_main.d
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(31): Error: module `core.stdc.stdint` import `intptr_t` not found
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(798): Error: module `core.sys.posix.sys.types` import `ssize_t` not found, did you mean alias `object.size_t`?
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(802): Error: undefined identifier `c_long`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(2011): Error: module `core.stdc.stddef` import `wchar_t` not found
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(1470): Error: `pragma(printf)` function `vsprintf` must have signature `int vsprintf([parameters...], const(char)*, va_list)`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(1473): Error: `pragma(scanf)` function `vsscanf` must have signature `int vsscanf([parameters...], const(char)*, va_list)`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(1476): Error: `pragma(printf)` function `vprintf` must have signature `int vprintf([parameters...], const(char)*, va_list)`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(1479): Error: `pragma(scanf)` function `vscanf` must have signature `int vscanf([parameters...], const(char)*, va_list)`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(1537): Error: undefined identifier `c_long`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(1539): Error: undefined identifier `c_long`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(2003): Error: `pragma(printf)` function `vsnprintf` must have signature `int vsnprintf([parameters...], const(char)*, va_list)`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/time.d(34): Error: undefined identifier `time_t`, did you mean function `time`?
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/time.d(34): Error: undefined identifier `time_t`, did you mean function `time`?
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/time.d(37): Error: undefined identifier `time_t`, did you mean function `time`?
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/time.d(37): Error: undefined identifier `tm`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/time.d(40): Error: undefined identifier `time_t`, did you mean function `time`?
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/time.d(40): Error: undefined identifier `time_t`, did you mean function `time`?
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/time.d(43): Error: undefined identifier `tm`
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/time.d(46): Error: undefined identifier `time_t`, did you mean function `time`?
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/time.d(49): Error: undefined identifier `tm`
Compiler bypasses not only first assert line of my assertion_test_main.d file, but also static asserts inside of druntime modules like as in core.stdc.time, and placed near to start of file static assert(false, "unsupported system"); isn't triggered
This looks like a frontend bug, please file the bug with DMD upstream.
Can't reproduce on the upstream:
> ../../dmd/dmd -conf=dmd.conf -target=x86-linux -c assertion_test_main.d
Error: the architecture must not be changed in the Environment64 section of dmd.conf
> ../../dmd/dmd -conf=dmd.conf -mcpu=avx2 -c assertion_test_main.d
assertion_test_main.d(1): Error: static assert: "some assertion failed"
> ../../dmd/dmd -vasm -c assertion_test_main.d
assertion_test_main.d(1): Error: static assert: "some assertion failed"
> ../../dmd/dmd -conf=dmd.conf -target=x86_64-linux -c assertion_test_main.d
assertion_test_main.d(1): Error: static assert: "some assertion failed"
Perhaps is a bug in the frontend, but it doesn't show up because you can’t switch the architecture through triples in DMD?
Can you try to make a reproducing test case without druntime involved?
Probably something like this works:
static assert(false, "asdad");
import module_that_has_error;
// file module_that_has_error.d
something a;
Found the reason of such behaviour: with unlimited errors (--verrors=0) compiler outputs appropriate static assert error message, but only at end of output:
> ldc2 --mtriple=riscv32 --verrors=0 -c assertion_test_main.d
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdio.d(31): Error: module `core.stdc.stdint` import `intptr_t` not found
[...skip93 lines...]
/home/denizzz/ldc2_standalone/bin/../import/core/stdc/stdint.d(539): Error: undefined identifier `wint_t`
assertion_test_main.d(1): Error: static assert: "some assertion failed"
Thus, static assert is triggered as expected, but the compiler shows appropriate message only after all another found errors, and such static assert errors on daily used real modules do not appear into the output
I think it makes sense to show static assert error first as being much more important
Imports are most likely processed before static asserts. This is nothing LDC-specific obviously.
It might make sense to add a comment into stderr, like: "displayed not all found errors, make sure there isn't something interesting at the end of the list using --verrors=0"?
I just remembered that several years ago I already encountered into this
you can still file a quality-of-life feature request upstream (same bug tracker)
https://issues.dlang.org/show_bug.cgi?id=24645