Bug 20897 – AST contains try/finally statements in -betterC mode

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2020-06-05T13:55:38Z
Last change time
2020-06-28T15:57:30Z
Assigned to
No Owner
Creator
Roxanne

Comments

Comment #0 by assemblyislaw — 2020-06-05T13:55:38Z
Both DMD 2.091.1 and LDC 10.0.0 when compiling the following code ``` import core.stdc.stdlib; import core.volatile; struct List(T) { T* a; this(T b) { a = cast(T*)malloc(b); } ~this() { free(a); } } uint ioAPICRead(size_t ioAPIC, uint reg) { auto list = List!uint(reg); uint* base = cast(uint*)(cast(size_t)list.a); volatileStore(base, reg); return volatileLoad(base + 4); } ``` Generate a pair of `try`/`catch` in the AST that will generate references to `_d_eh_personality`: ``` import object; import core.stdc.stdlib; import core.volatile; struct List(T) { T* a; this(T b) { a = cast(T*)malloc(b); } ~this() { free(a); } } uint ioAPICRead(ulong ioAPIC, uint reg) { List!uint list = list = 0 , list.this(reg); try { uint* base = cast(uint*)cast(ulong)list.a; volatileStore(base, reg); return volatileLoad(base + 16L); } finally list.~this(); } List!uint { struct List { uint* a; nothrow @nogc @system this(uint b) { this.a = cast(uint*)malloc(cast(ulong)b); return this; } ~this() { free(cast(void*)this.a); } alias __xdtor = ~this() { free(cast(void*)this.a); } ; nothrow @nogc ref @system List!uint opAssign(List!uint p) return { (List!uint __swap2 = void;) , __swap2 = this , (this = p , __swap2.~this()); return this; } } } RTInfo!(List!uint) { enum immutable(ulong)* RTInfo = & RTInfoImpl; } NoPointersBitmapPayload!1LU { enum ulong[1] NoPointersBitmapPayload = 0LU; } RTInfoImpl!([8LU, 1LU]) { immutable immutable(ulong[2]) RTInfoImpl = [8LU, 1LU]; } ``` It can also be checked in https://run.dlang.io/is/aewRQ1 .
Comment #1 by assemblyislaw — 2020-06-05T13:56:38Z
I meant LDC 1.21.0 with LLVM 10.0.0, not LDC 10.0.0, sorry for the inconvenience
Comment #2 by kinke — 2020-06-05T16:41:51Z
Unfortunately, you'll need another test case - some try/finally in the -vcg-ast output aren't actual TryFinallyStatements (compiler internals...). The testcase should fail to link (at least with LDC) when adding an `extern(C) int main() { return 0; }` and compiling with `-betterC`.
Comment #3 by kinke — 2020-06-28T12:25:41Z
A similar example (from https://github.com/ldc-developers/ldc/issues/3479), this time for scope(exit): void create(uint a, uint b, string c) {} extern(C) int main() { int a = 5; scope(exit) a = 6; create(0, 1, "2"); return 0; } Currently lowered to: extern(C) int main() { int a = 5; try { create(0u, 1u, "2"); return 0; } finally a = 6; } Instead of having each compiler backend translate TryFinallyStatements in betterC mode to 2 consecutive block statements, the frontend should do this.
Comment #4 by kinke — 2020-06-28T15:57:30Z
Sorry, my bad - I've overlooked the return-statement and similar control-flow stuff requiring to represent a cleanup via a TryFinallyStatement for -betterC too. Will be fixed in LDC's glue layer instead.