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.