December 07, 2017
https://issues.dlang.org/show_bug.cgi?id=18045

          Issue ID: 18045
           Summary: Temporary created during comparison not destroyed
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: blocker
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: andrei@erdani.com

Consider:

import std.stdio;

struct A
{
    int state;
    this(this) { writeln("postblit: A(", state, ")"); }
    ~this() { writeln("dtor: A(", state, ")"); }
}

A fun()
{
    static a = A(42);
    return a;
}

int main()
{
    static a = A(-42);
    return fun() == a;
}

The code outputs:

postblit: A(42)

What happens is the following. Static objects issue no constructor or destructor calls. The construction is done during compilation, and destructor is not called for data with static lifetime (see https://issues.dlang.org/show_bug.cgi?id=14650).

The postblitted object is the temporary copied from within fun() into its return value. As the output shows, that temporary is never destroyed. It should be destroyed at the end of the full expression.

This bug seems to manifest itself with '==` and 'is', but not if I write e.g.

    return fun().state == 0;

--