aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2022-06-25 13:48:52 -0700
committerFangrui Song <i@maskray.me>2022-06-25 13:48:52 -0700
commitb0d6dd3905db145853c7c744ac92d49b00b1fa20 (patch)
treeab06cdf32a501d495ebff0d6c4ecf6715c2b2cdd
parentd479b2e4db62f527e2bcdaa601f9d195cf4b7df0 (diff)
downloadllvm-b0d6dd3905db145853c7c744ac92d49b00b1fa20.zip
llvm-b0d6dd3905db145853c7c744ac92d49b00b1fa20.tar.gz
llvm-b0d6dd3905db145853c7c744ac92d49b00b1fa20.tar.bz2
[ELF] Fix precedence of ? when there are 2 or more operators on the left hand side
For 1 != 1 <= 1 ? 1 : 2, the current code incorrectly considers that ? has a higher precedence than != (minPrec). Also, add a test for right associativity.
-rw-r--r--lld/ELF/ScriptParser.cpp5
-rw-r--r--lld/test/ELF/linkerscript/operators.test6
2 files changed, 6 insertions, 5 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 4df4462..bd9807c 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -645,6 +645,7 @@ static int precedence(StringRef op) {
.Case("|", 4)
.Case("&&", 3)
.Case("||", 2)
+ .Case("?", 1)
.Default(-1);
}
@@ -1128,11 +1129,11 @@ Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
Expr ScriptParser::readExpr1(Expr lhs, int minPrec) {
while (!atEOF() && !errorCount()) {
// Read an operator and an expression.
- if (consume("?"))
- return readTernary(lhs);
StringRef op1 = peek();
if (precedence(op1) < minPrec)
break;
+ if (consume("?"))
+ return readTernary(lhs);
skip();
Expr rhs = readPrimary();
diff --git a/lld/test/ELF/linkerscript/operators.test b/lld/test/ELF/linkerscript/operators.test
index b096df5..cbccd45 100644
--- a/lld/test/ELF/linkerscript/operators.test
+++ b/lld/test/ELF/linkerscript/operators.test
@@ -13,14 +13,14 @@ SECTIONS {
nospace = 1+2*6/3;
braces = 1 + (2 + 3) * 4;
and = 0xbb & 0xee;
- ternary1 = 1 ? 1 : 2;
+ ternary1 = 1 ? 2 : 3 ? 4 : 5;
ternary2 = 0 ? 1 : 2;
less = 1 < 0 ? 1 : 2;
lesseq = 1 <= 1 ? 1 : 2;
greater = 0 > 1 ? 1 : 2;
greatereq = 1 >= 1 ? 1 : 2;
eq = 1 == 1 ? 1 : 2;
- neq = (1 != 1 <= 1) ? 1 : 2;
+ neq = 1 != 1 <= 1 ? 1 : 2;
plusassign = 1;
plusassign += 2;
unary = -1 + 3;
@@ -64,7 +64,7 @@ SECTIONS {
# CHECK-NEXT: 00000000000005 A nospace
# CHECK-NEXT: 00000000000015 A braces
# CHECK-NEXT: 000000000000aa A and
-# CHECK-NEXT: 00000000000001 A ternary1
+# CHECK-NEXT: 00000000000002 A ternary1
# CHECK-NEXT: 00000000000002 A ternary2
# CHECK-NEXT: 00000000000002 A less
# CHECK-NEXT: 00000000000001 A lesseq