From b349b6d0de9d375bda2db418fb16fabe7fc2f031 Mon Sep 17 00:00:00 2001 From: Teodor Dutu Date: Sat, 19 Aug 2023 08:24:13 +0800 Subject: [PATCH] Fix Issue 24078 - Fold constants on array concatenation only for strings Without this limitation, the code could incorrectly concatenate `["c"] ~ "a" ~ "b"` as `["c"] ~ "ab"`, which was incorrect. Signed-off-by: Teodor Dutu --- compiler/src/dmd/optimize.d | 28 +++++++++++++++++----------- compiler/test/runnable/test24078.d | 6 ++++++ 2 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 compiler/test/runnable/test24078.d diff --git a/compiler/src/dmd/optimize.d b/compiler/src/dmd/optimize.d index f98e7c76bc..37563826a2 100644 --- a/compiler/src/dmd/optimize.d +++ b/compiler/src/dmd/optimize.d @@ -1280,19 +1280,25 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) //printf("CatExp::optimize(%d) %s\n", result, e.toChars()); if (binOptimize(e, result)) return; - if (auto ce1 = e.e1.isCatExp()) - { - // https://issues.dlang.org/show_bug.cgi?id=12798 - // optimize ((expr ~ str1) ~ str2) - scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2); - cex.type = e.type; - Expression ex = Expression_optimize(cex, result, false); - if (ex != cex) + + if (e.type == Type.tstring) + if (auto ce1 = e.e1.isCatExp()) { - e.e1 = ce1.e1; - e.e2 = ex; + // https://issues.dlang.org/show_bug.cgi?id=12798 + // optimize ((expr ~ str1) ~ str2) + // https://issues.dlang.org/show_bug.cgi?id=24078 + // This optimization is only valid if `expr` is a string. + // Otherwise it leads to: + // `["c"] ~ "a" ~ "b"` becoming `["c"] ~ "ab"` + scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2); + cex.type = e.type; + Expression ex = Expression_optimize(cex, result, false); + if (ex != cex) + { + e.e1 = ce1.e1; + e.e2 = ex; + } } - } // optimize "str"[] -> "str" if (auto se1 = e.e1.isSliceExp()) { diff --git a/compiler/test/runnable/test24078.d b/compiler/test/runnable/test24078.d new file mode 100644 index 0000000000..99d74400cf --- /dev/null +++ b/compiler/test/runnable/test24078.d @@ -0,0 +1,6 @@ +//https://issues.dlang.org/show_bug.cgi?id=24078 + +void main() +{ + assert(["c"] ~ "a" ~ "b" == ["c", "a", "b"]); +}