From 97618f5fe59e5e4338b2b39896a9f4c3b6df9706 Mon Sep 17 00:00:00 2001 From: Rainer Date: Fri, 29 May 2026 08:24:40 +0200 Subject: [PATCH] Fix #23182 - Duplicate __aaget declaration for simple expression with associative array don't evaluate arrExp twice in `arrExp.length++` if non-trivial --- compiler/src/dmd/expressionsem.d | 13 ++++++++++++- compiler/test/runnable/testaa3.d | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 8ccfbebf210f..0ccd016b9c2d 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -11825,7 +11825,18 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor /* If e1 is not trivial, take a reference to it */ Expression de = null; - if (exp.e1.op != EXP.variable && exp.e1.op != EXP.arrayLength) + if (auto ale = exp.e1.isArrayLengthExp()) + { + // don't evaluate arrExp twice in `arrExp.length++` if non-trivial + if (ale.e1.op != EXP.variable) + { + // ref v = e1; + auto v = copyToTemp(STC.ref_, "__postref", ale.e1); + de = new DeclarationExp(ale.loc, v); + ale.e1 = new VarExp(ale.e1.loc, v); + } + } + else if (exp.e1.op != EXP.variable) { // ref v = e1; auto v = copyToTemp(STC.ref_, "__postref", exp.e1); diff --git a/compiler/test/runnable/testaa3.d b/compiler/test/runnable/testaa3.d index 99acfed11460..8c6f88a4b1f9 100644 --- a/compiler/test/runnable/testaa3.d +++ b/compiler/test/runnable/testaa3.d @@ -498,6 +498,26 @@ void test23065() A!B a; a == a; } + +// https://github.com/dlang/dmd/issues/23182 +void test23182() +{ + int[][string] aarr; + aarr["key"] = []; + aarr["key"].length++; + + int calls = 0; + int[] a; + ref int[] arr() + { + calls++; + return a; + } + arr().length++; + assert(a.length == 1); + assert(calls == 1); +} + /***************************************************/ // https://github.com/dlang/dmd/issues/22567 @@ -567,4 +587,5 @@ void main() test22567(); test22556(); test19829(); + test23182(); }