From bc3c423fd7804b63a008bdd344420a1edb68f626 Mon Sep 17 00:00:00 2001 From: Abul Hossain Khan <140191921+abulgit@users.noreply.github.com> Date: Fri, 18 Apr 2025 04:54:30 +0530 Subject: [PATCH] Fix error location for binary operations to point at operator instead of first operand (#21253) --- compiler/src/dmd/parse.d | 27 +++++++------------ compiler/test/fail_compilation/fail196.d | 2 +- .../fail_compilation/fail_pretty_errors.d | 2 +- compiler/test/fail_compilation/fix21166.d | 13 +++++++++ 4 files changed, 25 insertions(+), 19 deletions(-) create mode 100644 compiler/test/fail_compilation/fix21166.d diff --git a/compiler/src/dmd/parse.d b/compiler/src/dmd/parse.d index c2d9a20944..574a0f230d 100644 --- a/compiler/src/dmd/parse.d +++ b/compiler/src/dmd/parse.d @@ -9068,11 +9068,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Expression parseMulExp() { - const loc = token.loc; auto e = parseUnaryExp(); while (1) { + const loc = token.loc; switch (token.value) { case TOK.mul: @@ -9103,11 +9103,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Expression parseAddExp() { - const loc = token.loc; auto e = parseMulExp(); while (1) { + const loc = token.loc; switch (token.value) { case TOK.add: @@ -9138,11 +9138,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Expression parseShiftExp() { - const loc = token.loc; auto e = parseAddExp(); while (1) { + const loc = token.loc; switch (token.value) { case TOK.leftShift: @@ -9173,10 +9173,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Expression parseCmpExp() { - const loc = token.loc; - auto e = parseShiftExp(); EXP op = EXP.reserved; + const loc = token.loc; switch (token.value) { @@ -9238,28 +9237,26 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Expression parseAndExp() { - Loc loc = token.loc; auto e = parseCmpExp(); while (token.value == TOK.and) { checkParens(TOK.and, e); + const loc = token.loc; nextToken(); auto e2 = parseCmpExp(); checkParens(TOK.and, e2); e = new AST.AndExp(loc, e, e2); - loc = token.loc; } return e; } private AST.Expression parseXorExp() { - const loc = token.loc; - auto e = parseAndExp(); while (token.value == TOK.xor) { checkParens(TOK.xor, e); + const loc = token.loc; nextToken(); auto e2 = parseAndExp(); checkParens(TOK.xor, e2); @@ -9270,12 +9267,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Expression parseOrExp() { - const loc = token.loc; - auto e = parseXorExp(); while (token.value == TOK.or) { checkParens(TOK.or, e); + const loc = token.loc; nextToken(); auto e2 = parseXorExp(); checkParens(TOK.or, e2); @@ -9286,11 +9282,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Expression parseAndAndExp() { - const loc = token.loc; - auto e = parseOrExp(); while (token.value == TOK.andAnd) { + const loc = token.loc; nextToken(); auto e2 = parseOrExp(); e = new AST.LogicalExp(loc, EXP.andAnd, e, e2); @@ -9300,11 +9295,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Expression parseOrOrExp() { - const loc = token.loc; - auto e = parseAndAndExp(); while (token.value == TOK.orOr) { + const loc = token.loc; nextToken(); auto e2 = parseAndAndExp(); e = new AST.LogicalExp(loc, EXP.orOr, e, e2); @@ -9314,11 +9308,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Expression parseCondExp() { - const loc = token.loc; - auto e = parseOrOrExp(); if (token.value == TOK.question) { + const loc = token.loc; nextToken(); auto e1 = parseExpression(); check(TOK.colon); diff --git a/compiler/test/fail_compilation/fail196.d b/compiler/test/fail_compilation/fail196.d index 78c596390b..a5d4499f3f 100644 --- a/compiler/test/fail_compilation/fail196.d +++ b/compiler/test/fail_compilation/fail196.d @@ -21,7 +21,7 @@ fail_compilation/fail196.d(44): expression: `";\n assert(s == "` fail_compilation/fail196.d(45): Error: found `}` when expecting `;` following expression fail_compilation/fail196.d(45): expression: `xxx` fail_compilation/fail196.d(47): Error: found `<` when expecting `;` following expression -fail_compilation/fail196.d(45): expression: `");\n\n s = q" < foo` +fail_compilation/fail196.d(47): expression: `");\n\n s = q" < foo` fail_compilation/fail196.d(48): Error: found `foo` when expecting `;` following expression fail_compilation/fail196.d(47): expression: `xxx >> ";\n assert(s == "` fail_compilation/fail196.d(48): Error: found `<` instead of statement diff --git a/compiler/test/fail_compilation/fail_pretty_errors.d b/compiler/test/fail_compilation/fail_pretty_errors.d index 79242b163e..ebd36a7cc1 100644 --- a/compiler/test/fail_compilation/fail_pretty_errors.d +++ b/compiler/test/fail_compilation/fail_pretty_errors.d @@ -16,7 +16,7 @@ fail_compilation/fail_pretty_errors.d(44): Error: mixin `fail_pretty_errors.test ^ fail_compilation/fail_pretty_errors.d(50): Error: invalid array operation `"" + ""` (possible missing []) auto x = ""+""; - ^ + ^ fail_compilation/fail_pretty_errors.d(50): did you mean to concatenate (`"" ~ ""`) instead ? fail_compilation/fail_pretty_errors.d(53): Error: cannot implicitly convert expression `1111` of type `int` to `byte` byte ɑ = 1111; diff --git a/compiler/test/fail_compilation/fix21166.d b/compiler/test/fail_compilation/fix21166.d new file mode 100644 index 0000000000..24dbf8b467 --- /dev/null +++ b/compiler/test/fail_compilation/fix21166.d @@ -0,0 +1,13 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/fix21166.d(12): Error: invalid array operation `"foo" + "bar"` (possible missing []) +fail_compilation/fix21166.d(12): did you mean to concatenate (`"foo" ~ "bar"`) instead ? +--- +*/ + +// Test case for https://github.com/dlang/dmd/issues/21166 +auto r = + "foo" + + + "bar";