r280360 - [analyzer] Add more FileIDs to PlistDiagnostic map to avoid assertion

Aleksei Sidorin via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 1 05:25:17 PDT 2016


Author: a.sidorin
Date: Thu Sep  1 07:25:16 2016
New Revision: 280360

URL: http://llvm.org/viewvc/llvm-project?rev=280360&view=rev
Log:
[analyzer] Add more FileIDs to PlistDiagnostic map to avoid assertion

Some FileIDs that may be used by PlistDiagnostics were not added while building
a list of pieces. This caused assertion violation in GetFID() function.
This patch adds some missing FileIDs to avoid the assertion. It also contains
small refactoring of PlistDiagnostics::FlushDiagnosticsImpl().

Patch by Aleksei Sidorin, Ilya Palachev.

Differential Revision: https://reviews.llvm.org/D22090

Added:
    cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def
    cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h
    cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=280360&r1=280359&r2=280360&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Thu Sep  1 07:25:16 2016
@@ -297,40 +297,42 @@ void PlistDiagnostics::FlushDiagnosticsI
     SM = &Diags.front()->path.front()->getLocation().getManager();
 
 
-  for (std::vector<const PathDiagnostic*>::iterator DI = Diags.begin(),
-       DE = Diags.end(); DI != DE; ++DI) {
+  auto AddPieceFID = [&FM, &Fids, SM](const PathDiagnosticPiece *Piece)->void {
+    AddFID(FM, Fids, *SM, Piece->getLocation().asLocation());
+    ArrayRef<SourceRange> Ranges = Piece->getRanges();
+    for (const SourceRange &Range : Ranges) {
+      AddFID(FM, Fids, *SM, Range.getBegin());
+      AddFID(FM, Fids, *SM, Range.getEnd());
+    }
+  };
 
-    const PathDiagnostic *D = *DI;
+  for (const PathDiagnostic *D : Diags) {
 
     SmallVector<const PathPieces *, 5> WorkList;
     WorkList.push_back(&D->path);
 
     while (!WorkList.empty()) {
-      const PathPieces &path = *WorkList.pop_back_val();
-
-      for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E;
-           ++I) {
-        const PathDiagnosticPiece *piece = I->get();
-        AddFID(FM, Fids, *SM, piece->getLocation().asLocation());
-        ArrayRef<SourceRange> Ranges = piece->getRanges();
-        for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
-                                             E = Ranges.end(); I != E; ++I) {
-          AddFID(FM, Fids, *SM, I->getBegin());
-          AddFID(FM, Fids, *SM, I->getEnd());
-        }
+      const PathPieces &Path = *WorkList.pop_back_val();
 
-        if (const PathDiagnosticCallPiece *call =
-            dyn_cast<PathDiagnosticCallPiece>(piece)) {
-          IntrusiveRefCntPtr<PathDiagnosticEventPiece>
-            callEnterWithin = call->getCallEnterWithinCallerEvent();
-          if (callEnterWithin)
-            AddFID(FM, Fids, *SM, callEnterWithin->getLocation().asLocation());
+      for (const auto &Iter : Path) {
+        const PathDiagnosticPiece *Piece = Iter.get();
+        AddPieceFID(Piece);
+
+        if (const PathDiagnosticCallPiece *Call =
+            dyn_cast<PathDiagnosticCallPiece>(Piece)) {
+          if (IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+              CallEnterWithin = Call->getCallEnterWithinCallerEvent())
+            AddPieceFID(CallEnterWithin.get());
+
+          if (IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+              CallEnterEvent = Call->getCallEnterEvent())
+            AddPieceFID(CallEnterEvent.get());
 
-          WorkList.push_back(&call->path);
+          WorkList.push_back(&Call->path);
         }
-        else if (const PathDiagnosticMacroPiece *macro =
-                 dyn_cast<PathDiagnosticMacroPiece>(piece)) {
-          WorkList.push_back(&macro->subPieces);
+        else if (const PathDiagnosticMacroPiece *Macro =
+                 dyn_cast<PathDiagnosticMacroPiece>(Piece)) {
+          WorkList.push_back(&Macro->subPieces);
         }
       }
     }

Added: cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def?rev=280360&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def (added)
+++ cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def Thu Sep  1 07:25:16 2016
@@ -0,0 +1 @@
+PLIST_DEF_MACRO

Added: cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h?rev=280360&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h (added)
+++ cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h Thu Sep  1 07:25:16 2016
@@ -0,0 +1,9 @@
+void clang_analyzer_warnIfReached();
+
+class PlistCheckMacro {
+public:
+  PlistCheckMacro () { }
+  void run() {
+    clang_analyzer_warnIfReached();
+  }
+};

Added: cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp?rev=280360&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp (added)
+++ cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp Thu Sep  1 07:25:16 2016
@@ -0,0 +1,140 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -analyzer-output=plist-multi-file %s -o %t.plist
+// RUN: FileCheck --input-file=%t.plist %s
+
+#include "Inputs/include/plist-diagnostics-include-check-macro.h"
+
+void foo() {
+  PlistCheckMacro()
+#define PLIST_DEF_MACRO .run();
+#include "Inputs/include/plist-diagnostics-include-check-macro.def"
+}
+
+// CHECK:   <key>diagnostics</key>
+// CHECK-NEXT:  <array>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>7</integer>
+// CHECK-NEXT:       <key>col</key><integer>3</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>7</integer>
+// CHECK-NEXT:          <key>col</key><integer>3</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1</integer>
+// CHECK-NEXT:          <key>col</key><integer>15</integer>
+// CHECK-NEXT:          <key>file</key><integer>2</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Calling 'PlistCheckMacro::run'</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Calling 'PlistCheckMacro::run'</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>6</integer>
+// CHECK-NEXT:       <key>col</key><integer>3</integer>
+// CHECK-NEXT:       <key>file</key><integer>1</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>depth</key><integer>1</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Entered call from 'foo'</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Entered call from 'foo'</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>6</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>1</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>6</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>1</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>7</integer>
+// CHECK-NEXT:            <key>col</key><integer>5</integer>
+// CHECK-NEXT:            <key>file</key><integer>1</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>7</integer>
+// CHECK-NEXT:            <key>col</key><integer>32</integer>
+// CHECK-NEXT:            <key>file</key><integer>1</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>7</integer>
+// CHECK-NEXT:       <key>col</key><integer>5</integer>
+// CHECK-NEXT:       <key>file</key><integer>1</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>7</integer>
+// CHECK-NEXT:          <key>col</key><integer>5</integer>
+// CHECK-NEXT:          <key>file</key><integer>1</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>7</integer>
+// CHECK-NEXT:          <key>col</key><integer>34</integer>
+// CHECK-NEXT:          <key>file</key><integer>1</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>1</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>REACHABLE</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>REACHABLE</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>REACHABLE</string>
+// CHECK-NEXT:    <key>category</key><string>debug</string>
+// CHECK-NEXT:    <key>type</key><string>Checking analyzer assumptions</string>
+// CHECK-NEXT:    <key>check_name</key><string>debug.ExprInspection</string>
+// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>93b4eab05b21c892c8e31723e5af3f59</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>C++ method</string>
+// CHECK-NEXT:   <key>issue_context</key><string>run</string>
+// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>7</integer>
+// CHECK-NEXT:    <key>col</key><integer>5</integer>
+// CHECK-NEXT:    <key>file</key><integer>1</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:  </array>




More information about the cfe-commits mailing list