diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -517,6 +517,8 @@ const MCSymbol &SA = A->getSymbol(); const MCSymbol &SB = B->getSymbol(); + const MCFragment *FragA = SA.getFragment(); + const MCFragment *FragB = SB.getFragment(); if (SA.isUndefined() || SB.isUndefined()) return; @@ -524,8 +526,9 @@ if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet)) return; - if (SA.getFragment() == SB.getFragment() && !SA.isVariable() && - !SA.isUnset() && !SB.isVariable() && !SB.isUnset()) { + if (FragA == FragB && !SA.isVariable() && !SA.isUnset() && !SB.isVariable() && + !SB.isUnset()) { + Addend += (SA.getOffset() - SB.getOffset()); // Pointers to Thumb symbols need to have their low-bit set to allow @@ -544,13 +547,39 @@ return; } - if (!Layout) + const MCSection &SecA = *FragA->getParent(); + const MCSection &SecB = *FragB->getParent(); + + if ((&SecA != &SecB) && !Addrs) return; - const MCSection &SecA = *SA.getFragment()->getParent(); - const MCSection &SecB = *SB.getFragment()->getParent(); + // Pointers to Thumb symbols need to have their low-bit set to allow + if ((&SecA != &SecB) && !Addrs) + return; - if ((&SecA != &SecB) && !Addrs) + if (SecB.getFragmentList().getNextNode(*FragB) == FragA && + dyn_cast(FragA) && dyn_cast(FragB)) { + Addend += + (SA.getOffset() + (cast(FragB))->getContents().size() - + SB.getOffset()); + + // Pointers to Thumb symbols need to have their low-bit set to allow + // for interworking. + if (Asm->isThumbFunc(&SA)) + Addend |= 1; + + // If symbol is labeled as micromips, we set low-bit to ensure + // correct offset in .gcc_except_table + if (Asm->getBackend().isMicroMips(&SA)) + Addend |= 1; + + // Clear the symbol expr pointers to indicate we have folded these + // operands. + A = B = nullptr; + return; + } + + if (!Layout) return; // Eagerly evaluate. diff --git a/llvm/test/MC/AsmParser/directive_if_with_dot_symbol.s b/llvm/test/MC/AsmParser/directive_if_with_dot_symbol.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AsmParser/directive_if_with_dot_symbol.s @@ -0,0 +1,6 @@ +@ RUN: llvm-mc -filetype=obj -triple armv7a-linux-gnueabihf %s -o - + +nop +.arch_extension sec +9997: nop ; .if . - 9997b == 2 ; nop ; .endif ; +// CHECK-MESSAGES: :[[@LINE-1]]:17: error: expected absolute expression