Bug 20321 – Uncontrollable blitting should be preventable for proper elaborate copy semantics

Status
NEW
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-10-25T22:33:26Z
Last change time
2024-12-13T19:05:59Z
Assigned to
No Owner
Creator
Suleyman Sahmi (سليمان السهمي)
Moved to GitHub: dmd#19633 →

Comments

Comment #0 by sahmi.soulaimane — 2019-10-25T22:33:26Z
The same symptoms of issue #17448 but with copy semantics as well. Even though D supports elaborate copy with the copy constructor and the postblit, the compiler(s) still move(s) objects in certain cases in an unpreventable manner, which blocks certain practices that require strict copy control such as saving internal pointers. Following is an example which fails on DMD, GDC, and LDC as of date. Note that every case in the following example is a copy operation not a move, i.e the source is an lvalue. https://run.dlang.io/is/qomDRU ``` /** Container with internal pointer */ struct Container { long[3] data; void* p; this(int) { p = &data[0]; } this(ref inout Container) inout { p = &data[0]; } /** Ensure the internal pointer is correct */ void check(int line = __LINE__, string file = __FILE__)() { if (p != &data[0]) { import core.stdc.stdio : printf; printf("%s(%d): %s\n", file.ptr, line, "error".ptr); } } } void func(Container c) { c.check(); } // error Container get() { auto a = Container(1); auto b = a; a.check(); // ok b.check(); // ok // no nrvo if (1) return a; else return b; } Container get2() out(r){} do { auto v = Container(1); v.check(); // ok return v; } void main() { Container v = Container(1); v.check(); // ok func(v); auto r = get(); r.check(); // error auto r2 = get2(); r.check(); // error Container[1] slit = [v]; slit[0].check(); // error Container[] dlit = [v]; dlit[0].check(); // error auto b = B(v); b.m.check(); // error } struct B { Container m; } ``` output: --- test.d(22): error test.d(53): error test.d(56): error test.d(59): error test.d(62): error test.d(65): error --- expected: no output
Comment #1 by kinke — 2019-10-26T02:30:08Z
Thx, I've just hacked LDC to get this testcase green (on Win64 at least): https://github.com/ldc-developers/ldc/pull/3204
Comment #2 by sahmi.soulaimane — 2019-10-26T03:26:48Z
Comment #3 by dlang-bot — 2019-11-20T22:37:29Z
@SSoulaimane updated dlang/dmd pull request #10539 "Fix the concat assign case of Issue 20321 in a frontend solution" mentioning this issue: - Issue 20321 - Move CatElemAssign logic to the frontend Solves one of the cases of issue 20321 which wasn't straight forward to solve in the backend since elablorate copy semantics are currently understood by the semantic phase only. See issues 17448 and 20321. The problem is solved by avoiding `doCopyOrMove()` which only partially helps the backend with elaborate copy. This goes hand in hand with the effort being spent on templatizing druntime, this benefit from that effort actually. https://github.com/dlang/dmd/pull/10539
Comment #4 by robert.schadek — 2024-12-13T19:05:59Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19633 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB