From b19d37acc8d2e06fdbe907e3b8250a4ffdc46b04 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Fri, 26 Oct 2018 00:30:25 -0700 Subject: [PATCH] fix Issue 18457 - betterC - struct destructor is always called at function return --- src/dmd/func.d | 11 ++++++++++- test/runnable/betterc.d | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/dmd/func.d b/src/dmd/func.d index 0e97e582aaf8..7625777a3668 100644 --- a/src/dmd/func.d +++ b/src/dmd/func.d @@ -98,8 +98,17 @@ public: { DtorExpStatement des; if (fd.nrvo_can && s.finalbody && (des = s.finalbody.isDtorExpStatement()) !is null && - fd.nrvo_var == des.var && global.params.useExceptions && ClassDeclaration.throwable) + fd.nrvo_var == des.var) { + if (!(global.params.useExceptions && ClassDeclaration.throwable)) + { + /* Don't need to call destructor at all, since it is nrvo + */ + replaceCurrent(s._body); + s._body.accept(this); + return; + } + /* Normally local variable dtors are called regardless exceptions. * But for nrvo_var, its dtor should be called only when exception is thrown. * diff --git a/test/runnable/betterc.d b/test/runnable/betterc.d index d4655a24d32d..b4b5a725b711 100644 --- a/test/runnable/betterc.d +++ b/test/runnable/betterc.d @@ -26,6 +26,7 @@ extern (C) void main() test(1); test18472(); testRuntimeLowerings(); + test18457(); } /*******************************************/ @@ -156,3 +157,31 @@ void testRuntimeLowerings() break; } } + +/**********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=18457 + +__gshared int dtor; + +struct S18457 +{ + int a = 3; + ~this() { a = 0; ++dtor; } +} + +S18457 myFunction() +{ + S18457 s = S18457(); + return s; +} + +void test18457() +{ + { + S18457 s = myFunction(); + assert(s.a == 3); + assert(dtor == 0); + } + assert(dtor == 1); +} +