diff options
author | Fangrui Song <i@maskray.me> | 2022-06-25 13:48:52 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2022-06-25 13:48:52 -0700 |
commit | b0d6dd3905db145853c7c744ac92d49b00b1fa20 (patch) | |
tree | ab06cdf32a501d495ebff0d6c4ecf6715c2b2cdd | |
parent | d479b2e4db62f527e2bcdaa601f9d195cf4b7df0 (diff) | |
download | llvm-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.cpp | 5 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/operators.test | 6 |
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 |