Skip to content

C++ deleting destructor leaks memory #23458

Description

@tim-dlang

When an extern(C++) class is declared in D, but freed from C++, it calls the virtual deleting destructor. Currently DMD only calls the destructor, but does not free the memory, so this can cause silent memory leaks.

See TODO comment in DMD for Itanium ABI:

if (target.cpp.twoDtorInVtable)
{
// TODO: create a C++ compatible deleting destructor (call out to `operator delete`)
// for the moment, we'll call the non-deleting destructor and leak
cldec.vtbl[cldec.cppDtorVtblIndex + 1] = cldec.dtor;
}

For Windows there is a similar TODO comment:
// // TODO: if (del) delete (char*)this;

Previous discussion is in #8277.

There are different options to implement this:

  • Directly calling operator delete in the deleting destructor would be simple, but break code using extern(C++), but not using C++ new/delete.
  • The deleting destructor could call a configurable callback in druntime, but this would not work with BetterC.
  • A pragma or UDA could be used to enable/disable the deleting destructor. This would preserve backward compatibility, but users have to remember to do this, so memory is not leaked. In a future edition it could be enabled by default. The UDA/pragma could also be inherited by subclasses, so only a base class has to be marked.

I currently think a pragma would be best and will create a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions