]> granicus.if.org Git - clang/commitdiff
[Format] Do not use a global static value for EOF within ScopedMacroState.
authorDavid L. Jones <dlj@google.com>
Fri, 15 Jun 2018 06:08:54 +0000 (06:08 +0000)
committerDavid L. Jones <dlj@google.com>
Fri, 15 Jun 2018 06:08:54 +0000 (06:08 +0000)
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

lib/Format/UnwrappedLineParser.cpp

index b257b2b74dd84f2455d248ca8c34e54ee68027f7..e1fa72e84bda5504318853b9bc5ce77e87415800 100644 (file)
@@ -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;