mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Fix Bugzilla Issue 24371 - String array concatenation does not respect operator precedence
Rethink lowering logic to account for parentheses and operator associativity. Signed-off-by: Teodor Dutu <teodor.dutu@gmail.com>
This commit is contained in:
parent
a61180db7b
commit
2423b93798
2 changed files with 39 additions and 21 deletions
|
@ -12196,30 +12196,33 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return result;
|
||||
}
|
||||
|
||||
void handleCatArgument(Expressions *arguments, Expression e, Type catType)
|
||||
void handleCatArgument(Expressions *arguments, Expression e, Type catType, bool isRightArg)
|
||||
{
|
||||
auto tb = e.type.toBasetype();
|
||||
|
||||
if (!e.parens || (catType.equals(tb) && (tb.ty == Tarray || tb.ty == Tsarray)))
|
||||
if (auto ce = e.isCatExp())
|
||||
if ((isRightArg && e.parens) || (!isRightArg && !tb.equals(catType)))
|
||||
{
|
||||
arguments.push(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto ce = e.isCatExp())
|
||||
{
|
||||
Expression lowering = ce.lowering;
|
||||
|
||||
/* Skip `file`, `line`, and `funcname` if the hook of the parent
|
||||
* `CatExp` is `_d_arraycatnTXTrace`.
|
||||
*/
|
||||
if (auto callExp = isRuntimeHook(lowering, hook))
|
||||
{
|
||||
Expression lowering = ce.lowering;
|
||||
|
||||
/* Skip `file`, `line`, and `funcname` if the hook of the parent
|
||||
* `CatExp` is `_d_arraycatnTXTrace`.
|
||||
*/
|
||||
if (auto callExp = isRuntimeHook(lowering, hook))
|
||||
{
|
||||
if (hook == Id._d_arraycatnTX)
|
||||
arguments.pushSlice((*callExp.arguments)[]);
|
||||
else
|
||||
arguments.pushSlice((*callExp.arguments)[3 .. $]);
|
||||
}
|
||||
|
||||
return;
|
||||
if (hook == Id._d_arraycatnTX)
|
||||
arguments.pushSlice((*callExp.arguments)[]);
|
||||
else
|
||||
arguments.pushSlice((*callExp.arguments)[3 .. $]);
|
||||
}
|
||||
|
||||
arguments.push(e);
|
||||
}
|
||||
else
|
||||
arguments.push(e);
|
||||
}
|
||||
|
||||
auto arguments = new Expressions();
|
||||
|
@ -12232,8 +12235,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
arguments.push(new StringExp(exp.loc, funcname.toDString()));
|
||||
}
|
||||
|
||||
handleCatArgument(arguments, exp.e1, exp.type.toBasetype());
|
||||
handleCatArgument(arguments, exp.e2, exp.type.toBasetype());
|
||||
handleCatArgument(arguments, exp.e1, exp.type.toBasetype(), false);
|
||||
handleCatArgument(arguments, exp.e2, exp.type.toBasetype(), true);
|
||||
|
||||
Expression id = new IdentifierExp(exp.loc, Id.empty);
|
||||
id = new DotIdExp(exp.loc, id, Id.object);
|
||||
|
|
15
compiler/test/runnable/test24371.d
Normal file
15
compiler/test/runnable/test24371.d
Normal file
|
@ -0,0 +1,15 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=24371
|
||||
|
||||
void main()
|
||||
{
|
||||
assert("b" ~ "c" == "bc");
|
||||
assert(["a"] ~ "b" == ["a", "b"]);
|
||||
assert(["a"] ~ ("b" ~ "c") == ["a", "bc"]);
|
||||
|
||||
auto strArr = ["a"];
|
||||
assert(strArr ~ ("b" ~ "c") == ["a", "bc"]);
|
||||
auto str = "c";
|
||||
assert(["a"] ~ ("b" ~ str) == ["a", "bc"]);
|
||||
|
||||
assert(strArr ~ ("b" ~ str) == ["a", "bc"]);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue