Bug 21709 – std.conv.emplace not usable in betterC - 2.096
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-03-13T16:11:09Z
Last change time
2021-04-09T10:48:59Z
Assigned to
No Owner
Creator
mmcomando
Comments
Comment #0 by mmcomando — 2021-03-13T16:11:09Z
Our CI updated to dmd 2.096 and this error showed up:
/root/dlang/dmd-2.096.0/linux/bin64/../../src/druntime/import/core/internal/lifetime.d(35,13): Error: Cannot use try-catch statements with -betterC
/root/dlang/dmd-2.096.0/linux/bin64/../../src/druntime/import/core/internal/lifetime.d(57,21): Error: template instance `core.internal.lifetime.emplaceRef!(EntityManager, EntityManager, uint, uint, uint).emplaceRef.S.__ctor!()` error instantiating
CI job url:
https://gitlab.com/mmcomando/bubel-ecs/-/jobs/1095299347
From error message it seems that core.internal.lifetime.emplaceRef uses try-catch statement which is not supported by -betterC.
I have tried to look for the code on github but I have not found lines with try-catch in druntime/import/core/internal/lifetime.d(35,13) so I am not sure if try-catch is the problem.
Part of our code which uses emplace:
static T* make(T, Args...)(Args args)
{
T* ret = cast(T*) malloc(T.sizeof);
static import std.conv;
static if (__traits(isPOD, T))
{
__gshared immutable T init = T.init;
memcpy(ret, &init, T.sizeof);
}
else static if (is(T == struct))
std.conv.emplace(ret, args);
return ret;
}
Comment #1 by mmcomando — 2021-03-13T16:27:01Z
I was told that this code reproduces the issue:
import std.conv : emplace;
struct AA
{
~this()
{
}
}
extern(C) void main()
{
AA aa;
emplace(&aa, AA.init);
}
Comment #2 by moonlightsentinel — 2021-03-14T13:48:32Z
This regression was introduced by enabling -preview=dtorfields by default[1]. This preview inserts a destructor call into constructors that is executed when they abort with an exception (using a generated try ... catch ...).
DMD apparently fails to infer `nothrow` given that `-betterC` prohibits exceptions.
[1] https://github.com/dlang/dmd/pull/11656
Comment #3 by moonlightsentinel — 2021-03-14T13:49:24Z
(In reply to moonlightsentinel from comment #2)
> (using a generated try ... catch
EDIT: Only for functions that aren't `nothrow`
Comment #4 by dlang-bot — 2021-03-15T01:02:19Z
dlang/dmd pull request #12277 "Fix 21709 - Don't generate try-catch in betterC code for dtorfields" was merged into stable:
- afebdfa54ec01005da6ec62bc1249917b3b75a76 by MoonlightSentinel:
Fix 21709 - Don't generate try-catch in betterC code for dtorfields
The code may never throw exceptions in betterC mode, so it cannot abort
the ctor with an uncaught exception.
https://github.com/dlang/dmd/pull/12277
Comment #5 by moonlightsentinel — 2021-03-15T16:45:55Z
*** Issue 21720 has been marked as a duplicate of this issue. ***
Comment #6 by mmcomando — 2021-03-16T19:05:07Z
Thanks for quick fix!
Comment #7 by dlang-bot — 2021-04-09T10:48:59Z
dlang/dmd pull request #12408 "Merge stable into master" was merged into master:
- 6a36649a96f8f01e2e39a4224ff6bd58fc4e1667 by MoonlightSentinel:
Fix 21709 - Don't generate try-catch in betterC code for dtorfields
The code may never throw exceptions in betterC mode, so it cannot abort
the ctor with an uncaught exception.
https://github.com/dlang/dmd/pull/12408