[Issue 2451] Adding structs that use opAssign or postblit to an AA is broken

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Oct 19 15:08:16 PDT 2010


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


Don <clugdbug at yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


--- Comment #9 from Don <clugdbug at yahoo.com.au> 2010-10-19 15:07:26 PDT ---
Here's a patch. 
Do the opAssign onto a temporary variable, then blit the temporary into the AA
as normal.

TEST CASE:
struct Foo {
    int z = 3;
    void opAssign(Foo x) { z= 2;}
}

struct Foo2 {
    int z = 3;
    this(this){ z = 17; }
}

void main() {
    Foo[string] stuff;
    stuff["foo"] = Foo.init;
    assert(stuff["foo"].z == 2);

    Foo2[string] stuff2;
    Foo2 q;
    stuff2["dog"] = q;
    assert(stuff2["dog"].z == 17);   
}

PATCH: expression.c line 8966, AssignExp::semantic.
---------------------
    /* If it is an assignment from a 'foreign' type,
     * check for operator overloading.
     */
    if (t1->ty == Tstruct)
    {
        StructDeclaration *sd = ((TypeStruct *)t1)->sym;
        if (op == TOKassign)
        {
            Expression *e = op_overload(sc);

+            if (e && e1->op==TOKindex &&
+                ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
+            {
+                // Deal with AAs (Bugzilla 2451)
+                // Rewrite as:
+                // e1 = (typeof(e2) tmp = void, tmp = e2, tmp);
+                Identifier *id = Lexer::uniqueId("__aatmp");
+                VarDeclaration *v = new VarDeclaration(loc, e2->type, 
+                    id, new VoidInitializer(NULL));
+                v->storage_class |= STCctfe;

+                Expression *de = new DeclarationExp(loc, v);
+                VarExp *ve = new VarExp(loc, v);

+                AssignExp *ae = new AssignExp(loc, ve, e2);
+                e = ae->op_overload(sc);
+                e2 = new CommaExp(loc, new CommaExp(loc, de, e), ve);
+                e2 = e2->semantic(sc);
+            }
+            else
            if (e)
                return e;

-- 
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