1 // https://bugzilla.gdcproject.org/show_bug.cgi?id=36
2 // { dg-additional-sources "imports/gdc36.d" }
3 // { dg-options "-I $srcdir/gdc.dg" }
4 // { dg-do run }
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  */
test36a()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  */
test36b()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  */
test36c_1()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 
test36c()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  */
Parser(R)92 struct Parser(R)
93 {
94     @property program()
95     {
96         return Regex!char();
97     }
98 }
99 
Regex(Char)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 
test36d()112 void test36d()
113 {
114     auto parser = Parser!(char[])();
115     imports.gdc36.test36d_1;
116 }
117 
main()118 void main()
119 {
120   test36a('n');
121   test36b('n');
122   test36c();
123   test36d();
124 }
125 
126