summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gdc.test/runnable/test17559.d
blob: a759f1564c6cabc1d90f478dd34f1064c8b6bd39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// REQUIRED_ARGS: -g
// REQUIRED_ARGS(linux freebsd dragonflybsd): -L-export-dynamic
// PERMUTE_ARGS:
// DISABLED: osx

import core.stdc.stdio;

void main()
{
    fun(1);
    fun(2);
    fun(3);
#line 30
    fun(4);

    foo(1, 10);
    foo(2, 10);
    foo(3, 10);
#line 40
    foo(4, 10);
}

void fun(int n, int defParam = 10)
{
    try
    {
        if (n == 4)
            throw new Exception("fun");
    }
    catch(Exception e)
    {
        string s = e.toString();
        printf("%.*s\n", cast(int)s.length, s.ptr);
        int line = lineInMain(e.toString());
        assert(line >= 30 && line <= 32); // return address might be next statement
    }
}

void foo(int n, int m)
{
    try
    {
        if (n == 4)
            throw new Exception("foo");
    }
    catch(Exception e)
    {
        string s = e.toString();
        printf("%.*s\n", cast(int)s.length, s.ptr);
        int line = lineInMain(e.toString());
        assert(line >= 40 && line <= 41); // return address might be next statement
    }
}

int lineInMain(string msg)
{
    // find line number of _Dmain in stack trace
    // on linux:   file.d:line _Dmain [addr]
    // on windows: addr in _Dmain at file.d(line)
    int line = 0;
    bool mainFound = false;
    for (size_t pos = 0; pos + 6 < msg.length; pos++)
    {
        if (msg[pos] == '\n')
        {
            line = 0;
            mainFound = false;
        }
        else if ((msg[pos] == ':' || msg[pos] == '(') && line == 0)
        {
            for (pos++; pos < msg.length && msg[pos] >= '0' && msg[pos] <= '9'; pos++)
                line = line * 10 + msg[pos] - '0';
            if (line > 0 && mainFound)
                return line;
        }
        else if (msg[pos .. pos + 6] == "_Dmain" || msg[pos .. pos + 6] == "D main")
        {
            mainFound = true;
            if (line > 0 && mainFound)
                return line;
        }
    }
    return 0;
}