www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 14903] New: Destructors for arguments completely broken

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

          Issue ID: 14903
           Summary: Destructors for arguments completely broken
           Product: D
           Version: D2
          Hardware: x86
                OS: Mac OS X
            Status: NEW
          Severity: major
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: code klickverbot.at

While finalizing the LDC 2.067 merge, Martin and I stumbled over major DMD
codegen issues for structs with destructors as function arguments. [1]

Consider this program:

---
import core.stdc.stdio;

struct Foo {
    const char* name;
    bool throwInDtor;

    this(const char* name, bool throwInDtor) {
        printf("Constructing %s\n", name);
        this.name = name;
        this.throwInDtor = throwInDtor;
    }

    ~this() {
        printf("Destroying %s\n", name);
        if (throwInDtor)
            throw new Exception("dtor " ~ name[0]);
    }
}

Foo make(const char* name, bool doThrow) {
    if (doThrow)
        throw new Exception("make()");
    return Foo(name, false);
}

void foo(Foo a, Foo b, Foo c, Foo d) { throw new Exception("foo()!"); }

void main() {
    foo(Foo("a", true), make("b", true), Foo("c", false), make("d", true));
}
---

Depending on the arguments to the Foo constructor and make, we can get
different test cases for exception chaining and destruction of temporaries (DMD
2.068.0, OS X x86_64):

---
1) foo(Foo("a", true), make("b", false), Foo("c", true), make("d", false))
Constructing a
Constructing b
Constructing c
Constructing d
Destroying a
Destroying b
Destroying c
Destroying d
object.Exception test.d(27): foo()!
object.Exception test.d(17): dtor a
object.Exception test.d(17): dtor c

2) foo(Foo("a", true), make("b", false), Foo("c", true), make("d", true))
Constructing a
Constructing b
Constructing c
object.Exception test.d(23): make()

3) foo(Foo("a", false), make("b", false), Foo("c", false), make("d", true))
Constructing a
Constructing b
Constructing c
object.Exception test.d(23): make()

4) foo(Foo("a", false), make("b", true), Foo("c", false), make("d", true))
Constructing a
object.Exception test.d(23): make()

5) foo(Foo("a", true), make("b", true), Foo("c", false), make("d", true))
Constructing a
object.Exception test.d(23): make()
---


1) is correct, although the order of destruction is somewhat unexpected (given
that they are destroyed by the callee, this is probably not wrong, though).

However, the destructors in 2) to 5) are never called.


[1] Our issue is at
https://github.com/ldc-developers/ldc/issues/1010#issuecomment-129596359

--
Aug 10 2015