Index: lld/ELF/ScriptParser.cpp =================================================================== --- lld/ELF/ScriptParser.cpp +++ lld/ELF/ScriptParser.cpp @@ -1233,6 +1233,9 @@ // Reads an "extern C++" directive, e.g., // "extern "C++" { ns::*; "f(int, double)"; };" +// +// The last semicolon is optional. E.g. this is OK: +//"extern "C++" { ns::*; "f(int, double)" };" std::vector ScriptParser::readVersionExtern() { StringRef Tok = next(); bool IsCXX = Tok == "\"C++\""; @@ -1245,6 +1248,8 @@ StringRef Tok = next(); bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); + if (consume("}")) + return Ret; expect(";"); } Index: lld/test/ELF/dynamic-list-extern.s =================================================================== --- lld/test/ELF/dynamic-list-extern.s +++ lld/test/ELF/dynamic-list-extern.s @@ -4,12 +4,8 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo '{ \ -# RUN: extern "C" { \ -# RUN: foo; \ -# RUN: }; \ -# RUN: extern "C++" { \ -# RUN: bar; \ -# RUN: }; \ -# RUN: };' > %t.list +# RUN: echo '{ extern "C" { foo; }; extern "C++" { bar; }; };' > %t.list +# RUN: ld.lld --dynamic-list %t.list %t.o -shared -o %t.so + +# RUN: echo '{ extern "C" { foo }; extern "C++" { bar }; };' > %t.list # RUN: ld.lld --dynamic-list %t.list %t.o -shared -o %t.so