================ @@ -0,0 +1,106 @@ +//===- unittests/StaticAnalyzer/CheckLifetimeEndTest.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/CallDescription.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/llvm-config.h" +#include "gtest/gtest.h" + +namespace { +using namespace clang; +using namespace ento; + +class LifetimeEndReporter : public Checker<check::LifetimeEnd> { + const BugType LifetimeEndNode{this, "LifetimeEndReporter"}; + + bool report(CheckerContext &C, Twine Description) const { + ExplodedNode *Node = C.generateNonFatalErrorNode(C.getState()); + if (!Node) + return false; + + auto Report = std::make_unique<PathSensitiveBugReport>( + LifetimeEndNode, Description.str(), Node); + C.emitReport(std::move(Report)); + return true; + } + +public: + void checkLifetimeEnd(const VarDecl *D, CheckerContext &C) const { + auto II = D->getIdentifier(); + ASSERT_TRUE(II != nullptr); + report(C, II->getName() + " LIFETIME END"); + } +}; + +void addLifetimeEndReporter(AnalysisASTConsumer &AnalysisConsumer, + AnalyzerOptions &AnOpts) { + AnOpts.CheckersAndPackages = { + {"test.LifetimeEndReporter", true}, + }; + AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) { + Registry.addChecker<LifetimeEndReporter>( + "test.LifetimeEndReporter", "EmptyDescription", "EmptyDocsUri"); + }); +} + +const std::vector<std::string> DisableLifetimeArgs{ + "-Xclang", "-analyzer-config", "-Xclang", "cfg-lifetime=false"}; +const std::vector<std::string> EnableLifetimeArgs{ + "-Xclang", "-analyzer-config", "-Xclang", "cfg-lifetime=true"}; + +TEST(CheckLifetimeEnd, CFGLifetimeEnabled) { + constexpr auto Code = R"( +void foo() { + int i = 0; +} + )"; + + std::string Diags; + EXPECT_TRUE(runCheckerOnCodeWithArgs<addLifetimeEndReporter>( + Code, EnableLifetimeArgs, Diags, /*OnlyEmitWarnings=*/true)); + EXPECT_EQ(Diags, "test.LifetimeEndReporter: i LIFETIME END\n"); +} ---------------- steakhal wrote:
You tried hard not checking the CFG dumps in LIT. While this test demonstrates that the callback gets called, and that replies with some plausible parameterization, it doesn't demonstrate that the CFG element is at the right place relative to the other CFGElements. I think we should also test: - multiple variables on stack - local static: does not call lifetime ends - local variables within nested blocks (like a local variable within the loop, or the loop induction variable lifetime) - how it works with lifetime extension https://github.com/llvm/llvm-project/pull/201123 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
