aboutsummaryrefslogtreecommitdiff
path: root/clang/unittests
diff options
context:
space:
mode:
authorRafael Stahl <r.stahl@tum.de>2019-01-07 15:07:01 +0000
committerRafael Stahl <r.stahl@tum.de>2019-01-07 15:07:01 +0000
commitcc19f921b5797446943d040884981eb4b82c4a3e (patch)
tree1000bd3797c551dccdf41efb784a91d05cffed32 /clang/unittests
parent9b6dfac5ad6a80766234203c23d26b5cff15711b (diff)
[analyzer] Pass the correct loc Expr from VisitIncDecOp to evalStore
Summary: The LocationE parameter of evalStore is documented as "The location expression that is stored to". When storing from an increment / decrement operator this was not satisfied. In user code this causes an inconsistency between the SVal and Stmt parameters of checkLocation. Reviewers: NoQ, dcoughlin, george.karpenkov Reviewed By: NoQ Subscribers: xazax.hun, baloghadamsoftware, szepet, a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, dkrupp, cfe-commits Differential Revision: https://reviews.llvm.org/D55701 llvm-svn: 350528
Diffstat (limited to 'clang/unittests')
-rw-r--r--clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp55
1 files changed, 39 insertions, 16 deletions
diff --git a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
index 0dbf3ae451d2..568a719e3366 100644
--- a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
+++ b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
@@ -21,16 +21,7 @@ namespace clang {
namespace ento {
namespace {
-class CustomChecker : public Checker<check::ASTCodeBody> {
-public:
- void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
- BugReporter &BR) const {
- BR.EmitBasicReport(D, this, "Custom diagnostic", categories::LogicError,
- "Custom diagnostic description",
- PathDiagnosticLocation(D, Mgr.getSourceManager()), {});
- }
-};
-
+template <typename CheckerT>
class TestAction : public ASTFrontendAction {
class DiagConsumer : public PathDiagnosticConsumer {
llvm::raw_ostream &Output;
@@ -59,23 +50,55 @@ public:
Compiler.getAnalyzerOpts()->CheckersControlList = {
{"custom.CustomChecker", true}};
AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
- Registry.addChecker<CustomChecker>("custom.CustomChecker", "Description",
- "");
+ Registry.addChecker<CheckerT>("custom.CustomChecker", "Description", "");
});
return std::move(AnalysisConsumer);
}
};
+template <typename CheckerT>
+bool runCheckerOnCode(const std::string &Code, std::string &Diags) {
+ llvm::raw_string_ostream OS(Diags);
+ return tooling::runToolOnCode(new TestAction<CheckerT>(OS), Code);
+}
+template <typename CheckerT>
+bool runCheckerOnCode(const std::string &Code) {
+ std::string Diags;
+ return runCheckerOnCode<CheckerT>(Code, Diags);
+}
+
+
+class CustomChecker : public Checker<check::ASTCodeBody> {
+public:
+ void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
+ BugReporter &BR) const {
+ BR.EmitBasicReport(D, this, "Custom diagnostic", categories::LogicError,
+ "Custom diagnostic description",
+ PathDiagnosticLocation(D, Mgr.getSourceManager()), {});
+ }
+};
TEST(RegisterCustomCheckers, RegisterChecker) {
std::string Diags;
- {
- llvm::raw_string_ostream OS(Diags);
- EXPECT_TRUE(tooling::runToolOnCode(new TestAction(OS), "void f() {;}"));
- }
+ EXPECT_TRUE(runCheckerOnCode<CustomChecker>("void f() {;}", Diags));
EXPECT_EQ(Diags, "custom.CustomChecker:Custom diagnostic description");
}
+class LocIncDecChecker : public Checker<check::Location> {
+public:
+ void checkLocation(SVal Loc, bool IsLoad, const Stmt *S,
+ CheckerContext &C) const {
+ auto UnaryOp = dyn_cast<UnaryOperator>(S);
+ if (UnaryOp && !IsLoad)
+ EXPECT_FALSE(UnaryOp->isIncrementOp());
+ }
+};
+
+TEST(RegisterCustomCheckers, CheckLocationIncDec) {
+ EXPECT_TRUE(
+ runCheckerOnCode<LocIncDecChecker>("void f() { int *p; (*p)++; }"));
+}
+
}
}
}