]> granicus.if.org Git - clang/commitdiff
[PCH] Fix reading from PCH of diagnostic pragmas.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 9 Nov 2011 01:24:17 +0000 (01:24 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 9 Nov 2011 01:24:17 +0000 (01:24 +0000)
In certain cases ASTReader would call the normal DiagnosticsEngine API to initialize
the state of diagnostic pragmas but DiagnosticsEngine would try to compare source locations
leading to crash because the main FileID was not yet initialized.

Yet another case of the ASTReader trying to use the normal APIs and inadvertently breaking
invariants. Fix this by having the ASTReader set up the internal state directly.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144153 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Diagnostic.h
lib/Basic/Diagnostic.cpp
lib/Serialization/ASTReader.cpp
test/Index/Inputs/pragma_disable_warning.h [new file with mode: 0644]
test/Index/pragma-diag-reparse.c

index 7dde271c38fc8dd42e4aee78544991ca579870e9..78af10ce68cab0e502a4713c9bb59ef883d521ba 100644 (file)
@@ -624,6 +624,21 @@ private:
   /// to insert, remove, or modify at a particular position.
   FixItHint FixItHints[MaxFixItHints];
 
+  DiagnosticMappingInfo makeMappingInfo(diag::Mapping Map, SourceLocation L) {
+    bool isPragma = L.isValid();
+    DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make(
+      Map, /*IsUser=*/true, isPragma);
+
+    // If this is a pragma mapping, then set the diagnostic mapping flags so
+    // that we override command line options.
+    if (isPragma) {
+      MappingInfo.setNoWarningAsError(true);
+      MappingInfo.setNoErrorAsFatal(true);
+    }
+
+    return MappingInfo;
+  }
+
   /// ProcessDiag - This is the method used to report a diagnostic that is
   /// finally fully formed.
   ///
index e5f390196d80e067b76ad2c4292bbe4af0cb7c9c..7ea296233a24510549a392efd32908809c46749f 100644 (file)
@@ -169,18 +169,9 @@ void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
          "Cannot map errors into warnings!");
   assert(!DiagStatePoints.empty());
 
-  bool isPragma = L.isValid();
   FullSourceLoc Loc(L, *SourceMgr);
   FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
-  DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make(
-    Map, /*IsUser=*/true, isPragma);
-
-  // If this is a pragma mapping, then set the diagnostic mapping flags so that
-  // we override command line options.
-  if (isPragma) {
-    MappingInfo.setNoWarningAsError(true);
-    MappingInfo.setNoErrorAsFatal(true);
-  }
+  DiagnosticMappingInfo MappingInfo = makeMappingInfo(Map, L);
 
   // Common case; setting all the diagnostics of a group in one place.
   if (Loc.isInvalid() || Loc == LastStateChangePos) {
index cbf6cd0c5cc7b59b3beb6b9b63016252d45f44e9..3aeaf19cd55dba561efaf4d279442d2c66e7398b 100644 (file)
@@ -3109,6 +3109,10 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
     unsigned Idx = 0;
     while (Idx < F.PragmaDiagMappings.size()) {
       SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
+      Diag.DiagStates.push_back(*Diag.GetCurDiagState());
+      Diag.DiagStatePoints.push_back(
+          DiagnosticsEngine::DiagStatePoint(&Diag.DiagStates.back(),
+                                            FullSourceLoc(Loc, SourceMgr)));
       while (1) {
         assert(Idx < F.PragmaDiagMappings.size() &&
                "Invalid data, didn't find '-1' marking end of diag/map pairs");
@@ -3121,8 +3125,8 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
           break; // no more diag/map pairs for this location.
         }
         diag::Mapping Map = (diag::Mapping)F.PragmaDiagMappings[Idx++];
-        // The user bit gets set by WritePragmaDiagnosticMappings.
-        Diag.setDiagnosticMapping(DiagID, Map, Loc);
+        DiagnosticMappingInfo MappingInfo = Diag.makeMappingInfo(Map, Loc);
+        Diag.GetCurDiagState()->setMappingInfo(DiagID, MappingInfo);
       }
     }
   }
diff --git a/test/Index/Inputs/pragma_disable_warning.h b/test/Index/Inputs/pragma_disable_warning.h
new file mode 100644 (file)
index 0000000..b40e9e7
--- /dev/null
@@ -0,0 +1 @@
+#pragma clang diagnostic ignored "-Wunused-parameter"
index 1dccd59523f12c25bd08210bd4a75e8454e4e089..71d0618d709285937705c00532875f4daee2fdb1 100644 (file)
@@ -1,4 +1,5 @@
 #pragma clang diagnostic ignored "-Wtautological-compare"
+#include "pragma_disable_warning.h"
 
 int main (int argc, const char * argv[])
 {
@@ -13,6 +14,7 @@ int main (int argc, const char * argv[])
 void foo() { int b=0; while (b==b); }
 
 // RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_FAILONERROR=1 c-index-test -test-load-source-reparse 5 local \
+// RUN: -I%S/Inputs \
 // RUN:   %s -Wall -Werror | FileCheck %s
 
-// CHECK: pragma-diag-reparse.c:7:7: VarDecl=x:7:7 (Definition) Extent=[7:3 - 7:10]
+// CHECK: pragma-diag-reparse.c:8:7: VarDecl=x:8:7 (Definition) Extent=[8:3 - 8:10]