Skip to content

Commit 6fa0961

Browse files
authored
[analyzer] Use explicit call description mode in MIGChecker (#91331)
This commit explicitly specifies the matching mode (C library function, any non-method function, or C++ method) for the `CallDescription`s constructed in the checker `osx.MIG`. The code was simplified to use a `CallDescriptionMap` instead of a raw vector of pairs. This change won't cause major functional changes, but isn't NFC because it ensures that e.g. call descriptions for a non-method function won't accidentally match a method that has the same name. Separate commits have already performed this change in other checkers: - easy cases: e2f1cba, 6d64f8e - MallocChecker: d6d84b5 - iterator checkers: 06eedff - InvalidPtr checker: 024281d - apiModeling.llvm.ReturnValue: 97dd8e3 ... and follow-up commits will handle the remaining few checkers. My goal is to ensure that the call description mode is always explicitly specified and eliminate (or strongly restrict) the vague "may be either a method or a simple function" mode that's the current default.
1 parent 1922011 commit 6fa0961

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ class MIGChecker : public Checker<check::PostCall, check::PreStmt<ReturnStmt>,
4646
// additionally an argument of a MIG routine, the checker keeps track of that
4747
// information and issues a warning when an error is returned from the
4848
// respective routine.
49-
std::vector<std::pair<CallDescription, unsigned>> Deallocators = {
49+
CallDescriptionMap<unsigned> Deallocators = {
5050
#define CALL(required_args, deallocated_arg, ...) \
51-
{{{__VA_ARGS__}, required_args}, deallocated_arg}
52-
// E.g., if the checker sees a C function 'vm_deallocate' that is
53-
// defined on class 'IOUserClient' that has exactly 3 parameters, it knows
54-
// that argument #1 (starting from 0, i.e. the second argument) is going
55-
// to be consumed in the sense of the MIG consume-on-success convention.
51+
{{CDM::SimpleFunc, {__VA_ARGS__}, required_args}, deallocated_arg}
52+
// E.g., if the checker sees a C function 'vm_deallocate' that has
53+
// exactly 3 parameters, it knows that argument #1 (starting from 0, i.e.
54+
// the second argument) is going to be consumed in the sense of the MIG
55+
// consume-on-success convention.
5656
CALL(3, 1, "vm_deallocate"),
5757
CALL(3, 1, "mach_vm_deallocate"),
5858
CALL(2, 0, "mig_deallocate"),
@@ -78,6 +78,9 @@ class MIGChecker : public Checker<check::PostCall, check::PreStmt<ReturnStmt>,
7878
CALL(1, 0, "thread_inspect_deallocate"),
7979
CALL(1, 0, "upl_deallocate"),
8080
CALL(1, 0, "vm_map_deallocate"),
81+
#undef CALL
82+
#define CALL(required_args, deallocated_arg, ...) \
83+
{{CDM::CXXMethod, {__VA_ARGS__}, required_args}, deallocated_arg}
8184
// E.g., if the checker sees a method 'releaseAsyncReference64()' that is
8285
// defined on class 'IOUserClient' that takes exactly 1 argument, it knows
8386
// that the argument is going to be consumed in the sense of the MIG
@@ -87,7 +90,7 @@ class MIGChecker : public Checker<check::PostCall, check::PreStmt<ReturnStmt>,
8790
#undef CALL
8891
};
8992

90-
CallDescription OsRefRetain{{"os_ref_retain"}, 1};
93+
CallDescription OsRefRetain{CDM::SimpleFunc, {"os_ref_retain"}, 1};
9194

9295
void checkReturnAux(const ReturnStmt *RS, CheckerContext &C) const;
9396

@@ -198,15 +201,12 @@ void MIGChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const {
198201
if (!isInMIGCall(C))
199202
return;
200203

201-
auto I = llvm::find_if(Deallocators,
202-
[&](const std::pair<CallDescription, unsigned> &Item) {
203-
return Item.first.matches(Call);
204-
});
205-
if (I == Deallocators.end())
204+
const unsigned *ArgIdxPtr = Deallocators.lookup(Call);
205+
if (!ArgIdxPtr)
206206
return;
207207

208208
ProgramStateRef State = C.getState();
209-
unsigned ArgIdx = I->second;
209+
unsigned ArgIdx = *ArgIdxPtr;
210210
SVal Arg = Call.getArgSVal(ArgIdx);
211211
const ParmVarDecl *PVD = getOriginParam(Arg, C);
212212
if (!PVD || State->contains<RefCountedParameters>(PVD))

0 commit comments

Comments
 (0)