Author: Dmitri Gribenko Date: 2020-06-29T17:00:15+02:00 New Revision: a44425f25b5ca417e7ecee6e7e00040224e50a69
URL: https://github.com/llvm/llvm-project/commit/a44425f25b5ca417e7ecee6e7e00040224e50a69 DIFF: https://github.com/llvm/llvm-project/commit/a44425f25b5ca417e7ecee6e7e00040224e50a69.diff LOG: Revert "[analyzer][NFC] Add unittest for FalsePositiveRefutationBRVisitor" This reverts commit e22cae32c5c4cf8c49b674cea34c105a6cb015f9. It broke the build: FalsePositiveRefutationBRVisitorTest.cpp:112:3: error: use of undeclared identifier 'LLVM_WITH_Z3' Added: Modified: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp clang/unittests/StaticAnalyzer/CMakeLists.txt clang/unittests/StaticAnalyzer/CheckerRegistration.h Removed: clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 719edfdb51e6..ad79f7cb9359 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -52,7 +52,6 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" @@ -2813,19 +2812,12 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, // Implementation of FalsePositiveRefutationBRVisitor. //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "FalsePositiveRefutationBRVisitor" -STATISTIC(CrosscheckedBugReports, - "The # of bug reports which were checked for infeasible constraints"); -STATISTIC(CrosscheckInvalidatedBugReports, - "The # of bug reports invalidated due to infeasible constraints"); - FalsePositiveRefutationBRVisitor::FalsePositiveRefutationBRVisitor() : Constraints(ConstraintRangeTy::Factory().getEmptyMap()) {} void FalsePositiveRefutationBRVisitor::finalizeVisitor( BugReporterContext &BRC, const ExplodedNode *EndPathNode, PathSensitiveBugReport &BR) { - ++CrosscheckedBugReports; // Collect new constraints VisitNode(EndPathNode, BRC, BR); @@ -2856,10 +2848,8 @@ void FalsePositiveRefutationBRVisitor::finalizeVisitor( if (!isSat.hasValue()) return; - if (!isSat.getValue()) { - ++CrosscheckInvalidatedBugReports; + if (!isSat.getValue()) BR.markInvalid("Infeasible constraints", EndPathNode->getLocationContext()); - } } PathDiagnosticPieceRef FalsePositiveRefutationBRVisitor::VisitNode( diff --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt b/clang/unittests/StaticAnalyzer/CMakeLists.txt index 0e6d8763d96d..564eba879f24 100644 --- a/clang/unittests/StaticAnalyzer/CMakeLists.txt +++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt @@ -7,7 +7,6 @@ add_clang_unittest(StaticAnalysisTests AnalyzerOptionsTest.cpp CallDescriptionTest.cpp CallEventTest.cpp - FalsePositiveRefutationBRVisitorTest.cpp ParamRegionTest.cpp RangeSetTest.cpp RegisterCustomCheckersTest.cpp diff --git a/clang/unittests/StaticAnalyzer/CheckerRegistration.h b/clang/unittests/StaticAnalyzer/CheckerRegistration.h index e02b856e0e9c..0bbed9b7784f 100644 --- a/clang/unittests/StaticAnalyzer/CheckerRegistration.h +++ b/clang/unittests/StaticAnalyzer/CheckerRegistration.h @@ -14,7 +14,6 @@ #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h" #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" #include "clang/Tooling/Tooling.h" -#include "gtest/gtest.h" namespace clang { namespace ento { @@ -66,21 +65,10 @@ class TestAction : public ASTFrontendAction { } }; -inline SmallString<80> getCurrentTestNameAsFileName() { - const ::testing::TestInfo *Info = - ::testing::UnitTest::GetInstance()->current_test_info(); - - SmallString<80> FileName; - (Twine{Info->name()} + ".cc").toVector(FileName); - return FileName; -} - template <AddCheckerFn... Fns> bool runCheckerOnCode(const std::string &Code, std::string &Diags) { - const SmallVectorImpl<char> &FileName = getCurrentTestNameAsFileName(); llvm::raw_string_ostream OS(Diags); - return tooling::runToolOnCode(std::make_unique<TestAction<Fns...>>(OS), Code, - FileName); + return tooling::runToolOnCode(std::make_unique<TestAction<Fns...>>(OS), Code); } template <AddCheckerFn... Fns> @@ -89,22 +77,5 @@ bool runCheckerOnCode(const std::string &Code) { return runCheckerOnCode<Fns...>(Code, Diags); } -template <AddCheckerFn... Fns> -bool runCheckerOnCodeWithArgs(const std::string &Code, - const std::vector<std::string> &Args, - std::string &Diags) { - const SmallVectorImpl<char> &FileName = getCurrentTestNameAsFileName(); - llvm::raw_string_ostream OS(Diags); - return tooling::runToolOnCodeWithArgs( - std::make_unique<TestAction<Fns...>>(OS), Code, Args, FileName); -} - -template <AddCheckerFn... Fns> -bool runCheckerOnCodeWithArgs(const std::string &Code, - const std::vector<std::string> &Args) { - std::string Diags; - return runCheckerOnCodeWithArgs<Fns...>(Code, Args, Diags); -} - } // namespace ento } // namespace clang diff --git a/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp b/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp deleted file mode 100644 index 60f266dd685d..000000000000 --- a/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp +++ /dev/null @@ -1,175 +0,0 @@ -//===- unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp --===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "CheckerRegistration.h" -#include "Reusables.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" -#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h" -#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" -#include "llvm/Config/config.h" -#include "gtest/gtest.h" - -// FIXME: Use GTEST_SKIP() instead if GTest is updated to version 1.10.0 -#define SKIP_WITHOUT_Z3 \ - do \ - if (!LLVM_WITH_Z3) \ - return; \ - while (0) - -namespace clang { -namespace ento { -namespace { - -class FalsePositiveGenerator : public Checker<eval::Call> { - using Self = FalsePositiveGenerator; - const BuiltinBug FalsePositiveGeneratorBug{this, "FalsePositiveGenerator"}; - using HandlerFn = bool (Self::*)(const CallEvent &Call, - CheckerContext &) const; - CallDescriptionMap<HandlerFn> Callbacks = { - {{"reachedWithContradiction", 0}, &Self::reachedWithContradiction}, - {{"reachedWithNoContradiction", 0}, &Self::reachedWithNoContradiction}, - {{"reportIfCanBeTrue", 1}, &Self::reportIfCanBeTrue}, - }; - - bool report(CheckerContext &C, ProgramStateRef State, - StringRef Description) const { - ExplodedNode *Node = C.generateNonFatalErrorNode(State); - if (!Node) - return false; - - auto Report = std::make_unique<PathSensitiveBugReport>( - FalsePositiveGeneratorBug, Description, Node); - C.emitReport(std::move(Report)); - return true; - } - - bool reachedWithNoContradiction(const CallEvent &, CheckerContext &C) const { - return report(C, C.getState(), "REACHED_WITH_NO_CONTRADICTION"); - } - - bool reachedWithContradiction(const CallEvent &, CheckerContext &C) const { - return report(C, C.getState(), "REACHED_WITH_CONTRADICTION"); - } - - // Similar to ExprInspectionChecker::analyzerEval except it emits warning only - // if the argument can be true. The report emits the report in the state where - // the assertion true. - bool reportIfCanBeTrue(const CallEvent &Call, CheckerContext &C) const { - // A specific instantiation of an inlined function may have more constrained - // values than can generally be assumed. Skip the check. - if (C.getPredecessor()->getLocationContext()->getStackFrame()->getParent()) - return false; - - SVal AssertionVal = Call.getArgSVal(0); - if (AssertionVal.isUndef()) - return false; - - ProgramStateRef State = C.getPredecessor()->getState(); - ProgramStateRef StTrue; - std::tie(StTrue, std::ignore) = - State->assume(AssertionVal.castAs<DefinedOrUnknownSVal>()); - if (StTrue) - return report(C, StTrue, "CAN_BE_TRUE"); - return false; - } - -public: - bool evalCall(const CallEvent &Call, CheckerContext &C) const { - if (const HandlerFn *Callback = Callbacks.lookup(Call)) - return (this->*(*Callback))(Call, C); - return false; - } -}; - -void addFalsePositiveGenerator(AnalysisASTConsumer &AnalysisConsumer, - AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"test.FalsePositiveGenerator", true}, - {"debug.ViewExplodedGraph", false}}; - AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) { - Registry.addChecker<FalsePositiveGenerator>( - "test.FalsePositiveGenerator", "EmptyDescription", "EmptyDocsUri"); - }); -} - -// C++20 use constexpr below. -const std::vector<std::string> LazyAssumeArgs{ - "-Xclang", "-analyzer-config", "-Xclang", "eagerly-assume=false"}; -const std::vector<std::string> LazyAssumeAndCrossCheckArgs{ - "-Xclang", "-analyzer-config", "-Xclang", "eagerly-assume=false", - "-Xclang", "-analyzer-config", "-Xclang", "crosscheck-with-z3=true"}; - -TEST(FalsePositiveRefutationBRVisitor, UnSatInTheMiddleNoReport) { - SKIP_WITHOUT_Z3; - constexpr auto Code = R"( - void reachedWithContradiction(); - void reachedWithNoContradiction(); - void test(int x, int y) { - if (x * y == 0) - return; - reachedWithNoContradiction(); - if (x == 0) { - reachedWithContradiction(); - // x * y != 0 => x != 0 && y != 0 => contradict with x == 0 - } - })"; - - std::string Diags; - EXPECT_TRUE(runCheckerOnCodeWithArgs<addFalsePositiveGenerator>( - Code, LazyAssumeAndCrossCheckArgs, Diags)); - EXPECT_EQ(Diags, - "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n"); - // Single warning. The second report was invalidated by the visitor. - - // Without enabling the crosscheck-with-z3 both reports are displayed. - std::string Diags2; - EXPECT_TRUE(runCheckerOnCodeWithArgs<addFalsePositiveGenerator>( - Code, LazyAssumeArgs, Diags2)); - EXPECT_EQ(Diags2, - "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n" - "test.FalsePositiveGenerator:REACHED_WITH_CONTRADICTION\n"); -} - -TEST(FalsePositiveRefutationBRVisitor, UnSatAtErrorNodeWithNewSymbolNoReport) { - SKIP_WITHOUT_Z3; - constexpr auto Code = R"( - void reportIfCanBeTrue(bool); - void reachedWithNoContradiction(); - void test(int x, int y) { - if (x * y == 0) - return; - // We know that 'x * y': {[MIN,-1], [1,MAX]} - reachedWithNoContradiction(); - reportIfCanBeTrue(x == 0); // contradiction - // The function introduces the 'x == 0' constraint in the ErrorNode which - // leads to contradiction with the constraint of 'x * y'. - // Note that the new constraint was bound to a new symbol 'x'. - })"; - std::string Diags; - EXPECT_TRUE(runCheckerOnCodeWithArgs<addFalsePositiveGenerator>( - Code, LazyAssumeAndCrossCheckArgs, Diags)); - EXPECT_EQ(Diags, - "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n"); - // Single warning. The second report was invalidated by the visitor. - - // Without enabling the crosscheck-with-z3 both reports are displayed. - std::string Diags2; - EXPECT_TRUE(runCheckerOnCodeWithArgs<addFalsePositiveGenerator>( - Code, LazyAssumeArgs, Diags2)); - EXPECT_EQ(Diags2, - "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n" - "test.FalsePositiveGenerator:CAN_BE_TRUE\n"); -} - -} // namespace -} // namespace ento -} // namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits