r361982 - [analyzer] print() JSONify: Checker messages implementation
Csaba Dabis via cfe-commits
cfe-commits at lists.llvm.org
Wed May 29 09:02:33 PDT 2019
Author: charusso
Date: Wed May 29 09:02:33 2019
New Revision: 361982
URL: http://llvm.org/viewvc/llvm-project?rev=361982&view=rev
Log:
[analyzer] print() JSONify: Checker messages implementation
Summary: -
Reviewers: NoQ, xazax.hun, ravikandhadai, baloghadamsoftware, Szelethus
Reviewed By: NoQ
Subscribers: szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy,
dkrupp
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62086
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/test/Analysis/expr-inspection.c
cfe/trunk/test/Analysis/use-after-move.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=361982&r1=361981&r2=361982&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Wed May 29 09:02:33 2019
@@ -406,16 +406,21 @@ public:
///
/// Unlike most other callbacks, any checker can simply implement the virtual
/// method CheckerBase::printState if it has custom data to print.
- /// \param Out The output stream
+ ///
+ /// \param Out The output stream
/// \param State The state being printed
- /// \param NL The preferred representation of a newline.
- /// \param Sep The preferred separator between different kinds of data.
- void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep);
+ /// \param NL The preferred representation of a newline.
+ /// \param Sep The preferred separator between different messages.
+ /// \param Space The preferred space between the left side and the message.
+ /// \param IsDot Whether the message will be printed in 'dot' format.
+ void runCheckersForPrintStateJson(raw_ostream &Out, ProgramStateRef State,
+ const char *NL = "\n",
+ unsigned int Space = 0,
+ bool IsDot = false) const;
-//===----------------------------------------------------------------------===//
-// Internal registration functions for AST traversing.
-//===----------------------------------------------------------------------===//
+ //===----------------------------------------------------------------------===//
+ // Internal registration functions for AST traversing.
+ //===----------------------------------------------------------------------===//
// Functions used by the registration mechanism, checkers should not touch
// these directly.
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=361982&r1=361981&r2=361982&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Wed May 29 09:02:33 2019
@@ -14,6 +14,7 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/JsonSupport.h"
#include "clang/Basic/LLVM.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
@@ -698,11 +699,73 @@ void CheckerManager::runCheckersOnEndOfT
EndOfTranslationUnitChecker(TU, mgr, BR);
}
-void CheckerManager::runCheckersForPrintState(raw_ostream &Out,
- ProgramStateRef State,
- const char *NL, const char *Sep) {
- for (const auto &CheckerTag : CheckerTags)
- CheckerTag.second->printState(Out, State, NL, Sep);
+void CheckerManager::runCheckersForPrintStateJson(raw_ostream &Out,
+ ProgramStateRef State,
+ const char *NL,
+ unsigned int Space,
+ bool IsDot) const {
+ Indent(Out, Space, IsDot) << "\"checker_messages\": ";
+
+ // Create a temporary stream to see whether we have any message.
+ SmallString<1024> TempBuf;
+ llvm::raw_svector_ostream TempOut(TempBuf);
+ unsigned int InnerSpace = Space + 2;
+
+ // Create the new-line in JSON with enough space.
+ SmallString<128> NewLine;
+ llvm::raw_svector_ostream NLOut(NewLine);
+ NLOut << "\", " << NL; // Inject the ending and a new line
+ Indent(NLOut, InnerSpace, IsDot) << "\""; // then begin the next message.
+
+ ++Space;
+ bool HasMessage = false;
+
+ // Store the last CheckerTag.
+ const void *LastCT = nullptr;
+ for (const auto &CT : CheckerTags) {
+ // See whether the current checker has a message.
+ CT.second->printState(TempOut, State, /*NL=*/NewLine.c_str(), /*Sep=*/"");
+
+ if (TempBuf.empty())
+ continue;
+
+ if (!HasMessage) {
+ Out << '[' << NL;
+ HasMessage = true;
+ }
+
+ LastCT = &CT;
+ TempBuf.clear();
+ }
+
+ for (const auto &CT : CheckerTags) {
+ // See whether the current checker has a message.
+ CT.second->printState(TempOut, State, /*NL=*/NewLine.c_str(), /*Sep=*/"");
+
+ if (TempBuf.empty())
+ continue;
+
+ Indent(Out, Space, IsDot)
+ << "{ \"checker\": \"" << CT.second->getCheckName().getName()
+ << "\", \"messages\": [" << NL;
+ Indent(Out, InnerSpace, IsDot)
+ << '\"' << TempBuf.str().trim() << '\"' << NL;
+ Indent(Out, Space, IsDot) << "]}";
+
+ if (&CT != LastCT)
+ Out << ',';
+ Out << NL;
+
+ TempBuf.clear();
+ }
+
+ // It is the last element of the 'program_state' so do not add a comma.
+ if (HasMessage)
+ Indent(Out, --Space, IsDot) << "]";
+ else
+ Out << "null";
+
+ Out << NL;
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=361982&r1=361981&r2=361982&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed May 29 09:02:33 2019
@@ -633,7 +633,8 @@ void ExprEngine::printJson(raw_ostream &
Out << "null," << NL;
}
- getCheckerManager().runCheckersForPrintState(Out, State, NL, "");
+ getCheckerManager().runCheckersForPrintStateJson(Out, State, NL, Space,
+ IsDot);
}
void ExprEngine::processEndWorklist() {
Modified: cfe/trunk/test/Analysis/expr-inspection.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/expr-inspection.c?rev=361982&r1=361981&r2=361982&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/expr-inspection.c (original)
+++ cfe/trunk/test/Analysis/expr-inspection.c Wed May 29 09:02:33 2019
@@ -38,3 +38,5 @@ void foo(int x) {
// CHECK-NEXT: ],
// CHECK-NEXT: "dynamic_types": null,
// CHECK-NEXT: "constructing_objects": null,
+// CHECK-NEXT: "checker_messages": null
+
Modified: cfe/trunk/test/Analysis/use-after-move.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/use-after-move.cpp?rev=361982&r1=361981&r2=361982&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/use-after-move.cpp (original)
+++ cfe/trunk/test/Analysis/use-after-move.cpp Wed May 29 09:02:33 2019
@@ -44,9 +44,18 @@
// CHECK-MOVE-INVALID-VALUE-SAME: "KnownsOnly", "KnownsAndLocals" or "All"
// CHECK-MOVE-INVALID-VALUE-SAME: string value
+// Tests checker-messages printing.
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
+// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
+// RUN: -analyzer-config exploration_strategy=dfs -DDFS\
+// RUN: -analyzer-config cplusplus.Move:WarnOn=All -DAGGRESSIVE_DFS\
+// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\
+// RUN: -verify=expected,peaceful,aggressive %s 2>&1 | FileCheck %s
+
#include "Inputs/system-header-simulator-cxx.h"
void clang_analyzer_warnIfReached();
+void clang_analyzer_printState();
class B {
public:
@@ -145,6 +154,19 @@ void simpleMoveCtorTest() {
{
A a;
A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+
+#ifdef AGGRESSIVE_DFS
+ clang_analyzer_printState();
+
+// CHECK: "checker_messages": [
+// CHECK-NEXT: { "checker": "cplusplus.Move", "messages": [
+// CHECK-NEXT: "Moved-from objects :",
+// CHECK: "a: moved",
+// CHECK: ""
+// CHECK-NEXT: ]}
+// CHECK-NEXT: ]
+#endif
+
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
// peaceful-note at -1 {{Method called on moved-from object 'a'}}
}
More information about the cfe-commits
mailing list