mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-01 12:43:47 +00:00
[analyzer][NFC] Switch to using CallDescription::matches() instead of isCalled()
This patch replaces each use of the previous API with the new one. In variadic cases, it will use the ADL `matchesAny(Call, CDs...)` variadic function. Also simplifies some code involving such operations. Reviewed By: martong, xazax.hun Differential Revision: https://reviews.llvm.org/D113591
This commit is contained in:
parent
6c512703a9
commit
f18da190b0
@ -257,20 +257,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns true if the CallEvent is a call to a function that matches
|
||||
/// the CallDescription.
|
||||
///
|
||||
/// Note that this function is not intended to be used to match Obj-C method
|
||||
/// calls.
|
||||
bool isCalled(const CallDescription &CD) const;
|
||||
|
||||
/// Returns true whether the CallEvent is any of the CallDescriptions supplied
|
||||
/// as a parameter.
|
||||
template <typename FirstCallDesc, typename... CallDescs>
|
||||
bool isCalled(const FirstCallDesc &First, const CallDescs &... Rest) const {
|
||||
return isCalled(First) || isCalled(Rest...);
|
||||
}
|
||||
|
||||
/// Returns a source range for the entire call, suitable for
|
||||
/// outputting in diagnostics.
|
||||
virtual SourceRange getSourceRange() const {
|
||||
|
@ -551,8 +551,8 @@ void CFRetainReleaseChecker::checkPreCall(const CallEvent &Call,
|
||||
return;
|
||||
|
||||
// Check if we called CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
|
||||
if (!(Call.isCalled(CFRetain) || Call.isCalled(CFRelease) ||
|
||||
Call.isCalled(CFMakeCollectable) || Call.isCalled(CFAutorelease)))
|
||||
|
||||
if (!matchesAny(Call, CFRetain, CFRelease, CFMakeCollectable, CFAutorelease))
|
||||
return;
|
||||
|
||||
// Get the argument's value.
|
||||
|
@ -97,14 +97,7 @@ void BlockInCriticalSectionChecker::initIdentifierInfo(ASTContext &Ctx) const {
|
||||
}
|
||||
|
||||
bool BlockInCriticalSectionChecker::isBlockingFunction(const CallEvent &Call) const {
|
||||
if (Call.isCalled(SleepFn)
|
||||
|| Call.isCalled(GetcFn)
|
||||
|| Call.isCalled(FgetsFn)
|
||||
|| Call.isCalled(ReadFn)
|
||||
|| Call.isCalled(RecvFn)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return matchesAny(Call, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn);
|
||||
}
|
||||
|
||||
bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) const {
|
||||
@ -114,15 +107,8 @@ bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) const
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Call.isCalled(LockFn)
|
||||
|| Call.isCalled(PthreadLockFn)
|
||||
|| Call.isCalled(PthreadTryLockFn)
|
||||
|| Call.isCalled(MtxLock)
|
||||
|| Call.isCalled(MtxTimedLock)
|
||||
|| Call.isCalled(MtxTryLock)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return matchesAny(Call, LockFn, PthreadLockFn, PthreadTryLockFn, MtxLock,
|
||||
MtxTimedLock, MtxTryLock);
|
||||
}
|
||||
|
||||
bool BlockInCriticalSectionChecker::isUnlockFunction(const CallEvent &Call) const {
|
||||
@ -133,12 +119,7 @@ bool BlockInCriticalSectionChecker::isUnlockFunction(const CallEvent &Call) cons
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Call.isCalled(UnlockFn)
|
||||
|| Call.isCalled(PthreadUnlockFn)
|
||||
|| Call.isCalled(MtxUnlock)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return matchesAny(Call, UnlockFn, PthreadUnlockFn, MtxUnlock);
|
||||
}
|
||||
|
||||
void BlockInCriticalSectionChecker::checkPostCall(const CallEvent &Call,
|
||||
|
@ -2272,11 +2272,10 @@ CStringChecker::FnCheck CStringChecker::identifyCall(const CallEvent &Call,
|
||||
if (!FD)
|
||||
return nullptr;
|
||||
|
||||
if (Call.isCalled(StdCopy)) {
|
||||
if (StdCopy.matches(Call))
|
||||
return &CStringChecker::evalStdCopy;
|
||||
} else if (Call.isCalled(StdCopyBackward)) {
|
||||
if (StdCopyBackward.matches(Call))
|
||||
return &CStringChecker::evalStdCopyBackward;
|
||||
}
|
||||
|
||||
// Pro-actively check that argument types are safe to do arithmetic upon.
|
||||
// We do not want to crash if someone accidentally passes a structure
|
||||
|
@ -64,11 +64,11 @@ private:
|
||||
} // end anonymous namespace
|
||||
|
||||
bool ChrootChecker::evalCall(const CallEvent &Call, CheckerContext &C) const {
|
||||
if (Call.isCalled(Chroot)) {
|
||||
if (Chroot.matches(Call)) {
|
||||
evalChroot(Call, C);
|
||||
return true;
|
||||
}
|
||||
if (Call.isCalled(Chdir)) {
|
||||
if (Chdir.matches(Call)) {
|
||||
evalChdir(Call, C);
|
||||
return true;
|
||||
}
|
||||
@ -116,7 +116,7 @@ void ChrootChecker::evalChdir(const CallEvent &Call, CheckerContext &C) const {
|
||||
void ChrootChecker::checkPreCall(const CallEvent &Call,
|
||||
CheckerContext &C) const {
|
||||
// Ignore chroot and chdir.
|
||||
if (Call.isCalled(Chroot) || Call.isCalled(Chdir))
|
||||
if (matchesAny(Call, Chroot, Chdir))
|
||||
return;
|
||||
|
||||
// If jail state is ROOT_CHANGED, generate BugReport.
|
||||
|
@ -126,19 +126,15 @@ bool InnerPointerChecker::isInvalidatingMemberFunction(
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return (isa<CXXDestructorCall>(Call) || Call.isCalled(AppendFn) ||
|
||||
Call.isCalled(AssignFn) || Call.isCalled(ClearFn) ||
|
||||
Call.isCalled(EraseFn) || Call.isCalled(InsertFn) ||
|
||||
Call.isCalled(PopBackFn) || Call.isCalled(PushBackFn) ||
|
||||
Call.isCalled(ReplaceFn) || Call.isCalled(ReserveFn) ||
|
||||
Call.isCalled(ResizeFn) || Call.isCalled(ShrinkToFitFn) ||
|
||||
Call.isCalled(SwapFn));
|
||||
return isa<CXXDestructorCall>(Call) ||
|
||||
matchesAny(Call, AppendFn, AssignFn, ClearFn, EraseFn, InsertFn,
|
||||
PopBackFn, PushBackFn, ReplaceFn, ReserveFn, ResizeFn,
|
||||
ShrinkToFitFn, SwapFn);
|
||||
}
|
||||
|
||||
bool InnerPointerChecker::isInnerPointerAccessFunction(
|
||||
const CallEvent &Call) const {
|
||||
return (Call.isCalled(CStrFn) || Call.isCalled(DataFn) ||
|
||||
Call.isCalled(DataMemberFn));
|
||||
return matchesAny(Call, CStrFn, DataFn, DataMemberFn);
|
||||
}
|
||||
|
||||
void InnerPointerChecker::markPtrSymbolsReleased(const CallEvent &Call,
|
||||
@ -185,7 +181,7 @@ void InnerPointerChecker::checkFunctionArguments(const CallEvent &Call,
|
||||
|
||||
// std::addressof function accepts a non-const reference as an argument,
|
||||
// but doesn't modify it.
|
||||
if (Call.isCalled(AddressofFn))
|
||||
if (AddressofFn.matches(Call))
|
||||
continue;
|
||||
|
||||
markPtrSymbolsReleased(Call, State, ArgRegion, C);
|
||||
|
@ -181,7 +181,7 @@ static bool isInMIGCall(CheckerContext &C) {
|
||||
}
|
||||
|
||||
void MIGChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const {
|
||||
if (Call.isCalled(OsRefRetain)) {
|
||||
if (OsRefRetain.matches(Call)) {
|
||||
// If the code is doing reference counting over the parameter,
|
||||
// it opens up an opportunity for safely calling a destructor function.
|
||||
// TODO: We should still check for over-releases.
|
||||
@ -199,7 +199,7 @@ void MIGChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const {
|
||||
|
||||
auto I = llvm::find_if(Deallocators,
|
||||
[&](const std::pair<CallDescription, unsigned> &Item) {
|
||||
return Call.isCalled(Item.first);
|
||||
return Item.first.matches(Call);
|
||||
});
|
||||
if (I == Deallocators.end())
|
||||
return;
|
||||
|
@ -47,7 +47,7 @@ int MmapWriteExecChecker::ProtRead = 0x01;
|
||||
|
||||
void MmapWriteExecChecker::checkPreCall(const CallEvent &Call,
|
||||
CheckerContext &C) const {
|
||||
if (Call.isCalled(MmapFn) || Call.isCalled(MprotectFn)) {
|
||||
if (matchesAny(Call, MmapFn, MprotectFn)) {
|
||||
SVal ProtVal = Call.getArgSVal(2);
|
||||
Optional<nonloc::ConcreteInt> ProtLoc = ProtVal.getAs<nonloc::ConcreteInt>();
|
||||
int64_t Prot = ProtLoc->getValue().getSExtValue();
|
||||
|
@ -120,7 +120,7 @@ void SimpleStreamChecker::checkPostCall(const CallEvent &Call,
|
||||
if (!Call.isGlobalCFunction())
|
||||
return;
|
||||
|
||||
if (!Call.isCalled(OpenFn))
|
||||
if (!OpenFn.matches(Call))
|
||||
return;
|
||||
|
||||
// Get the symbolic value corresponding to the file handle.
|
||||
@ -139,7 +139,7 @@ void SimpleStreamChecker::checkPreCall(const CallEvent &Call,
|
||||
if (!Call.isGlobalCFunction())
|
||||
return;
|
||||
|
||||
if (!Call.isCalled(CloseFn))
|
||||
if (!CloseFn.matches(Call))
|
||||
return;
|
||||
|
||||
// Get the symbolic value corresponding to the file handle.
|
||||
|
@ -286,7 +286,7 @@ bool SmartPtrModeling::evalCall(const CallEvent &Call,
|
||||
if (ModelSmartPtrDereference && isStdOstreamOperatorCall(Call))
|
||||
return handleOstreamOperator(Call, C);
|
||||
|
||||
if (Call.isCalled(StdSwapCall)) {
|
||||
if (StdSwapCall.matches(Call)) {
|
||||
// Check the first arg, if it is of std::unique_ptr type.
|
||||
assert(Call.getNumArgs() == 2 && "std::swap should have two arguments");
|
||||
const Expr *FirstArg = Call.getArgExpr(0);
|
||||
@ -295,8 +295,7 @@ bool SmartPtrModeling::evalCall(const CallEvent &Call,
|
||||
return handleSwap(State, Call.getArgSVal(0), Call.getArgSVal(1), C);
|
||||
}
|
||||
|
||||
if (Call.isCalled(StdMakeUniqueCall) ||
|
||||
Call.isCalled(StdMakeUniqueForOverwriteCall)) {
|
||||
if (matchesAny(Call, StdMakeUniqueCall, StdMakeUniqueForOverwriteCall)) {
|
||||
if (!ModelSmartPtrDereference)
|
||||
return false;
|
||||
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
|
||||
bool StringChecker::isCharToStringCtor(const CallEvent &Call,
|
||||
const ASTContext &ACtx) const {
|
||||
if (!Call.isCalled(TwoParamStdStringCtor))
|
||||
if (!TwoParamStdStringCtor.matches(Call))
|
||||
return false;
|
||||
const auto *FD = dyn_cast<FunctionDecl>(Call.getDecl());
|
||||
assert(FD);
|
||||
|
@ -127,15 +127,15 @@ void ValistChecker::checkPreCall(const CallEvent &Call,
|
||||
CheckerContext &C) const {
|
||||
if (!Call.isGlobalCFunction())
|
||||
return;
|
||||
if (Call.isCalled(VaStart))
|
||||
if (VaStart.matches(Call))
|
||||
checkVAListStartCall(Call, C, false);
|
||||
else if (Call.isCalled(VaCopy))
|
||||
else if (VaCopy.matches(Call))
|
||||
checkVAListStartCall(Call, C, true);
|
||||
else if (Call.isCalled(VaEnd))
|
||||
else if (VaEnd.matches(Call))
|
||||
checkVAListEndCall(Call, C);
|
||||
else {
|
||||
for (auto FuncInfo : VAListAccepters) {
|
||||
if (!Call.isCalled(FuncInfo.Func))
|
||||
if (!FuncInfo.Func.matches(Call))
|
||||
continue;
|
||||
bool Symbolic;
|
||||
const MemRegion *VAList =
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
|
||||
void PutenvWithAutoChecker::checkPostCall(const CallEvent &Call,
|
||||
CheckerContext &C) const {
|
||||
if (!Call.isCalled(Putenv))
|
||||
if (!Putenv.matches(Call))
|
||||
return;
|
||||
|
||||
SVal ArgV = Call.getArgSVal(0);
|
||||
|
@ -303,10 +303,6 @@ ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
|
||||
return PostImplicitCall(D, Loc, getLocationContext(), Tag);
|
||||
}
|
||||
|
||||
bool CallEvent::isCalled(const CallDescription &CD) const {
|
||||
return CD.matches(*this);
|
||||
}
|
||||
|
||||
SVal CallEvent::getArgSVal(unsigned Index) const {
|
||||
const Expr *ArgE = getArgExpr(Index);
|
||||
if (!ArgE)
|
||||
|
@ -22,7 +22,7 @@ class EvalCallBase : public Checker<eval::Call> {
|
||||
|
||||
public:
|
||||
bool evalCall(const CallEvent &Call, CheckerContext &C) const {
|
||||
return Call.isCalled(Foo);
|
||||
return Foo.matches(Call);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -86,17 +86,17 @@ class StatefulChecker : public Checker<check::PreCall> {
|
||||
|
||||
public:
|
||||
void checkPreCall(const CallEvent &Call, CheckerContext &C) const {
|
||||
if (Call.isCalled(CallDescription{"preventError", 0})) {
|
||||
if (CallDescription{"preventError", 0}.matches(Call)) {
|
||||
C.addTransition(C.getState()->set<ErrorPrevented>(true));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Call.isCalled(CallDescription{"allowError", 0})) {
|
||||
if (CallDescription{"allowError", 0}.matches(Call)) {
|
||||
C.addTransition(C.getState()->set<ErrorPrevented>(false));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Call.isCalled(CallDescription{"error", 0})) {
|
||||
if (CallDescription{"error", 0}.matches(Call)) {
|
||||
if (C.getState()->get<ErrorPrevented>())
|
||||
return;
|
||||
const ExplodedNode *N = C.generateErrorNode();
|
||||
|
Loading…
x
Reference in New Issue
Block a user