================
@@ -56,111 +83,20 @@ struct CritSectionMarker {
}
};
-class CallDescriptionBasedMatcher {
- CallDescription LockFn;
- CallDescription UnlockFn;
-
-public:
- CallDescriptionBasedMatcher(CallDescription &&LockFn,
- CallDescription &&UnlockFn)
- : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {}
- [[nodiscard]] bool matches(const CallEvent &Call, bool IsLock) const {
- if (IsLock) {
- return LockFn.matches(Call);
- }
- return UnlockFn.matches(Call);
- }
-};
-
-class FirstArgMutexDescriptor : public CallDescriptionBasedMatcher {
-public:
- FirstArgMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn)
- : CallDescriptionBasedMatcher(std::move(LockFn), std::move(UnlockFn)) {}
-
- [[nodiscard]] const MemRegion *getRegion(const CallEvent &Call, bool) const {
- return Call.getArgSVal(0).getAsRegion();
- }
-};
-
-class MemberMutexDescriptor : public CallDescriptionBasedMatcher {
-public:
- MemberMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn)
- : CallDescriptionBasedMatcher(std::move(LockFn), std::move(UnlockFn)) {}
-
- [[nodiscard]] const MemRegion *getRegion(const CallEvent &Call, bool) const {
- return cast<CXXMemberCall>(Call).getCXXThisVal().getAsRegion();
- }
+enum class Role {
+ Lock,
+ Unlock,
};
-class RAIIMutexDescriptor {
- mutable const IdentifierInfo *Guard{};
- mutable bool IdentifierInfoInitialized{};
- mutable llvm::SmallString<32> GuardName{};
-
- void initIdentifierInfo(const CallEvent &Call) const {
- if (!IdentifierInfoInitialized) {
- // In case of checking C code, or when the corresponding headers are not
- // included, we might end up query the identifier table every time when
- // this function is called instead of early returning it. To avoid this,
a
- // bool variable (IdentifierInfoInitialized) is used and the function
will
- // be run only once.
- const auto &ASTCtx = Call.getASTContext();
- Guard = &ASTCtx.Idents.get(GuardName);
- }
- }
+using GetRegionFn = const MemRegion *(*)(const CallEvent &);
+using FilterFn = bool (*)(const CallEvent &);
- template <typename T> bool matchesImpl(const CallEvent &Call) const {
- const T *C = dyn_cast<T>(&Call);
- if (!C)
- return false;
- const IdentifierInfo *II =
- cast<CXXRecordDecl>(C->getDecl()->getParent())->getIdentifier();
- if (II != Guard)
- return false;
-
- // For unique_lock, check if it's constructed with a ctor that takes the
tag
- // type defer_lock_t. In this case, the lock is not acquired.
- if constexpr (std::is_same_v<T, CXXConstructorCall>) {
- if (GuardName == "unique_lock" && C->getNumArgs() >= 2) {
- const Expr *SecondArg = C->getArgExpr(1);
- QualType ArgType = SecondArg->getType().getNonReferenceType();
- if (const auto *RD = ArgType->getAsRecordDecl();
- RD && RD->getName() == "defer_lock_t" && RD->isInStdNamespace()) {
- return false;
- }
- }
- }
-
- return true;
- }
-
-public:
- RAIIMutexDescriptor(StringRef GuardName) : GuardName(GuardName) {}
- [[nodiscard]] bool matches(const CallEvent &Call, bool IsLock) const {
- initIdentifierInfo(Call);
- if (IsLock) {
- return matchesImpl<CXXConstructorCall>(Call);
- }
- return matchesImpl<CXXDestructorCall>(Call);
- }
- [[nodiscard]] const MemRegion *getRegion(const CallEvent &Call,
- bool IsLock) const {
- const MemRegion *LockRegion = nullptr;
- if (IsLock) {
- if (std::optional<SVal> Object = Call.getReturnValueUnderConstruction())
{
- LockRegion = Object->getAsRegion();
- }
- } else {
- LockRegion = cast<CXXDestructorCall>(Call).getCXXThisVal().getAsRegion();
- }
- return LockRegion;
- }
+struct ThreadingCallDescription {
+ Role Role;
+ GetRegionFn GetRegion = getFirstArgRegion;
+ FilterFn Filter = nullptr;
----------------
steakhal wrote:
We could default this to (auto) => false.
https://github.com/llvm/llvm-project/pull/224230
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits