March 28, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

--- Comment #10 from RazvanN <razvan.nitu1305@gmail.com> ---
(In reply to Andrei Alexandrescu from comment #8)
> It seems the main anomaly is that cast() yields (sometimes...) an lvalue for
> shared data. Razvan, can you investigate if code would break if we forced
> cast() on shared data to always return an rvalue?

The intention in the compiler code is that casts should always return rvalues, however the optimizer can simply bypass the check sometimes. For example:

const(int) x;
cast()x = 5;

Here the optimizer sees that x is a constant and rewrites the cast to `cast(int)0`; later on when the lhs expression is analyzed to see if it is modifiable you get the confusing error that Mathias pointed out. In the case of `shared x` it cannot constfold x since the variable could be modified from another thread so it simply drops `shared` from the lhs type. I would argue that an optimizing pass should be done only after semantic is done.

It seems that the simplest way to deal with these cases is to simply allow cast expressions to return lvalue in some situations; these situations are already described in the spec [1], under the "Lvalue" section.

[1] https://dlang.org/spec/expression.html#definitions-and-terms

--
May 24, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #11 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #9505 "Fix Issue 19754 - cast() sometimes yields lvalue, sometimes yields rvalue" was merged into master:

- 91e7151838a703e9c31cf308f3711ddee47c86e6 by RazvanN7:
  Fix Issue 19754 - cast() sometimes yields lvalue, sometimes yields rvalue

https://github.com/dlang/dmd/pull/9505

--
May 25, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

--- Comment #12 from ag0aep6g <ag0aep6g@gmail.com> ---
*** Issue 17729 has been marked as a duplicate of this issue. ***

--
June 29, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=20011

--
June 30, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

kinke <kinke@gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
                 CC|                            |kinke@gmx.net
         Resolution|FIXED                       |---

--- Comment #13 from kinke <kinke@gmx.net> ---
It does yield an lvalue now with v2.087, but a wrong one (temporary, I guess):

void main()
{
    const x = 0;
    const p = &x;
    (cast() x) = 5; // wrongly const-folded to 0 = 5
    assert(*p == 5); // fails, still 0
}

--
June 30, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

--- Comment #14 from ag0aep6g <ag0aep6g@gmail.com> ---
(In reply to kinke from comment #13)
> It does yield an lvalue now with v2.087, but a wrong one (temporary, I
> guess):
> 
> void main()
> {
>     const x = 0;
>     const p = &x;
>     (cast() x) = 5; // wrongly const-folded to 0 = 5
>     assert(*p == 5); // fails, still 0
> }

That code is invalid. Mutating x has undefined behavior.

--
June 30, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

--- Comment #15 from kinke <kinke@gmx.net> ---
More to the point:

void main()
{
    const x = 0;
    assert(&x == &(cast() x)); // fails; lowered to `assert(& x is &0)`
}

--
July 02, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

--- Comment #16 from RazvanN <razvan.nitu1305@gmail.com> ---
The root problem here is that dmd does optimizations and semantic analysis in the same pass. Will try to fix this.

--
July 02, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

--- Comment #17 from Dlang Bot <dlang-bot@dlang.rocks> ---
@RazvanN7 created dlang/dmd pull request #10121 "Fix Issue 19754 - cast() sometimes yields lvalue, sometimes yields rvalue" fixing this issue:

- Fix Issue 19754 - cast() sometimes yields lvalue, sometimes yields rvalue

https://github.com/dlang/dmd/pull/10121

--
July 02, 2019
https://issues.dlang.org/show_bug.cgi?id=19754

--- Comment #18 from Dlang Bot <dlang-bot@dlang.rocks> ---
@kinke created dlang/dmd pull request #10124 "[WIP] [stable] Don't optimize()
lhs lvalues of (bin)assign expressions to constants " mentioning this issue:

- Respect `keepLvalue` when optimizing/const-folding a CastExp

  One aspect of issue 19754.

https://github.com/dlang/dmd/pull/10124

--