From c57da0cf5945cfb45eed06f1fd820435cda3ee3a Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Tue, 31 Dec 2024 01:00:03 -0800 Subject: [PATCH] fix #20621 Comparing addresses of rvalue reference parameters not correct (#20622) --- compiler/src/dmd/backend/inliner.d | 15 ++++++++++++++- compiler/src/dmd/constfold.d | 13 ++++++++++++- compiler/src/dmd/e2ir.d | 10 ++++++++++ compiler/test/runnable/rvalue1.d | 2 ++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/compiler/src/dmd/backend/inliner.d b/compiler/src/dmd/backend/inliner.d index cf24050e4b3b..e4bac8fa56f6 100644 --- a/compiler/src/dmd/backend/inliner.d +++ b/compiler/src/dmd/backend/inliner.d @@ -516,7 +516,20 @@ private elem* initializeParamsWithArgs(elem* eargs, SYMIDX sistart, SYMIDX siend { if (log) printf("detected slice with %s\n", s.Sident.ptr); auto s2 = nextSymbol(si); - if (!s2) { symbol_print(*s); elem_print(e); assert(0); } + if (!s2) + { + for (size_t m = args.length; m; --m) + { + elem* ex = args[m - 1]; + printf("arg[%d]\n", cast(int) m); + elem_print(ex); + } + + printf("function: %s\n", funcsym_p.Sident.ptr); + printf("szs: %d sze: %d\n", cast(int)szs, cast(int)sze); + printf("detected slice with %s\n", s.Sident.ptr); + symbol_print(*s); elem_print(e); assert(0); + } assert(szs == type_size(s2.Stype)); const ty = s.Stype.Tty; diff --git a/compiler/src/dmd/constfold.d b/compiler/src/dmd/constfold.d index 1578ef770a09..9d5aa96416b5 100644 --- a/compiler/src/dmd/constfold.d +++ b/compiler/src/dmd/constfold.d @@ -806,6 +806,7 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e UnionExp Identity(EXP op, const ref Loc loc, Type type, Expression e1, Expression e2) { + //printf("Identity %s %s\n", e1.toChars(), e2.toChars()); UnionExp ue = void; int cmp; if (e1.op == EXP.null_) @@ -820,7 +821,17 @@ UnionExp Identity(EXP op, const ref Loc loc, Type type, Expression e1, Expressio { SymOffExp es1 = e1.isSymOffExp(); SymOffExp es2 = e2.isSymOffExp(); - cmp = (es1.var == es2.var && es1.offset == es2.offset); + cmp = es1.offset == es2.offset; + if (cmp) + { + cmp = es1.var == es2.var; + if (!cmp && (es1.var.isParameter() || es2.var.isParameter())) + { + // because of ref's, they may still be the same, we cannot tell + cantExp(ue); + return ue; + } + } } else { diff --git a/compiler/src/dmd/e2ir.d b/compiler/src/dmd/e2ir.d index e120df28d3a7..e2a2ad09a3ad 100644 --- a/compiler/src/dmd/e2ir.d +++ b/compiler/src/dmd/e2ir.d @@ -113,6 +113,11 @@ bool ISX64REF(Declaration var) || (var.storage_class & STC.lazy_) || (var.type.isTypeStruct() && var.type.isTypeStruct().sym.hasCopyConstruction()); } + else if (target.os & Target.OS.Windows) + { + auto ts = var.type.isTypeStruct(); + return !(var.storage_class & STC.lazy_) && ts && ts.sym.hasMoveCtor && ts.sym.hasCopyCtor; + } else if (target.os & Target.OS.Posix) { return !(var.storage_class & STC.lazy_) && var.type.isTypeStruct() && !var.type.isTypeStruct().sym.isPOD(); @@ -131,6 +136,11 @@ bool ISX64REF(ref IRState irs, Expression exp) return exp.type.size(Loc.initial) > registerSize || (exp.type.isTypeStruct() && exp.type.isTypeStruct().sym.hasCopyConstruction()); } + else if (irs.target.os & Target.OS.Windows) + { + auto ts = exp.type.isTypeStruct(); + return ts && ts.sym.hasMoveCtor && ts.sym.hasCopyCtor; + } else if (irs.target.os & Target.OS.Posix) { return exp.type.isTypeStruct() && !exp.type.isTypeStruct().sym.isPOD(); diff --git a/compiler/test/runnable/rvalue1.d b/compiler/test/runnable/rvalue1.d index 07ea4270b881..f8134f718a9f 100644 --- a/compiler/test/runnable/rvalue1.d +++ b/compiler/test/runnable/rvalue1.d @@ -55,6 +55,8 @@ struct S4 { void* p; + this(ref S4) { } + this(S4 s) { assert(&s is &x); // confirm the rvalue reference