[cfe-commits] r123462 - in /cfe/trunk: include/clang/Basic/Diagnostic.h include/clang/Serialization/ASTBitCodes.h include/clang/Serialization/ASTReader.h include/clang/Serialization/ASTWriter.h lib/Basic/Diagnostic.cpp lib/Basic/DiagnosticIDs.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/PCH/pragma-diag-section.cpp test/PCH/rdar8852495.c

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Jan 14 12:54:07 PST 2011


Author: akirtzidis
Date: Fri Jan 14 14:54:07 2011
New Revision: 123462

URL: http://llvm.org/viewvc/llvm-project?rev=123462&view=rev
Log:
Properly propagate #pragma diagnostic mappings from PCH but not command-line warning flags.
Addresses rdar://8435969&8852495

Added:
    cfe/trunk/test/PCH/pragma-diag-section.cpp
    cfe/trunk/test/PCH/rdar8852495.c
Modified:
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/lib/Basic/Diagnostic.cpp
    cfe/trunk/lib/Basic/DiagnosticIDs.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=123462&r1=123461&r2=123462&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Fri Jan 14 14:54:07 2011
@@ -168,18 +168,26 @@
   /// clear, then the low bits are set to the default value, and should be
   /// mapped with -pedantic, -Werror, etc.
   ///
-  /// Contrary to DiagMappings, a new DiagState is created and kept around when
-  /// diagnostic pragmas modify the state so that we know what is the diagnostic
-  /// state at any given source location.
+  /// A new DiagState is created and kept around when diagnostic pragmas modify
+  /// the state so that we know what is the diagnostic state at any given
+  /// source location.
   class DiagState {
-    mutable llvm::DenseMap<unsigned, unsigned> DiagMap;
+    llvm::DenseMap<unsigned, unsigned> DiagMap;
 
   public:
+    typedef llvm::DenseMap<unsigned, unsigned>::const_iterator iterator;
+
     void setMapping(diag::kind Diag, unsigned Map) { DiagMap[Diag] = Map; }
 
     diag::Mapping getMapping(diag::kind Diag) const {
-      return (diag::Mapping)DiagMap[Diag];
+      iterator I = DiagMap.find(Diag);
+      if (I != DiagMap.end())
+        return (diag::Mapping)I->second;
+      return diag::Mapping();
     }
+
+    iterator begin() const { return DiagMap.begin(); }
+    iterator end() const { return DiagMap.end(); }
   };
 
   /// \brief Keeps and automatically disposes all DiagStates that we create.
@@ -525,8 +533,10 @@
   }
 
   void setDiagnosticMappingInternal(unsigned DiagId, unsigned Map,
-                                    DiagState *State, bool isUser) const {
+                                    DiagState *State,
+                                    bool isUser, bool isPragma) const {
     if (isUser) Map |= 8;  // Set the high bit for user mappings.
+    if (isPragma) Map |= 0x10;  // Set the bit for diagnostic pragma mappings.
     State->setMapping((diag::kind)DiagId, Map);
   }
 

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=123462&r1=123461&r2=123462&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Jan 14 14:54:07 2011
@@ -343,8 +343,8 @@
       /// sets.
       CXX_BASE_SPECIFIER_OFFSETS = 37,
 
-      /// \brief Record code for diagnostic mappings specified by the user.
-      DIAG_USER_MAPPINGS = 38
+      /// \brief Record code for #pragma diagnostic mappings.
+      DIAG_PRAGMA_MAPPINGS = 38
     };
 
     /// \brief Record types used within a source manager block.

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=123462&r1=123461&r2=123462&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Jan 14 14:54:07 2011
@@ -569,7 +569,7 @@
   //@}
 
   /// \brief Diagnostic IDs and their mappings that the user changed.
-  llvm::SmallVector<uint64_t, 8> UserDiagMappings;
+  llvm::SmallVector<uint64_t, 8> PragmaDiagMappings;
 
   /// \brief The original file name that was used to build the primary AST file,
   /// which may have been modified for relocatable-pch support.
@@ -851,7 +851,7 @@
   /// \brief Read the preprocessed entity at the given offset.
   virtual PreprocessedEntity *ReadPreprocessedEntity(uint64_t Offset);
 
-  void ReadUserDiagnosticMappings(Diagnostic &Diag);
+  void ReadPragmaDiagnosticMappings(Diagnostic &Diag);
 
   /// \brief Returns the number of source locations found in the chain.
   unsigned getTotalNumSLocs() const {

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=123462&r1=123461&r2=123462&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Fri Jan 14 14:54:07 2011
@@ -311,7 +311,7 @@
                                const Preprocessor &PP,
                                const char* isysroot);
   void WritePreprocessor(const Preprocessor &PP);
-  void WriteUserDiagnosticMappings(const Diagnostic &Diag);
+  void WritePragmaDiagnosticMappings(const Diagnostic &Diag);
   void WriteType(QualType T);
   uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
   uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);

Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=123462&r1=123461&r2=123462&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Fri Jan 14 14:54:07 2011
@@ -147,12 +147,13 @@
          "Cannot map errors into warnings!");
   assert(!DiagStatePoints.empty());
 
+  bool isPragma = L.isValid();
   FullSourceLoc Loc(L, *SourceMgr);
   FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
 
   // Common case; setting all the diagnostics of a group in one place.
   if (Loc.isInvalid() || Loc == LastStateChangePos) {
-    setDiagnosticMappingInternal(Diag, Map, GetCurDiagState(), true);
+    setDiagnosticMappingInternal(Diag, Map, GetCurDiagState(), true, isPragma);
     return;
   }
 
@@ -165,7 +166,7 @@
     // the new state became active.
     DiagStates.push_back(*GetCurDiagState());
     PushDiagStatePoint(&DiagStates.back(), Loc);
-    setDiagnosticMappingInternal(Diag, Map, GetCurDiagState(), true);
+    setDiagnosticMappingInternal(Diag, Map, GetCurDiagState(), true, isPragma);
     return;
   }
 
@@ -178,12 +179,12 @@
   // Update all diagnostic states that are active after the given location.
   for (DiagStatePointsTy::iterator
          I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) {
-    setDiagnosticMappingInternal(Diag, Map, I->State, true);
+    setDiagnosticMappingInternal(Diag, Map, I->State, true, isPragma);
   }
 
   // If the location corresponds to an existing point, just update its state.
   if (Pos->Loc == Loc) {
-    setDiagnosticMappingInternal(Diag, Map, Pos->State, true);
+    setDiagnosticMappingInternal(Diag, Map, Pos->State, true, isPragma);
     return;
   }
 
@@ -192,7 +193,7 @@
   Pos->Loc.isBeforeInTranslationUnitThan(Loc);
   DiagStates.push_back(*Pos->State);
   DiagState *NewState = &DiagStates.back();
-  setDiagnosticMappingInternal(Diag, Map, NewState, true);
+  setDiagnosticMappingInternal(Diag, Map, NewState, true, isPragma);
   DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState,
                                                FullSourceLoc(Loc, *SourceMgr)));
 }

Modified: cfe/trunk/lib/Basic/DiagnosticIDs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/DiagnosticIDs.cpp?rev=123462&r1=123461&r2=123462&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/DiagnosticIDs.cpp (original)
+++ cfe/trunk/lib/Basic/DiagnosticIDs.cpp Fri Jan 14 14:54:07 2011
@@ -317,7 +317,7 @@
                                                        State);
   if (MappingInfo == 0) {
     MappingInfo = GetDefaultDiagMapping(DiagID);
-    Diag.setDiagnosticMappingInternal(DiagID, MappingInfo, State, false);
+    Diag.setDiagnosticMappingInternal(DiagID, MappingInfo, State, false, false);
   }
 
   switch (MappingInfo & 7) {

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=123462&r1=123461&r2=123462&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Jan 14 14:54:07 2011
@@ -2128,15 +2128,15 @@
       break;
     }
 
-    case DIAG_USER_MAPPINGS:
+    case DIAG_PRAGMA_MAPPINGS:
       if (Record.size() % 2 != 0) {
         Error("invalid DIAG_USER_MAPPINGS block in AST file");
         return Failure;
       }
-      if (UserDiagMappings.empty())
-        UserDiagMappings.swap(Record);
+      if (PragmaDiagMappings.empty())
+        PragmaDiagMappings.swap(Record);
       else
-        UserDiagMappings.insert(UserDiagMappings.end(),
+        PragmaDiagMappings.insert(PragmaDiagMappings.end(),
                                 Record.begin(), Record.end());
       break;
     }
@@ -2482,7 +2482,7 @@
   if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED])
     Context->setInt128Installed();
 
-  ReadUserDiagnosticMappings(Context->getDiagnostics());
+  ReadPragmaDiagnosticMappings(Context->getDiagnostics());
 }
 
 /// \brief Retrieve the name of the original source file name
@@ -2670,13 +2670,23 @@
   return ReadMacroRecord(*F, Offset);
 }
 
-void ASTReader::ReadUserDiagnosticMappings(Diagnostic &Diag) {
+void ASTReader::ReadPragmaDiagnosticMappings(Diagnostic &Diag) {
   unsigned Idx = 0;
-  while (Idx < UserDiagMappings.size()) {
-    unsigned DiagID = UserDiagMappings[Idx++];
-    unsigned Map = UserDiagMappings[Idx++];
-    Diag.setDiagnosticMappingInternal(DiagID, Map, Diag.GetCurDiagState(),
-                                      /*isUser=*/true);
+  while (Idx < PragmaDiagMappings.size()) {
+    SourceLocation
+      Loc = SourceLocation::getFromRawEncoding(PragmaDiagMappings[Idx++]);
+    while (1) {
+      assert(Idx < PragmaDiagMappings.size() &&
+             "Invalid data, didn't find '-1' marking end of diag/map pairs");
+      if (Idx >= PragmaDiagMappings.size())
+        break; // Something is messed up but at least avoid infinite loop in
+               // release build.
+      unsigned DiagID = PragmaDiagMappings[Idx++];
+      if (DiagID == (unsigned)-1)
+        break; // no more diag/map pairs for this location.
+      diag::Mapping Map = (diag::Mapping)PragmaDiagMappings[Idx++];
+      Diag.setDiagnosticMapping(DiagID, Map, Loc);
+    }
   }
 }
 

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=123462&r1=123461&r2=123462&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Jan 14 14:54:07 2011
@@ -1507,18 +1507,30 @@
   }
 }
 
-void ASTWriter::WriteUserDiagnosticMappings(const Diagnostic &Diag) {
+void ASTWriter::WritePragmaDiagnosticMappings(const Diagnostic &Diag) {
   RecordData Record;
-  for (unsigned i = 0; i != diag::DIAG_UPPER_LIMIT; ++i) {
-    diag::Mapping Map = Diag.getDiagnosticMappingInfo(i,Diag.GetCurDiagState());
-    if (Map & 0x8) { // user mapping.
-      Record.push_back(i);
-      Record.push_back(Map & 0x7);
+  for (Diagnostic::DiagStatePointsTy::const_iterator
+         I = Diag.DiagStatePoints.begin(), E = Diag.DiagStatePoints.end();
+         I != E; ++I) {
+    const Diagnostic::DiagStatePoint &point = *I; 
+    if (point.Loc.isInvalid())
+      continue;
+
+    Record.push_back(point.Loc.getRawEncoding());
+    for (Diagnostic::DiagState::iterator
+           I = point.State->begin(), E = point.State->end(); I != E; ++I) {
+      unsigned diag = I->first, map = I->second;
+      if (map & 0x10) { // mapping from a diagnostic pragma.
+        Record.push_back(diag);
+        Record.push_back(map & 0x7);
+      }
     }
+    Record.push_back(-1); // mark the end of the diag/map pairs for this
+                          // location.
   }
 
   if (!Record.empty())
-    Stream.EmitRecord(DIAG_USER_MAPPINGS, Record);
+    Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record);
 }
 
 //===----------------------------------------------------------------------===//
@@ -2483,7 +2495,7 @@
   WriteIdentifierTable(PP);
 
   WriteTypeDeclOffsets();
-  WriteUserDiagnosticMappings(Context.getDiagnostics());
+  WritePragmaDiagnosticMappings(Context.getDiagnostics());
 
   // Write the C++ base-specifier set offsets.
   if (!CXXBaseSpecifiersOffsets.empty()) {
@@ -2719,7 +2731,7 @@
   WriteTypeDeclOffsets();
   // FIXME: For chained PCH only write the new mappings (we currently
   // write all of them again).
-  WriteUserDiagnosticMappings(Context.getDiagnostics());
+  WritePragmaDiagnosticMappings(Context.getDiagnostics());
 
   /// Build a record containing first declarations from a chained PCH and the
   /// most recent declarations in this AST that they point to.

Added: cfe/trunk/test/PCH/pragma-diag-section.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-diag-section.cpp?rev=123462&view=auto
==============================================================================
--- cfe/trunk/test/PCH/pragma-diag-section.cpp (added)
+++ cfe/trunk/test/PCH/pragma-diag-section.cpp Fri Jan 14 14:54:07 2011
@@ -0,0 +1,26 @@
+// Test this without pch.
+// RUN: %clang_cc1 %s -include %s -verify -fsyntax-only
+
+// Test with pch.
+// RUN: %clang_cc1 %s -emit-pch -o %t
+// RUN: %clang_cc1 %s -include-pch %t -verify -fsyntax-only
+
+#ifndef HEADER
+#define HEADER
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wtautological-compare"
+template <typename T>
+struct TS {
+    void m() { T b = b==b; }
+};
+#pragma clang diagnostic pop
+
+#else
+
+void f() {
+    TS<int> ts;
+    ts.m();
+}
+
+#endif

Added: cfe/trunk/test/PCH/rdar8852495.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/rdar8852495.c?rev=123462&view=auto
==============================================================================
--- cfe/trunk/test/PCH/rdar8852495.c (added)
+++ cfe/trunk/test/PCH/rdar8852495.c Fri Jan 14 14:54:07 2011
@@ -0,0 +1,25 @@
+// Test this without pch.
+// RUN: %clang_cc1 %s -include %s -verify -fsyntax-only -Wno-sign-compare -Wtautological-compare
+
+// Test with pch.
+// RUN: %clang_cc1 %s -emit-pch -o %t -Wsign-compare -Wtautological-compare
+// RUN: %clang_cc1 %s -include-pch %t -verify -fsyntax-only -Wno-sign-compare -Wtautological-compare
+
+// This tests that diagnostic mappings from PCH are propagated for #pragma
+// diagnostics but not for command-line flags.
+
+#ifndef HEADER
+#define HEADER
+
+#pragma clang diagnostic ignored "-Wtautological-compare"
+
+#else
+
+int f() {
+  int b = b==b;
+  unsigned x;
+  signed y;
+  return x == y;
+}
+
+#endif





More information about the cfe-commits mailing list