dlj created this revision. dlj added a reviewer: djasper. dlj added a project: clang. Herald added a subscriber: klimek.
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. Repository: rC Clang https://reviews.llvm.org/D47759 Files: lib/Format/UnwrappedLineParser.cpp Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -83,6 +83,8 @@ : 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 @@ PreviousToken = Token; Token = PreviousTokenSource->getNextToken(); if (eof()) - return getFakeEOF(); + return &FakeEOF; return Token; } @@ -121,17 +123,7 @@ /*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;
Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -83,6 +83,8 @@ : 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 @@ PreviousToken = Token; Token = PreviousTokenSource->getNextToken(); if (eof()) - return getFakeEOF(); + return &FakeEOF; return Token; } @@ -121,17 +123,7 @@ /*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;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits