]>
Commit | Line | Data |
---|---|---|
844fa2de IB |
1 | // https://bugzilla.gdcproject.org/show_bug.cgi?id=36 |
2 | // { dg-additional-sources "imports/gdc36.d" } | |
3 | // { dg-options "-I $srcdir/gdc.dg" } | |
72ddef62 | 4 | // { dg-do run } |
844fa2de IB |
5 | // { dg-skip-if "needs gcc/config.d" { ! d_runtime } } |
6 | ||
7 | module gdc36; | |
8 | ||
9 | import imports.gdc36; | |
10 | ||
11 | /** | |
12 | * Here getChar is a function in a template where template.isnested == false | |
13 | * but getChar still is a nested function and needs to get a static chain | |
14 | * containing test36a. | |
15 | */ | |
16 | void test36a()(char val) | |
17 | { | |
18 | void error() | |
19 | { | |
20 | } | |
21 | ||
22 | void getChar()() | |
23 | { | |
24 | error(); | |
25 | } | |
26 | ||
27 | void parseString() | |
28 | { | |
29 | getChar(); | |
30 | } | |
31 | } | |
32 | ||
33 | /** | |
34 | * Similar as test36a, but a little more complicated: | |
35 | * Here getChar is nested in a struct template which is nested in a function. | |
36 | * getChar's static chain still needs to contain test36b. | |
37 | */ | |
38 | void test36b()(char val) | |
39 | { | |
40 | void error() | |
41 | { | |
42 | } | |
43 | ||
44 | struct S(T) | |
45 | { | |
46 | void getChar() | |
47 | { | |
48 | error(); | |
49 | } | |
50 | } | |
51 | ||
52 | ||
53 | void parseString() | |
54 | { | |
55 | S!(int)().getChar(); | |
56 | } | |
57 | } | |
58 | ||
59 | /** | |
60 | * If g had accessed a, the frontend would have generated a closure. | |
61 | * | |
62 | * As we do not access it, there's no closure. We have to be careful | |
63 | * not to set a static chain for g containing test36c_1 though, | |
64 | * as g can be called from outside (here from test1c). In the end | |
65 | * we have to treat this as if everything in test36c_1 was declared | |
66 | * at module scope. | |
67 | */ | |
68 | auto test36c_1() | |
69 | { | |
70 | int a; | |
71 | void c() {} | |
72 | class Result | |
73 | { | |
74 | int b; | |
75 | void g() { c(); /*a = 42;*/ } | |
76 | } | |
77 | ||
78 | return new Result(); | |
79 | } | |
80 | ||
81 | void test36c() | |
82 | { | |
83 | test36c_1().g(); | |
84 | } | |
85 | ||
86 | /** | |
87 | * empty is a (private) function which is nested in lightPostprocess. | |
88 | * At the same time it's a template instance, so it has to be declared as | |
89 | * weak or otherwise one-only. imports/gdc36.d creates another instance | |
90 | * of Regex!char to verify that. | |
91 | */ | |
92 | struct Parser(R) | |
93 | { | |
94 | @property program() | |
95 | { | |
96 | return Regex!char(); | |
97 | } | |
98 | } | |
99 | ||
100 | struct Regex(Char) | |
101 | { | |
102 | @trusted lightPostprocess() | |
103 | { | |
104 | struct FixedStack(T) | |
105 | { | |
106 | @property empty() { return false; } | |
107 | } | |
108 | auto counterRange = FixedStack!uint(); | |
109 | } | |
110 | } | |
111 | ||
112 | void test36d() | |
113 | { | |
114 | auto parser = Parser!(char[])(); | |
115 | imports.gdc36.test36d_1; | |
116 | } | |
117 | ||
118 | void main() | |
119 | { | |
120 | test36a('n'); | |
121 | test36b('n'); | |
122 | test36c(); | |
123 | test36d(); | |
124 | } | |
125 |