summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksei Sidorin <a.sidorin@samsung.com>2016-09-01 13:55:38 +0000
committerAleksei Sidorin <a.sidorin@samsung.com>2016-09-01 13:55:38 +0000
commit29afb1937ba755909fed46402c54cc3d7439b1ed (patch)
tree2e8c432a67b7753d06b462985a9ac16bda6b6e9c
parent3a9eef1670a50265379d4602d17644e491d39597 (diff)
downloadbcm5719-llvm-29afb1937ba755909fed46402c54cc3d7439b1ed.tar.gz
bcm5719-llvm-29afb1937ba755909fed46402c54cc3d7439b1ed.zip
[analyzer] ExprEngine: remove second call to PreStmt<CastExpr>
This patch also introduces AnalysisOrderChecker which is intended for testing of callback call correctness. Differential Revision: https://reviews.llvm.org/D23804 llvm-svn: 280367
-rw-r--r--clang/include/clang/StaticAnalyzer/Checkers/Checkers.td4
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp56
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt1
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp10
-rw-r--r--clang/test/Analysis/castexpr-callback.c10
5 files changed, 72 insertions, 9 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index a7a6623134e..51f22fa6fff 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -634,6 +634,10 @@ def LLVMConventionsChecker : Checker<"Conventions">,
let ParentPackage = Debug in {
+def AnalysisOrderChecker : Checker<"AnalysisOrder">,
+ HelpText<"Print callbacks that are called during analysis in order">,
+ DescFile<"AnalysisOrder.cpp">;
+
def DominatorsTreeDumper : Checker<"DumpDominators">,
HelpText<"Print the dominance tree for a given CFG">,
DescFile<"DebugCheckers.cpp">;
diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
new file mode 100644
index 00000000000..0bb0e3306f6
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
@@ -0,0 +1,56 @@
+//===- AnalysisOrderChecker - Print callbacks called ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker prints callbacks that are called during analysis.
+// This is required to ensure that callbacks are fired in order
+// and do not duplicate or get lost.
+// Feel free to extend this checker with any callback you need to check.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+class AnalysisOrderChecker : public Checker< check::PreStmt<CastExpr>,
+ check::PostStmt<CastExpr>> {
+ bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const {
+ AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions();
+ return Opts.getBooleanOption("*", false, this) ||
+ Opts.getBooleanOption(CallbackName, false, this);
+ }
+
+public:
+ void checkPreStmt(const CastExpr *CE, CheckerContext &C) const {
+ if (isCallbackEnabled(C, "PreStmtCastExpr"))
+ llvm::errs() << "PreStmt<CastExpr> (Kind : " << CE->getCastKindName()
+ << ")\n";
+ }
+
+ void checkPostStmt(const CastExpr *CE, CheckerContext &C) const {
+ if (isCallbackEnabled(C, "PostStmtCastExpr"))
+ llvm::errs() << "PostStmt<CastExpr> (Kind : " << CE->getCastKindName()
+ << ")\n";
+ }
+};
+}
+
+//===----------------------------------------------------------------------===//
+// Registration.
+//===----------------------------------------------------------------------===//
+
+void ento::registerAnalysisOrderChecker(CheckerManager &mgr) {
+ mgr.registerChecker<AnalysisOrderChecker>();
+}
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 75636c66496..5a486cdffb5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
add_clang_library(clangStaticAnalyzerCheckers
AllocationDiagnostics.cpp
+ AnalysisOrderChecker.cpp
AnalyzerStatsChecker.cpp
ArrayBoundChecker.cpp
ArrayBoundCheckerV2.cpp
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 6ca24c78a12..97f4d9fc19c 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1212,16 +1212,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::ObjCBridgedCastExprClass: {
Bldr.takeNodes(Pred);
const CastExpr *C = cast<CastExpr>(S);
- // Handle the previsit checks.
- ExplodedNodeSet dstPrevisit;
- getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this);
-
- // Handle the expression itself.
ExplodedNodeSet dstExpr;
- for (ExplodedNodeSet::iterator i = dstPrevisit.begin(),
- e = dstPrevisit.end(); i != e ; ++i) {
- VisitCast(C, C->getSubExpr(), *i, dstExpr);
- }
+ VisitCast(C, C->getSubExpr(), Pred, dstExpr);
// Handle the postvisit checks.
getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
diff --git a/clang/test/Analysis/castexpr-callback.c b/clang/test/Analysis/castexpr-callback.c
new file mode 100644
index 00000000000..73fa17a134a
--- /dev/null
+++ b/clang/test/Analysis/castexpr-callback.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PreStmtCastExpr=true,debug.AnalysisOrder:PostStmtCastExpr=true %s 2>&1 | FileCheck %s
+
+void test(char c) {
+ int i = (int)c;
+}
+
+// CHECK: PreStmt<CastExpr> (Kind : LValueToRValue)
+// CHECK-NEXT: PostStmt<CastExpr> (Kind : LValueToRValue)
+// CHECK-NEXT: PreStmt<CastExpr> (Kind : IntegralCast)
+// CHECK-NEXT: PostStmt<CastExpr> (Kind : IntegralCast)
OpenPOWER on IntegriCloud