Author: r.stahl Date: Mon Jan 7 07:07:01 2019 New Revision: 350528 URL: http://llvm.org/viewvc/llvm-project?rev=350528&view=rev Log: [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 Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=350528&r1=350527&r2=350528&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Mon Jan 7 07:07:01 2019 @@ -1052,7 +1052,7 @@ void ExprEngine::VisitIncrementDecrement // Perform the store, so that the uninitialized value detection happens. Bldr.takeNodes(*I); ExplodedNodeSet Dst3; - evalStore(Dst3, U, U, *I, state, loc, V2_untested); + evalStore(Dst3, U, Ex, *I, state, loc, V2_untested); Bldr.addNodes(Dst3); continue; @@ -1120,7 +1120,7 @@ void ExprEngine::VisitIncrementDecrement // Perform the store. Bldr.takeNodes(*I); ExplodedNodeSet Dst3; - evalStore(Dst3, U, U, *I, state, loc, Result); + evalStore(Dst3, U, Ex, *I, state, loc, Result); Bldr.addNodes(Dst3); } Dst.insert(Dst2); Modified: cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp?rev=350528&r1=350527&r2=350528&view=diff ============================================================================== --- cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp (original) +++ cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp Mon Jan 7 07:07:01 2019 @@ -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)++; }")); +} + } } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits