Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -783,16 +783,22 @@ return make(Name, E, getCurrentLocation()); } +namespace { +// Our lexer is context-aware. This sets the in-expression bit so that +// it applies different tokenization rules. +struct RAIIInExpr { + bool Old; + bool *Ptr; + RAIIInExpr(bool *Ptr, bool Val) : Old(*Ptr), Ptr(Ptr) { *Ptr = Val; } + ~RAIIInExpr() { *Ptr = Old; } +}; +} // namespace + // This is an operator-precedence parser to parse a linker // script expression. Expr ScriptParser::readExpr() { - // Our lexer is context-aware. Set the in-expression bit so that - // they apply different tokenization rules. - bool Orig = InExpr; - InExpr = true; - Expr E = readExpr1(readPrimary(), 0); - InExpr = Orig; - return E; + RAIIInExpr R(&InExpr, true); + return readExpr1(readPrimary(), 0); } static Expr combine(StringRef Op, Expr L, Expr R) { @@ -923,6 +929,7 @@ StringRef ScriptParser::readParenLiteral() { expect("("); + RAIIInExpr R(&InExpr, false); StringRef Tok = next(); expect(")"); return Tok; Index: test/ELF/linkerscript/parse-section-in-addr.s =================================================================== --- /dev/null +++ test/ELF/linkerscript/parse-section-in-addr.s @@ -0,0 +1,10 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o + +# RUN: echo "SECTIONS { \ +# RUN: .foo-bar : AT(ADDR(.foo-bar)) { *(.text) } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t.so --script %t.script %t.o -shared +# RUN: llvm-readelf -S %t.so | FileCheck %s + +# CHECK: .foo-bar