Thread overview
[Issue 21312] [REG 2.095] Newly triggered <expr> is not an lvalue and cannot be modified
Oct 15, 2020
Iain Buclaw
Oct 16, 2020
Mathias LANG
Nov 01, 2020
Dlang Bot
October 15, 2020
https://issues.dlang.org/show_bug.cgi?id=21312

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ibuclaw@gdcproject.org

--- Comment #1 from Iain Buclaw <ibuclaw@gdcproject.org> ---
So if looks like you are using `&[foo()][0]` to get around the fact that call
expressions aren't lvalues (e.g: `&foo()`).

Two questionable aspects of this come to mind.

1. There's nothing to prevent the optimizer removing the `[ ][0]` as being redundant.

2. There's nothing to prevent the array literal being stack allocated.

I'm not entirely sure of the validity of this, but I'll stop short of saying it is invalid.

--
October 16, 2020
https://issues.dlang.org/show_bug.cgi?id=21312

--- Comment #2 from Mathias LANG <pro.mathias.lang@gmail.com> ---
> So if looks like you are using `&[foo()][0]` to get around the fact that call expressions aren't lvalues (e.g: `&foo()`).

The code is in a deserializer. We handle pointers as single-entry arrays, and
the code follow that pattern. It recurses into itself, deserialize a single
entry of whatever the element type is, and use this to build an array. It then
takes the `.ptr` of this array.
It is no different in its intent from:
```
E[] result = [ deserializeFull!(...)(...) ];
return result.ptr;
```
Except that `result.ptr` is not `@safe`, so I'd have to use `return
&result[0];`, but was hoping to avoid bounds checking by putting the expression
inline.

> 1. There's nothing to prevent the optimizer removing the `[ ][0]` as being redundant.

`[][0]` might be redundant, but `&[][0]` is not, given `[]` does GC allocation.

> 2. There's nothing to prevent the array literal being stack allocated.

The compiler shouldn't promote it to the stack if it can't prove the address isn't escaping, which it is here.

--
November 01, 2020
https://issues.dlang.org/show_bug.cgi?id=21312

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

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

--- Comment #3 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #11873 " Fix Issue 21312 - Treat elements of (dynamic) array literals as lvalues again" was merged into master:

- eb14367b5da97657517f5b9626b01706d15b17a7 by Martin Kinkelin:
  Fix Issue 21312 - Treat elements of (dynamic) array literals as lvalues again

  Which entails making sure that const-folding doesn't descend into an
  array literal element if an lvalue is required.

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

--