llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-static-analyzer-1 Author: Benedek Kaibas (benedekaibas) <details> <summary>Changes</summary> I have implemented the checkPostCall function to understand the lifetimebound annotations when a parameter is annotated with it. I have generated the ExplodedGraph as well and the annotation is present. This PR is just the very base of the whole implementation of making the annotations present in the program state and I do not cover all the cases yet, but I just want to see if you have any suggestions for me. Here is the Compiler Explorer link to the code I have used as a test: https://godbolt.org/z/K896aceMf --- Full diff: https://github.com/llvm/llvm-project/pull/200145.diff 3 Files Affected: - (modified) clang/include/clang/StaticAnalyzer/Checkers/Checkers.td (+4) - (modified) clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt (+1) - (added) clang/lib/StaticAnalyzer/Checkers/LifetimeAnnotations.cpp (+73) ``````````diff diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index eca2afbe340a9..85d59fc139728 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -788,6 +788,10 @@ def SmartPtrChecker: Checker<"SmartPtr">, Dependencies<[SmartPtrModeling]>, Documentation<HasDocumentation>; +def LifetimeAnnotations : Checker<"LifetimeAnnotations">, + HelpText<"Check for lifetime violations using lifetime annotations">, + Documentation<NotDocumented>; + } // end: "alpha.cplusplus" //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index 8a0621077b977..3f426186189fa 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -55,6 +55,7 @@ add_clang_library(clangStaticAnalyzerCheckers IteratorModeling.cpp IteratorRangeChecker.cpp IvarInvalidationChecker.cpp + LifetimeAnnotations.cpp LLVMConventionsChecker.cpp LocalizationChecker.cpp MacOSKeychainAPIChecker.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/LifetimeAnnotations.cpp b/clang/lib/StaticAnalyzer/Checkers/LifetimeAnnotations.cpp new file mode 100644 index 0000000000000..54e98b945c7b3 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/LifetimeAnnotations.cpp @@ -0,0 +1,73 @@ +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.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 <AllocationState.h> + +using namespace clang; +using namespace ento; + +REGISTER_MAP_WITH_PROGRAMSTATE(LifetimeBoundMap, const MemRegion *, + const MemRegion *); + +class LifetimeAnnotations : public Checker<check::PostCall> { +public: + void checkPostCall(const CallEvent &Call, CheckerContext &C) const; + void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, + const char *Sep) const override; +}; + +void LifetimeAnnotations::checkPostCall(const CallEvent &Call, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + + const auto *MethodDecl = dyn_cast_if_present<CXXMethodDecl>(Call.getDecl()); + + if (!MethodDecl) + return; + + unsigned LBParamIdx = MethodDecl->getNumParams(); + for (unsigned i = 0; i < MethodDecl->getNumParams(); i++) { + if (MethodDecl->getParamDecl(i)->hasAttr<LifetimeBoundAttr>()) { + LBParamIdx = i; + break; + } + } + if (LBParamIdx == MethodDecl->getNumParams()) + return; + + SVal RetVal = Call.getReturnValue(); + const MemRegion *RetValRegion = RetVal.getAsRegion(); + if (!RetValRegion) + return; + + SVal ArgVal = Call.getArgSVal(LBParamIdx); + const MemRegion *ArgValRegion = ArgVal.getAsRegion(); + if (!ArgValRegion) + return; + + State = State->set<LifetimeBoundMap>(RetValRegion, ArgValRegion); + C.addTransition(State); +} + +void LifetimeAnnotations::printState(raw_ostream &Out, ProgramStateRef State, + const char *NL, const char *Sep) const { + auto LBTy = State->get<LifetimeBoundMap>(); + + if (!LBTy.isEmpty()) { + Out << Sep << "LifetimeBound objects: "; + + for (auto I : LBTy) { + Out << I.first << " bound to " << I.second << NL; + } + } +} + +void ento::registerLifetimeAnnotations(CheckerManager &mgr) { + mgr.registerChecker<LifetimeAnnotations>(); +} + +bool ento::shouldRegisterLifetimeAnnotations(const CheckerManager &mgr) { + return true; +} `````````` </details> https://github.com/llvm/llvm-project/pull/200145 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
