digitalmars.D.bugs - [Issue 14708] New: destructor for temporary not called during stack
- via Digitalmars-d-bugs (68/68) Jun 17 2015 https://issues.dlang.org/show_bug.cgi?id=14708
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 puremagic.com Reporter: k.hara.pg 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 --
Jun 17 2015