www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 20321] New: Uncontrollable blitting should be preventable for

https://issues.dlang.org/show_bug.cgi?id=20321

          Issue ID: 20321
           Summary: Uncontrollable blitting should be preventable for
                    proper elaborate copy semantics
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: blocker
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: sahmi.soulaimane gmail.com



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

--
Oct 25 2019