diff --git a/compiler/src/dmd/semantic3.d b/compiler/src/dmd/semantic3.d index 24bdd449d5e..210a75fbb3b 100644 --- a/compiler/src/dmd/semantic3.d +++ b/compiler/src/dmd/semantic3.d @@ -1310,6 +1310,26 @@ private extern(C++) final class Semantic3Visitor : Visitor finishScopeParamInference(funcdecl, f); + { + // Promote array literals like `auto x = [y];` to stack if possible + import dmd.foreachvar; + void dgVar(VarDeclaration v) + { + if (v.maybeScope && v._init) + if (auto ei = v._init.isExpInitializer()) + if (auto ce = ei.exp.isConstructExp()) + if (auto ale = ce.e2.isArrayLiteralExp()) + ale.onstack = true; + } + + void dgExp(Expression e) + { + foreachVar(e, &dgVar); + } + + foreachExpAndVar(funcdecl.fbody, &dgExp, &dgVar); + } + // reset deco to apply inference result to mangled name if (f != funcdecl.type) f.deco = null; diff --git a/compiler/test/fail_compilation/test21477.d b/compiler/test/fail_compilation/test21477.d index c9c7c7fcd50..24321e2ff3f 100644 --- a/compiler/test/fail_compilation/test21477.d +++ b/compiler/test/fail_compilation/test21477.d @@ -1,16 +1,17 @@ /* REQUIRED_ARGS: -betterC TEST_OUTPUT: --- -fail_compilation/test21477.d(103): Error: expression `[1]` uses the GC and cannot be used with switch `-betterC` +fail_compilation/test21477.d(14): Error: expression `[1]` uses the GC and cannot be used with switch `-betterC` --- */ // https://issues.dlang.org/show_bug.cgi?id=21477 -#line 100 +int[] global; int test() { int[] foo = [1]; + global = foo; return 0; } diff --git a/compiler/test/runnable/betterc.d b/compiler/test/runnable/betterc.d index 0fc32c75a1f..11c2030c850 100644 --- a/compiler/test/runnable/betterc.d +++ b/compiler/test/runnable/betterc.d @@ -43,6 +43,7 @@ extern (C) void main() testRuntimeLowerings(); test18457(); test20737(); + testScopeInferenceArrayLiteral(); } /*******************************************/ @@ -221,3 +222,15 @@ void test22427() char[] p; auto a = cast(int[])p; } + +/*******************************************/ +// Test that local variable can be inferred scope, moving +// array literal from GC to stack, allowing usage in betterC + +int testScopeInferenceArrayLiteral() +{ + auto x = [10, 20, 30] ~ [40]; + x[0] = 50; + assert(x[0] + x[1] == 70); + return x[0]; +}