[Issue 6681] struct constructor call is converted to struct literal that breaks union initialization

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Mar 13 05:32:51 PDT 2012


http://d.puremagic.com/issues/show_bug.cgi?id=6681



--- Comment #13 from yebblies <yebblies at gmail.com> 2012-03-13 23:32:59 EST ---
Thanks for doing this.  I think my branch was still letting you return
partially uninitialized arrays/structs from ctfe.  I also think the following
should work:

union U
{
   int a, b;
}
int func()
{
   U u;
   u.a = 3;
   assert(u.b == 3);
   return 1;
}
static assert(func());

But I don't know how to implement it. (it might not be worth it)

Umm, test cases. (some pass, some fail, some pulled out of other test cases in
dmd/phobos.)  The last one should fail, I doubt it's useful leave a variable
partially initialized.


/*
version(none)
{
    struct S
    {
        this(int a, int b) { this.a = b; this.b = a; }
        union {
            ulong g;
            struct
            {
                int a;
                int b;
            }
        }
    }

    static immutable S s = S(1, 0);

    extern(C) int printf(const char *, ...);

    void main()
    {
        S s = .s;
        printf("%d %d %d\n", s.g, s.a, s.b);
    }
}

version(none)
{
    union in6_addr
    {
        private union _in6_u_t
        {
            ubyte[16] u6_addr8;
            ushort[8] u6_addr16;
            uint[4] u6_addr32;
        }
        _in6_u_t in6_u;

        ubyte[16] s6_addr8;
        ushort[8] s6_addr16;
        uint[4] s6_addr32;

        alias s6_addr8 s6_addr;
    }


    const in6_addr IN6ADDR_ANY = { s6_addr8: [0] };
}


version(none)
{
    struct Zadok
    {
        char [4] s = void;
    }

    int quop()
    {
        Zadok pong;
        pong.s = ['z','x','f', 'g'];
        return 1;
    }

    static assert(quop()==1);
    static assert(quop()==1); // check for clobbering
}


//version = testc;
version(testc)
{
    union U
    {
        int a;
        int b;
    }

    int testxx()
    {
        U u;
        u.a = 7;
        u.b = 4;
        assert(u.a == 7);
        assert(u.b == 4);
        return 1;
    }

    static assert(testxx());
}

//version = testb;
version(testb)
{
    void fillWithZero(T)(T[] arr)
    {
        foreach(ref x; arr)
            x = 7;
    }

    T[4] f(T)()
    {
        T[4] stackSpace = void;
        T[4] x = stackSpace;
        int y = x[0];
        //int z = y + y;
        fillWithZero(stackSpace[]);
        return stackSpace;
    }

    static assert(f!int() == [7,7,7,7]); 
}

//version = testa;
version(testa)
{
    interface SomeInterface
    {
      int daz();
      float bar(char);
      int baz();
    }

    interface SomeOtherInterface
    {
        int xxx();
    }

    class TheBase : SomeInterface, SomeOtherInterface
    {
        int q = 88;
        int rad = 61;
        int a = 14;
        int somebaseclassfunc() { return 28;}
        int daz() { return 0; }
        int baz() { return 0; }
        int xxx() { return 762; }
        int foo() { return q; }
        float bar(char c) { return 3.6; }
    }

    class SomeClass : TheBase, SomeInterface
    {
        int gab = 9;
        int fab;
        int a = 17;
        int b = 23;
        int foo() { return gab + a; }
        float bar(char c) { return 2.6; }
        int something() { return 0; }
        int daz() { return 0; }
        int baz() { return 0; }
    }

    class Unrelated : TheBase {
        this(int x) { a = x; }
    }

    auto classtest1(int n)
    {
        SomeClass c = new SomeClass;
        assert(c.a == 17);
        assert(c.q == 88);
        TheBase d = c;
        assert(d.a == 14);
        assert(d.q == 88);
        if (n==7)
        {   // bad cast -- should fail
            Unrelated u = cast(Unrelated)d;
            assert(u is null);
        }
        SomeClass e = cast(SomeClass)d;
        d.q = 35;
        assert(c.q == 35);
        assert(c.foo() == 9 + 17);
        ++c.a;
        assert(c.foo() == 9 + 18);
        assert(d.foo() == 9 + 18);
        d = new TheBase;
        SomeInterface fc = c;
        SomeOtherInterface ot = c;
        assert(fc.bar('x') == 2.6);
        assert(ot.xxx() == 762);
        fc = d;
        ot = d;
        assert(fc.bar('x') == 3.6);
        assert(ot.xxx() == 762);

        Unrelated u2 = new Unrelated(7);
        assert(u2.a == 7);
        return 6;
    }
    static assert(classtest1(1));
    static assert(classtest1(2));
    static assert(classtest1(7)); // bug 7154
}

//version = testd;
version(testd)
{
    struct XY { union { int x, y; } }
    struct AHolder {
        XY aa;
        void a(XY x) { aa = x; }
    }
    struct AB {
        AHolder aHolder;
        XY b;
        void a(XY x) { aHolder.a(x); }
    }
    struct Main {
        AB ab;

        void setB() { ab.b = XY(); }
        void f() {
            ab.a(XY.init);
            setB();
        }
    }
}

//version = teste;
version(teste)
{
    union U
    {
        int a;
        long b;
    }

    long test()
    {
        U u;
        u.a = 3;
        u.b = 8;
        return u.a + u.b;
    }

    static assert(test() == 11);
}

//version = testf;
version(testf)
{
    int[5] test()
    {
        int[5] var = void;
        var[0] = 6;
        var[2] = 6;
        var[4] = 6;
        return var;
    }
    pragma(msg, test());
}
*/

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list