================ @@ -20,48 +20,180 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" + +#include <iterator> +#include <utility> +#include <variant> using namespace clang; using namespace ento; namespace { + +struct CritSectionMarker { + const Expr *LockExpr{}; + const MemRegion *LockReg{}; + + void Profile(llvm::FoldingSetNodeID &ID) const { + ID.Add(LockExpr); + ID.Add(LockReg); + } + + [[nodiscard]] constexpr bool + operator==(const CritSectionMarker &Other) const noexcept { + return LockExpr == Other.LockExpr && LockReg == Other.LockReg; + } + [[nodiscard]] constexpr bool + operator!=(const CritSectionMarker &Other) const noexcept { + return !(*this == Other); + } +}; + +class FirstArgMutexDescriptor { + CallDescription LockFn; + CallDescription UnlockFn; + +public: + FirstArgMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn) + : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {} + [[nodiscard]] bool matchesLock(const CallEvent &Call) const { + return LockFn.matches(Call) && Call.getNumArgs() > 0; + } + [[nodiscard]] bool matchesUnlock(const CallEvent &Call) const { + return UnlockFn.matches(Call) && Call.getNumArgs() > 0; + } + [[nodiscard]] const MemRegion *getLockRegion(const CallEvent &Call) const { + return Call.getArgSVal(0).getAsRegion(); + } + [[nodiscard]] const MemRegion *getUnlockRegion(const CallEvent &Call) const { + return Call.getArgSVal(0).getAsRegion(); + } +}; + +class MemberMutexDescriptor { + CallDescription LockFn; + CallDescription UnlockFn; + +public: + MemberMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn) + : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {} + [[nodiscard]] bool matchesLock(const CallEvent &Call) const { + return LockFn.matches(Call); + } + bool matchesUnlock(const CallEvent &Call) const { + return UnlockFn.matches(Call); + } + [[nodiscard]] const MemRegion *getLockRegion(const CallEvent &Call) const { + return cast<CXXMemberCall>(Call).getCXXThisVal().getAsRegion(); + } + [[nodiscard]] const MemRegion *getUnlockRegion(const CallEvent &Call) const { + return cast<CXXMemberCall>(Call).getCXXThisVal().getAsRegion(); + } +}; ---------------- NagyDonat wrote:
Would it be possible to reduce the code duplication between these by introducing a common ancestor class? https://github.com/llvm/llvm-project/pull/80029 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits