r334801 - [Format] Do not use a global static value for EOF within ScopedMacroState.

David L. Jones via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 14 23:08:54 PDT 2018


Author: dlj
Date: Thu Jun 14 23:08:54 2018
New Revision: 334801

URL: http://llvm.org/viewvc/llvm-project?rev=334801&view=rev
Log:
[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

Modified:
    cfe/trunk/lib/Format/UnwrappedLineParser.cpp

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=334801&r1=334800&r2=334801&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Thu Jun 14 23:08:54 2018
@@ -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;




More information about the cfe-commits mailing list