www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 22177] New: emplace should handle throwing constructors

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

          Issue ID: 22177
           Summary: emplace should handle throwing constructors
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: druntime
          Assignee: nobody puremagic.com
          Reporter: kinke gmx.net

This segfaults with v2.097.1:

```
extern(C) void free(void* p);

struct S
{
    void* p;
    this(int)
    {
        p = cast(void*) 0xdeadbeef;
        throw new Exception("blub");
    }
    ~this()
    {
        if (p)
            free(p);
    }
}

void regular()
{
    try
    {
        auto s = S(0); // not destructed because not successfully constructed
    }
    catch (Exception) {}
}

void empl()
{
    import core.lifetime;
    try
    {
        S s = void;
        emplace(&s, 0);
    } // `s` is destructed but in no well-defined state - boom
    catch (Exception) {}
}

void main()
{
    regular();
    empl();
}
```

The emplace family (incl. copyEmplace for throwing postblit/copy constructor)
should take care of resetting the instance to `T.init` in case of a throw, so
that (unavoidable) destruction is well-defined.

It should probably only do so if an Exception is thrown (as opposed to an
Error), to avoid the overhead for `nothrow` constructors.

This was suggested here:
https://github.com/dlang/druntime/pull/3483#discussion_r682629332

--
Aug 04