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