| // https://bugzilla.gdcproject.org/show_bug.cgi?id=36 |
| // { dg-additional-sources "imports/gdc36.d" } |
| // { dg-options "-I $srcdir/gdc.dg" } |
| // { dg-do run } |
| // { dg-skip-if "needs gcc/config.d" { ! d_runtime } } |
| |
| module gdc36; |
| |
| import imports.gdc36; |
| |
| /** |
| * Here getChar is a function in a template where template.isnested == false |
| * but getChar still is a nested function and needs to get a static chain |
| * containing test36a. |
| */ |
| void test36a()(char val) |
| { |
| void error() |
| { |
| } |
| |
| void getChar()() |
| { |
| error(); |
| } |
| |
| void parseString() |
| { |
| getChar(); |
| } |
| } |
| |
| /** |
| * Similar as test36a, but a little more complicated: |
| * Here getChar is nested in a struct template which is nested in a function. |
| * getChar's static chain still needs to contain test36b. |
| */ |
| void test36b()(char val) |
| { |
| void error() |
| { |
| } |
| |
| struct S(T) |
| { |
| void getChar() |
| { |
| error(); |
| } |
| } |
| |
| |
| void parseString() |
| { |
| S!(int)().getChar(); |
| } |
| } |
| |
| /** |
| * If g had accessed a, the frontend would have generated a closure. |
| * |
| * As we do not access it, there's no closure. We have to be careful |
| * not to set a static chain for g containing test36c_1 though, |
| * as g can be called from outside (here from test1c). In the end |
| * we have to treat this as if everything in test36c_1 was declared |
| * at module scope. |
| */ |
| auto test36c_1() |
| { |
| int a; |
| void c() {} |
| class Result |
| { |
| int b; |
| void g() { c(); /*a = 42;*/ } |
| } |
| |
| return new Result(); |
| } |
| |
| void test36c() |
| { |
| test36c_1().g(); |
| } |
| |
| /** |
| * empty is a (private) function which is nested in lightPostprocess. |
| * At the same time it's a template instance, so it has to be declared as |
| * weak or otherwise one-only. imports/gdc36.d creates another instance |
| * of Regex!char to verify that. |
| */ |
| struct Parser(R) |
| { |
| @property program() |
| { |
| return Regex!char(); |
| } |
| } |
| |
| struct Regex(Char) |
| { |
| @trusted lightPostprocess() |
| { |
| struct FixedStack(T) |
| { |
| @property empty() { return false; } |
| } |
| auto counterRange = FixedStack!uint(); |
| } |
| } |
| |
| void test36d() |
| { |
| auto parser = Parser!(char[])(); |
| imports.gdc36.test36d_1; |
| } |
| |
| void main() |
| { |
| test36a('n'); |
| test36b('n'); |
| test36c(); |
| test36d(); |
| } |
| |