www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1886] New: Inserting into an AA of structs with opAssign results in ArrayBoundsError

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1886

           Summary: Inserting into an AA of structs with opAssign results in
                    ArrayBoundsError
           Product: D
           Version: 2.011
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: ludwig informatik.uni-luebeck.de


Inserting into an associative array with structs as value types results in a
runtime error, as soon as the struct defines an opAssign. Structs without
opAssign work fine.

The code below will abort at runtime with an ArrayBoundsError exception:

-----------------
struct S {
        void opAssign( in S s ){}
}

int main()
{
        S[string] aa;
        aa["test"] = S(); // throws ArrayBoundsError

        return 0;
}
-----------------
Error: ArrayBoundsError bug_aaassign.d(8)


-- 
Mar 02 2008
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1886


burton-radons shaw.ca changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |burton-radons shaw.ca
           Severity|normal                      |major
            Version|2.011                       |2.023




------- Comment #1 from burton-radons shaw.ca  2009-02-14 12:35 -------
This bug still exists (2.023) and makes it impossible to use a Variant as the
value in an associative array, which is one of the most important uses for it.
However, the error message has changed to "core.exception.RangeError test(16):
Range violation".


-- 
Feb 14 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1886


Michael Rynn <y0uf00bar gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |y0uf00bar gmail.com


--- Comment #2 from Michael Rynn <y0uf00bar gmail.com> 2009-12-16 12:59:21 PST
---
Its not adding just opAssign. Having post-blit in a struct can do it too.
Documentation on struct in Associative Arrays in D2 is out of date.  Probably
because it mostly does not work. To return a pointer to the struct have to take
address of this



struct pblit {
     int x;

     pblit* opAssign(ref const pblit S)
     {
         this.x = S.x;

     }

     this(this)
     {
     }
     ~this()
     {
     }
} 

void main(char[][] args)
{
    pblit[string]   map;
    string[pblit]   rmap;

    pblit val;
    val.x = 12;

    rmap[val] = "test";   // this works
    map["test"] = val;    // oops! range error
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 16 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1886



--- Comment #3 from Michael Rynn <y0uf00bar gmail.com> 2009-12-16 13:09:14 PST
---
We are now 2.037 and still not fixed.

The documentation on D2.0 Associative Arrays with struct is wrong.
Adding the post-blit still allows the struct to be used as key, but not a
value. This is wierd. What is the approved opAssign example return type now?

     pblit opAssign(ref const pblit S)
     {
         this.x = S.x;
         return this; // return a value
     }

     -- OR ---
     pblit* opAssign(ref const pblit S)
     {
         this.x = S.x;
         return &this; // this is a struct!
     }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 16 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1886



--- Comment #4 from Michael Rynn <y0uf00bar gmail.com> 2009-12-16 19:10:53 PST
---
Sorry to split into 3 bits.  When I press tab the focus goes to the submit
button.

I stepped thru the x86 code generated in the debugger using Visual Studio 
2008 after conversion with cv2pdb -- great tool.

In the noblit case :- 
The code  calls __aaGet

    the arguments are the key, TypeInfo_Aa __init, and address of the 
map structure.
    An address? is returned in EAX, which is checked for null,
    The value of nval is directly blitted to the returned address.

    __aaGet does the checking if the key points to existing value, 
and allocates memory for new value as required.


In the postblit case the generated code seems to miss the point entirely.

The code initially makes a temporary copy of val. and calls the postblit 
constructor, which calls this(this).  -->  postblit__cpctor --> 
postblit __postblit.

Why is a prior temporary copy required, when one hopes that its the map 
that is going to provide the final destination?

From the temporary copy, it then pushes the bits value of the temporary 
(not the address!),
then the key, then TypeInfo_Aa __init, and address of map.

The code then calls __aaGetRvalue  ( not __aaGet )

__aaGetRvalue gives up very quickly, failing its first check.

     It pushes registers, and then checks the address in [esp+18h].
     This being null, it pop-exits with null as the result in eax.
     Obviously __aaGetRvalue is expecting something else to be setup.


     Presumably if __aaGetRvalue actually worked, it would just reblit 
the value in the temporary to the memory it allocated or found, without 
calling postblit again.

I would like to see ideally.
    No temporary copy made initially.

    The map lookup able to allocate or find memory for the key.
    The address returned.
    The copy made and then post-blit called.    

Failing that , please fix up __aaGetRvalue so it does the right thing.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 16 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1886


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au


--- Comment #5 from Don <clugdbug yahoo.com.au> 2010-05-25 13:27:52 PDT ---
Duplicate of bug 2451. However there is some useful information in the comments
for this bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 25 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1886


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |DUPLICATE


--- Comment #6 from Don <clugdbug yahoo.com.au> 2010-10-19 15:13:39 PDT ---
The patch for bug 2451 fixes this. Clearly a duplicate.

*** This issue has been marked as a duplicate of issue 2451 ***

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