www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 16960] New: implicit function return breaks chaining of

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

          Issue ID: 16960
           Summary: implicit function return breaks chaining of exceptions
                    thrown in scope(exit)
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: acehreli yahoo.com

The following function tries to throw an exception that has n+1 chains.
Uncomment any one of the 3 return statements inside foo() and you will get the
expected output:

foo called with 3
foo called with 2
foo called with 1
foo called with 0
thrown for 0
thrown for 1
thrown for 2
thrown for 3

However, when foo() returns implicitly without any return statement, there is
only one exception in the chain. main() detects this case by following the
.next links.

import std.stdio;
import std.string;

void foo(int n) {
    writeln("foo called with ", n);
    scope (exit) throw new Exception(format("thrown for %s", 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);
        }
    }
}

Ali

--
Dec 09 2016