]> granicus.if.org Git - clang/commitdiff
[analyzer] add a diagnostic event when entering a call via inlining, within the calle...
authorTed Kremenek <kremenek@apple.com>
Tue, 6 Mar 2012 01:25:01 +0000 (01:25 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 6 Mar 2012 01:25:01 +0000 (01:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152086 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
lib/StaticAnalyzer/Core/BugReporter.cpp
lib/StaticAnalyzer/Core/PathDiagnostic.cpp
lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
test/Analysis/inline-unique-reports.c

index 965ac3085e632f46650456f00283e53ffe5c9da6..245d5be93e658dcc132f61d63a6180e32bbc3944 100644 (file)
@@ -387,6 +387,7 @@ class PathDiagnosticCallPiece : public PathDiagnosticPiece {
   const Decl *Callee;
 public:
   PathDiagnosticLocation callEnter;
+  PathDiagnosticLocation callEnterWithin;
   PathDiagnosticLocation callReturn;  
   PathPieces path;
   
@@ -402,6 +403,8 @@ public:
   }
   
   IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallEnterEvent() const;
+  IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+    getCallEnterWithinCallerEvent() const;
   IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallExitEvent() const;
 
   virtual void flattenLocations() {
index 73e00e44167c06abd4f2d60c18c927f7af10d582..53fedaf2a12d1a7b542401814446ef2f8a55c1f9 100644 (file)
@@ -1233,10 +1233,18 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
       // Pop the call hierarchy if we are done walking the contents
       // of a function call.
       if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
+        // Add an edge to the start of the function.
+        const Decl *D = CE->getCalleeContext()->getDecl();
+        PathDiagnosticLocation pos =
+          PathDiagnosticLocation::createBegin(D, SM);
+        EB.addEdge(pos);
+        
+        // Flush all locations, and pop the active path.
         EB.flushLocations();
         PD.popActivePath();
         assert(!PD.getActivePath().empty());
         PDB.LC = N->getLocationContext();
+
         // The current active path should never be empty.  Either we
         // just added a bunch of stuff to the top-level path, or
         // we have a previous CallExit.  If the front of the active
index a082bba70dd5cfe155110a745f8805a5aa853a5b..01b40b43baf4141c4e2efbc7e9eb0c0eaddffa04 100644 (file)
@@ -527,7 +527,8 @@ void PathDiagnosticCallPiece::setCallee(const CallEnter &CE,
   const Decl *D = CE.getCalleeContext()->getDecl();
   Callee = D;
   callEnter = PathDiagnosticLocation(CE.getCallExpr(), SM,
-                                     CE.getLocationContext());  
+                                     CE.getLocationContext());
+  callEnterWithin = PathDiagnosticLocation::createBegin(D, SM);
 }
 
 IntrusiveRefCntPtr<PathDiagnosticEventPiece>
@@ -537,16 +538,32 @@ PathDiagnosticCallPiece::getCallEnterEvent() const {
   SmallString<256> buf;
   llvm::raw_svector_ostream Out(buf);
   if (isa<BlockDecl>(Callee))
-    Out << "Entering call to block";
+    Out << "Calling anonymous block";
   else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Callee))
-    Out << "Entering call to '" << *ND << "'";
+    Out << "Calling '" << *ND << "'";
   StringRef msg = Out.str();
   if (msg.empty())
     return 0;
   return new PathDiagnosticEventPiece(callEnter, msg);
 }
 
-IntrusiveRefCntPtr<PathDiagnosticEventPiece> 
+IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const {
+  if (!Callee)
+    return 0;
+  SmallString<256> buf;
+  llvm::raw_svector_ostream Out(buf);
+  if (isa<BlockDecl>(Callee))
+    Out << "Entered call to block";
+  else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Callee))
+    Out << "Entered call to '" << *ND << "'";
+  StringRef msg = Out.str();
+  if (msg.empty())
+    return 0;
+  return new PathDiagnosticEventPiece(callEnterWithin, msg);
+}
+
+IntrusiveRefCntPtr<PathDiagnosticEventPiece>
 PathDiagnosticCallPiece::getCallExitEvent() const {
   if (!Caller)
     return 0;
index 6f2a5ca9313419fd0f9b6841bae357a43e291da2..2c8270a2dd15798f045c5f33819d2a9fc9947e06 100644 (file)
@@ -255,15 +255,23 @@ static void ReportCall(raw_ostream &o,
   
   IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnter =
     P.getCallEnterEvent();  
+
   if (callEnter)
     ReportPiece(o, *callEnter, FM, SM, LangOpts, indent, true);
 
+  IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnterWithinCaller =
+    P.getCallEnterWithinCallerEvent();
+  
+  if (callEnterWithinCaller)
+    ReportPiece(o, *callEnterWithinCaller, FM, SM, LangOpts, indent, true);
+  
   for (PathPieces::const_iterator I = P.path.begin(), E = P.path.end();I!=E;++I)
     ReportPiece(o, **I, FM, SM, LangOpts, indent, true);
   
   IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
     P.getCallExitEvent();
-  if (callExit)  
+
+  if (callExit)
     ReportPiece(o, *callExit, FM, SM, LangOpts, indent, true);
 }
 
index f5e5b36be715916f2322b5e02c97c31e75f17caa..c99a303335347276f170afebbcb975f448bdb99f 100644 (file)
@@ -84,9 +84,56 @@ void test_bug_2() {
 // CHECK:        </array>
 // CHECK:      </array>
 // CHECK:      <key>extended_message</key>
-// CHECK:      <string>Entering call to &apos;bug&apos;</string>
+// CHECK:      <string>Calling &apos;bug&apos;</string>
 // CHECK:      <key>message</key>
-// CHECK: <string>Entering call to &apos;bug&apos;</string>
+// CHECK: <string>Calling &apos;bug&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>4</integer>
+// CHECK:       <key>col</key><integer>1</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Entered call to &apos;bug&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Entered call to &apos;bug&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>4</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>4</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
 // CHECK:      <key>kind</key><string>event</string>