Thread overview
[Issue 16960] implicit function return breaks chaining of exceptions
[Issue 16960] implicit function return breaks chaining of exceptions thrown in scope(exit)
Dec 14, 2016
Mathias LANG
Dec 14, 2016
Ali Cehreli
Dec 14, 2016
Ali Cehreli
Dec 15, 2016
Yuxuan Shui
Dec 17, 2022
Iain Buclaw
December 14, 2016
https://issues.dlang.org/show_bug.cgi?id=16960

Mathias LANG <pro.mathias.lang@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pro.mathias.lang@gmail.com

--- Comment #1 from Mathias LANG <pro.mathias.lang@gmail.com> ---
This is UB, according to http://dlang.org/spec/statement.html#ScopeGuardStatement

> A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a goto.

--
December 14, 2016
https://issues.dlang.org/show_bug.cgi?id=16960

--- Comment #2 from Ali Cehreli <acehreli@yahoo.com> ---
Thanks opened issue 16972 as an enhancement. Perhaps the compiler can warn about the obvious throw there.

--
December 14, 2016
https://issues.dlang.org/show_bug.cgi?id=16960

Ali Cehreli <acehreli@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|implicit function return    |implicit function return
                   |breaks chaining of          |breaks chaining of
                   |exceptions thrown in        |exceptions
                   |scope(exit)                 |

--- Comment #3 from Ali Cehreli <acehreli@yahoo.com> ---
The issue remains even if I don't throw from within a scope(exit) block.
Uncomment any 'return' inside foo() and the code works as expected:

import std.stdio;
import std.string;

struct ThrowsInDestructor {
    int n;

    ~this() {
        throw new Exception(format("thrown for %s", n));
    }
}

void foo(int n) {
    writeln("foo called with ", n);
    auto throws = ThrowsInDestructor(n);

    if (n > 0) {
        /* return */ foo(n - 1);
        // return;
    }
    // return;
}

void main() {
    // Never mind the unconventional range limits:
    // Throws one exception for each value in the range 0..n, including n.
    enum chainLength = 3;
    enum expectedLength = chainLength + 1;

    try {
        foo(chainLength);
    }
    catch (Exception original) {
        size_t count = 0;
        for (Throwable ex = original; ex; ex = ex.next) {
            writeln(ex.msg);
            ++count;
        }
        if (count != expectedLength) {
            writefln("Expected %s but walked %s links", expectedLength, count);
            writefln("\nTHE ORIGINAL EXCEPTION:\n\n%s", original);
        }
    }
}

--
December 15, 2016
https://issues.dlang.org/show_bug.cgi?id=16960

Yuxuan Shui <yshuiv7@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yshuiv7@gmail.com

--- Comment #4 from Yuxuan Shui <yshuiv7@gmail.com> ---
(In reply to Mathias LANG from comment #1)
> This is UB, according to http://dlang.org/spec/statement.html#ScopeGuardStatement
> 
> > A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a goto.

I don't think it make sense to forbid exiting scope block with a throw. Plus it totally works barring a few bugs not specific to it.

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=16960

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P3

--
December 13
https://issues.dlang.org/show_bug.cgi?id=16960

--- Comment #5 from dlangBugzillaToGithub <robert.schadek@posteo.de> ---
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/19213

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB

--