From: David L. Jones Date: Fri, 15 Jun 2018 06:08:54 +0000 (+0000) Subject: [Format] Do not use a global static value for EOF within ScopedMacroState. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7653a4f768906f1c40620403bf7172e9bf5c9c21;p=clang [Format] Do not use a global static value for EOF within ScopedMacroState. ScopedMacroState injects its own EOF token under certain conditions, and the returned token may be modified in several different locations. If multiple reformat operations are started in different threads, then they will both see the same fake EOF token, and may both try to modify it. This is a data race. This bug was caught with tsan. Reviewers: klimek Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D47759 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334801 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index b257b2b74d..e1fa72e84b 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -83,6 +83,8 @@ public: : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken), PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource), Token(nullptr), PreviousToken(nullptr) { + FakeEOF.Tok.startToken(); + FakeEOF.Tok.setKind(tok::eof); TokenSource = this; Line.Level = 0; Line.InPPDirective = true; @@ -102,7 +104,7 @@ public: PreviousToken = Token; Token = PreviousTokenSource->getNextToken(); if (eof()) - return getFakeEOF(); + return &FakeEOF; return Token; } @@ -121,17 +123,7 @@ private: /*MinColumnToken=*/PreviousToken); } - FormatToken *getFakeEOF() { - static bool EOFInitialized = false; - static FormatToken FormatTok; - if (!EOFInitialized) { - FormatTok.Tok.startToken(); - FormatTok.Tok.setKind(tok::eof); - EOFInitialized = true; - } - return &FormatTok; - } - + FormatToken FakeEOF; UnwrappedLine &Line; FormatTokenSource *&TokenSource; FormatToken *&ResetToken;