[Bug 70] dtor / destructor not called for (rvalue) struct used in opApply

gdc-bugzilla at gdcproject.org gdc-bugzilla at gdcproject.org
Sun Jul 14 00:32:00 PDT 2013


http://bugzilla.gdcproject.org/show_bug.cgi?id=70

Johannes Pfau <johannespfau at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |NEW
                 CC|                            |johannespfau at gmail.com
         Resolution|FIXED                       |

--- Comment #6 from Johannes Pfau <johannespfau at gmail.com> 2013-07-14 07:32:00 UTC ---
This bug fix has caused all remaining unit test failures (except the math
ones). The problem is that a function can throw without actually having
constructed the object and now we always call the dtor. A test case is
attached.


What dmd does is pretty weird. It doesn't handle this in toElemDtor because of
the reason stated above, there's absolutely no error handling in toElemDtor.
It's also not handled in the frontend.

Once the complete IR of a function is available, (eh.c: except_fillInEHTable)
iterates over all expressions. According to a comment dmd only handles
temporaries where the ctor&dtor are called in the same expression this way.

So what we should do is after we have the GENERIC representation of a function,
we have to do something like this pseudo code:

foreach(tree exp; functionIR)
{
    outer: foreach(i, tree exp2; compound(exp))
    {
        if(exp2.isctor)
        {
            size_t numCtor = 1;
            size_t indexFirstDtor = 0;
            foreach(j, tree exp3; compound(exp)[i+1 .. $])
            {
                if(exp.isctor)
                    numCtor++;
                else if(exp.isdtor)
                {
                    numCtor--;
                    if(indexFirstDtor == 0)
                        indexFirstDtor = j;
                    if(n == 0) //found all matching dtors
                    {
                        tree handler =
tryfinally(compound(exp)[i+1..firstDtor], compound(exp)[firstDtor..j+1]);
                        compound(exp)[i+1 .. j+1].replace(handler);
                        break outer; //AFAICS executing the inner loop once is
enough
                    }
                }
            }
        }
    }
}

Now I don't claim this code is pretty or correct, dmd has enough dtor related
bugs and this may be the cause of some. But this is what the dmd code currently
does.

In long term this needs to be fixed in the frontend though. I think we should
never rely on the glue layer to insert try/catch/finally statements. Instead
dmd should lower this "(DestroyMe __sl6 = DestroyMe(); ,
__sl6).opApply(delegate int(int item)" into "(DestroyMe __sl6 = DestroyMe();,
try{__sl6).opApply(delegate int(int item)}finally{__sl6.~this()})"


BTW: The unit test failure "null this" in parallelism.d is caused by the dtor
_not_ being called as in the original test case. So if we revert this fix
without applying a new fix, the std.parallelism test is the only failing test.

-- 
Configure bugmail: http://bugzilla.gdcproject.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching all bug changes.


More information about the D.gnu mailing list