Thread overview
[Issue 22864] [REG 2.067] Throwing in array literal leads to destructor being called on unconstructed data
Mar 23, 2022
RazvanN
Mar 23, 2022
Iain Buclaw
Apr 05, 2022
Dlang Bot
March 23, 2022
https://issues.dlang.org/show_bug.cgi?id=22864

RazvanN <razvan.nitu1305@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |razvan.nitu1305@gmail.com

--- Comment #1 from RazvanN <razvan.nitu1305@gmail.com> ---
This is a gluelayer problem (common for all 3 backends). I haven't looked at what gdc and ldc do, but in dmd the gluelayer first inserts a call to _d_arrayliteral (which allocates the array with the gc) and then it calls getS(). Look ma! I even got the code to prove it: https://github.com/dlang/dmd/blob/master/src/dmd/e2ir.d#L4834.  I assume that this is what gdc and ldc do also, so it's not a frontend bug.

The solution could be to first store the initializers on the stack and memcpy them after we allocate the array (essentially, the else branch of the verion in the original report).

--
March 23, 2022
https://issues.dlang.org/show_bug.cgi?id=22864

Iain Buclaw <ibuclaw@gdcproject.org> changed:

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

--- Comment #2 from Iain Buclaw <ibuclaw@gdcproject.org> ---
Doesn't affect gdc-11

This is the codegen:
---
  struct S[] ret;
  struct S slot[1];
  void* mem;

  ret.length = 1;
  slot[0] = getS (); [return slot optimization]
  mem = _d_arrayliteralTX (&_D25TypeInfo_AS10issue228641S6__initZ, 1);
  __builtin_memcpy (mem, &slot, 1);
  ret.ptr = mem;
  return ret.ptr;
---

The abort occurs if the array allocation and getS() calls are reversed.
---
  struct S[] ret;
  struct S slot[1];
  void* mem;

  ret.length = 1;
  mem = _d_arrayliteralTX (&_D25TypeInfo_AS10issue228641S6__initZ, 1);
  slot[0] = getS (); [return slot optimization]
  __builtin_memcpy (mem, &slot, 1);
  ret.ptr = mem;
  return ret.ptr;
---

So with ldc (and maybe dmd), it's an issue with what order arguments are evaluated in.  As at a high level, the lowered code would look like:
---
memcpy (_d_arrayliteralTX(), getS(), 1);
---
I guess it would be enforced LTR evaluation of C function calls.

--
April 05, 2022
https://issues.dlang.org/show_bug.cgi?id=22864

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #3 from Dlang Bot <dlang-bot@dlang.rocks> ---
@RazvanN7 created dlang/dmd pull request #13951 "Fix Issue 22864 - [REG 2.067] Throwing in array literal leads to destructor being called on unconstructed data" fixing this issue:

- Fix Issue 22864 - [REG 2.067] Throwing in array literal leads to destructor being called on unconstructed data

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

--
December 13
https://issues.dlang.org/show_bug.cgi?id=22864

--- Comment #4 from dlangBugzillaToGithub <robert.schadek@posteo.de> ---
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/18089

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB

--