[Issue 14708] New: destructor for temporary not called during stack unwinding
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Wed Jun 17 08:49:07 PDT 2015
https://issues.dlang.org/show_bug.cgi?id=14708
Issue ID: 14708
Summary: destructor for temporary not called during stack
unwinding
Product: D
Version: D2
Hardware: x86_64
OS: Windows
Status: NEW
Keywords: wrong-code
Severity: major
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: k.hara.pg at gmail.com
Reduced test case:
extern(C) int printf(const char*, ...);
bool dtor = false;
struct S
{
int n;
void* get(void* p = null)
{
return null;
}
~this()
{
printf("dtor\n");
dtor = true;
}
}
S makeS(int n)
{
return S(n);
}
void foo(void* x)
{
throw new Exception("fail!");
}
void test(int len = 2)
{
foo(makeS(1).get());
// A temporary is allocated on stack for the
// return value from makeS(1).
// When foo throws exception, it's dtor should be called
// during unwinding stack, but it does not happen in Win64.
}
void main()
{
try
{
test();
} catch (Exception e) {}
assert(dtor); // fails!
}
I confirmed the issue on Win64, but I think it would happen in all platforms
excepting Win32.
Currently dmd handles the destructor calls for temporaries by using OPdctor and
OPddtor. It works correctly for Structural Exception Handling (SEH) in Win32.
On the other hand, Win64 and other Posix platforms generate exception handler
tables and use them from druntime. However dmd generates them only for the
explicit try-catch and try-finally statements, and doesn't recognize the
implied try-block between OPdctor and OPddtor elements.
By that, throwing exception from 'foo' skips dtor call for the temporary in
test().
It's an obstacle to my compiler fix for issue 14696.
https://github.com/D-Programming-Language/dmd/pull/4749
--
More information about the Digitalmars-d-bugs
mailing list