[Issue 15399] unaligned pointers are not @safe

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Mar 4 11:40:46 UTC 2018


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

--- Comment #7 from ag0aep6g at gmail.com ---
(In reply to Walter Bright from comment #6)
> (In reply to ag0aep6g from comment #5)
> > Reopening because these very slight variations are still accepted:
> > 
> > 1) hosts[n] = Unaligned(0, new Victim);
> > 2) Unaligned u = { p: new Victim }; hosts[n] = u;
> 
> I don't know what that means. Can you please post a complete example?


//////////////////////////////// test.d ////////////////////////////////
@safe:

struct Victim
{
    bool alive = true;
    ~this() { alive = false; }
}

align(1)
struct Unaligned
{
align(1):
    ubyte filler;
    Victim* p;
}

pragma(msg, Unaligned.sizeof);

void main()
{
    enum N = 100;

    Unaligned[N] hosts;

    foreach (n; 0..N)
    {
        version (original) hosts[n].p = new Victim;
        else version (variation1) hosts[n] = Unaligned(0, new Victim);
        else version (variation2)
        {
            Unaligned u = { p: new Victim };
            hosts[n] = u;
        }
        else static assert(false);
        assert(hosts[n].p.alive);
    }

    // Unaligned.p is invisible to the GC due to alignment

    void trustedCollect() @trusted { import core.memory; GC.collect(); }
    trustedCollect();

    foreach (n; 0..N)
        assert(hosts[n].p.alive); // Dangling pointer!
}
////////////////////////////////////////////////////////////////////////

These should all fail with the same error:

    dmd -version=original test.d
    dmd -version=variation1 test.d
    dmd -version=variation2 test.d

The different versions effectively do the same thing, just with different
syntax.

--


More information about the Digitalmars-d-bugs mailing list