From: Ted Kremenek Date: Fri, 2 Mar 2012 21:16:22 +0000 (+0000) Subject: [analyzer diagnostics] flush locations *before* popping the current path when visitin... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ba86bc53bb280ba46a08459eda7d283d513b61f;p=clang [analyzer diagnostics] flush locations *before* popping the current path when visiting a CallEnter. Fixes git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151938 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index 66eb52604d..2b554332ae 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1229,17 +1229,14 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, PD.pushActivePath(&C->path); break; } - - // Note that is important that we update the LocationContext - // after looking at CallExits. CallExit basically adds an - // edge in the *caller*, so we don't want to update the LocationContext - // too soon. - PDB.LC = N->getLocationContext(); - + // Pop the call hierarchy if we are done walking the contents // of a function call. if (const CallEnter *CE = dyn_cast(&P)) { + 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 @@ -1247,16 +1244,20 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, // path terminated within a function call. We must then take the // current contents of the active path and place it within // a new PathDiagnosticCallPiece. - assert(!PD.getActivePath().empty()); - PathDiagnosticCallPiece *C = + PathDiagnosticCallPiece *C = dyn_cast(PD.getActivePath().front()); if (!C) C = PathDiagnosticCallPiece::construct(PD.getActivePath()); C->setCallee(*CE, SM); - EB.flushLocations(); EB.addContext(CE->getCallExpr()); break; } + + // Note that is important that we update the LocationContext + // after looking at CallExits. CallExit basically adds an + // edge in the *caller*, so we don't want to update the LocationContext + // too soon. + PDB.LC = N->getLocationContext(); // Block edges. if (const BlockEdge *BE = dyn_cast(&P)) { diff --git a/test/Analysis/inline-plist.c b/test/Analysis/inline-plist.c new file mode 100644 index 0000000000..c3420425ad --- /dev/null +++ b/test/Analysis/inline-plist.c @@ -0,0 +1,234 @@ +// RUN: %clang --analyze %s -Xclang -analyzer-inline-call -o %t +// RUN: FileCheck -input-file %t %s + +// +void mmm(int y) { + if (y != 0) + y++; +} + +int foo(int x, int y) { + mmm(y); + if (x != 0) + x++; + return 5/x; +} + +// CHECK: +// CHECK: +// CHECK: +// CHECK: files +// CHECK: +// CHECK: +// CHECK: diagnostics +// CHECK: +// CHECK: +// CHECK: path +// CHECK: +// CHECK: +// CHECK: kindcontrol +// CHECK: edges +// CHECK: +// CHECK: +// CHECK: start +// CHECK: +// CHECK: +// CHECK: line11 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line11 +// CHECK: col10 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: end +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: kindcontrol +// CHECK: edges +// CHECK: +// CHECK: +// CHECK: start +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: end +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col9 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col9 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: kindevent +// CHECK: location +// CHECK: +// CHECK: line12 +// CHECK: col9 +// CHECK: file0 +// CHECK: +// CHECK: ranges +// CHECK: +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col9 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col14 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: +// CHECK: extended_message +// CHECK: Assuming 'x' is equal to 0 +// CHECK: message +// CHECK: Assuming 'x' is equal to 0 +// CHECK: +// CHECK: +// CHECK: kindcontrol +// CHECK: edges +// CHECK: +// CHECK: +// CHECK: start +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col9 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line12 +// CHECK: col9 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: end +// CHECK: +// CHECK: +// CHECK: line14 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line14 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: kindcontrol +// CHECK: edges +// CHECK: +// CHECK: +// CHECK: start +// CHECK: +// CHECK: +// CHECK: line14 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line14 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: end +// CHECK: +// CHECK: +// CHECK: line14 +// CHECK: col12 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line14 +// CHECK: col12 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: kindevent +// CHECK: location +// CHECK: +// CHECK: line14 +// CHECK: col12 +// CHECK: file0 +// CHECK: +// CHECK: ranges +// CHECK: +// CHECK: +// CHECK: +// CHECK: line14 +// CHECK: col12 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line14 +// CHECK: col14 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: +// CHECK: extended_message +// CHECK: Division by zero +// CHECK: message +// CHECK: Division by zero +// CHECK: +// CHECK: +// CHECK: descriptionDivision by zero +// CHECK: categoryLogic error +// CHECK: typeDivision by zero +// CHECK: location +// CHECK: +// CHECK: line14 +// CHECK: col12 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +