Lowerings to strongly pure _d_arrayctor trigger warnings or risk being incorrectly removed
Paul Backus
snarwin at gmail.com
Tue Oct 12 16:46:00 UTC 2021
On Tuesday, 12 October 2021 at 16:27:51 UTC, Teodor Dutu wrote:
> Hi,
>
> I've been working on [this
> PR](https://github.com/dlang/dmd/pull/13116) for a while now
> and after seeing it fail some tests in phobos (for example,
> [this
> one](https://cirrus-ci.com/task/5609501660282880?logs=test_phobos#L116)), my mentors for SAoC 2021, Razvan Nitu and Eduard Staniloiu, and I figured out that, when lowered using `const` or `immutable` arguments, `_d_arrayctor` becomes a strongly pure function. For instance, in the code snippet below
> ```d
> struct S {};
> const S[2] b;
> const S[2] a = b;
> ```
> the line `const S[2] a = b` is lowered to `_d_arrayctor(a, b)`,
> which is the intended behaviour.
I think the fundamental problem is that what `_d_arrayctor` is
doing here is undefined behavior, according to the language spec:
> Note that casting away a const qualifier and then mutating is
> undefined behavior, too, even when the referenced data is
> mutable.
Source: https://dlang.org/spec/const3.html#removing_with_cast
The spec makes [a special exception][1] for `struct` and `class`
constructors, which allows them to write to non-mutable memory
once without invoking UB, but there is no corresponding exception
for variables that are not part of a `struct` or `class`.
In order to make progress on this, it will be necessary to change
both the language spec and the compiler to allow initialization
of non-mutable memory by library code. These changes will,
presumably, render the optimization you are currently fighting
against invalid.
[1]: https://dlang.org/spec/struct.html#field-init
More information about the Digitalmars-d
mailing list