[Issue 20321] New: Uncontrollable blitting should be preventable for proper elaborate copy semantics

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Oct 25 22:33:26 UTC 2019


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 at puremagic.com
          Reporter: sahmi.soulaimane at gmail.com

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

--


More information about the Digitalmars-d-bugs mailing list