August 23, 2019
https://issues.dlang.org/show_bug.cgi?id=20155

          Issue ID: 20155
           Summary: Allocating a struct with dtor on the GC heap can
                    produce false pointers
           Product: D
           Version: D2
          Hardware: x86
                OS: Windows
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: druntime
          Assignee: nobody@puremagic.com
          Reporter: r.sagitario@gmx.de

import core.memory;

void main()
{
    // for 64-bit, allocate a struct of size 40
    static struct S
    {
        size_t[4] data;
        S* ptr4;
    }
    auto p1 = new S;
    auto p2 = new S;
    p2.ptr4 = p1;

    // a struct with a dtor with size 32, but the dtor will cause
    //  allocation to be larger by a pointer
    static struct A
    {
        size_t[3] data;
        S* ptr3;

        ~this() {}
    }

    GC.free(p2);
    auto a = new A; // reuse same memory
    if(cast(void*)a is cast(void*)p2) // reusage not guaranteed
    {
        auto ptr = cast(S**)(a + 1);
        assert(*ptr != p1); // still same data as p2.ptr4?
    }
}

The problem is that allocating a struct with a dtor saves a pointer to the type info with the struct, but not within the beginning area of the allocation, but at the end of the actually allocated block. This contradicts assumptions of the GC that only clears the area after the requested size, assuming the rest to be initialized by the caller.

Array allocations have a similar issue as they store the requested length at the  end of the allocated blcok, but it is less critical because these are only 1 or 2 bytes.

--