Skip to content

Commit 52a460f

Browse files
authored
[analyzer] Refactor CallDescription match mode (NFC) (#83432)
The class `CallDescription` is used to define patterns that are used for matching `CallEvent`s. For example, a `CallDescription{{"std", "find_if"}, 3}` matches a call to `std::find_if` with 3 arguments. However, these patterns are somewhat fuzzy, so this pattern could also match something like `std::__1::find_if` (with an additional namespace layer), or, unfortunately, a `CallDescription` for the well-known function `free()` can match a C++ method named `free()`: #81597 To prevent this kind of ambiguity this commit introduces the enum `CallDescription::Mode` which can limit the pattern matching to non-method function calls (or method calls etc.). After this NFC change, one or more follow-up commits will apply the right pattern matching modes in the ~30 checkers that use `CallDescription`s. Note that `CallDescription` previously had a `Flags` field which had only two supported values: - `CDF_None` was the default "match anything" mode, - `CDF_MaybeBuiltin` was a "match only C library functions and accept some inexact matches" mode. This commit preserves `CDF_MaybeBuiltin` under the more descriptive name `CallDescription::Mode::CLibrary` (or `CDM::CLibrary`). Instead of this "Flags" model I'm switching to a plain enumeration becasue I don't think that there is a natural usecase to combine the different matching modes. (Except for the default "match anything" mode, which is currently kept for compatibility, but will be phased out in the follow-up commits.)
1 parent bbeb946 commit 52a460f

File tree

6 files changed

+138
-101
lines changed

6 files changed

+138
-101
lines changed

clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,48 @@ class IdentifierInfo;
2727

2828
namespace clang {
2929
namespace ento {
30-
31-
enum CallDescriptionFlags : unsigned {
32-
CDF_None = 0,
33-
34-
/// Describes a C standard function that is sometimes implemented as a macro
35-
/// that expands to a compiler builtin with some __builtin prefix.
36-
/// The builtin may as well have a few extra arguments on top of the requested
37-
/// number of arguments.
38-
CDF_MaybeBuiltin = 1 << 0,
39-
};
40-
41-
/// This class represents a description of a function call using the number of
42-
/// arguments and the name of the function.
30+
/// A `CallDescription` is a pattern that can be used to _match_ calls
31+
/// based on the qualified name and the argument/parameter counts.
4332
class CallDescription {
33+
public:
34+
enum class Mode {
35+
/// Match calls to functions from the C standard library. On some platforms
36+
/// some functions may be implemented as macros that expand to calls to
37+
/// built-in variants of the given functions, so in this mode we use some
38+
/// heuristics to recognize these implementation-defined variants:
39+
/// - We also accept calls where the name is derived from the specified
40+
/// name by adding "__builtin" or similar prefixes/suffixes.
41+
/// - We also accept calls where the number of arguments or parameters is
42+
/// greater than the specified value.
43+
/// For the exact heuristics, see CheckerContext::isCLibraryFunction().
44+
/// Note that functions whose declaration context is not a TU (e.g.
45+
/// methods, functions in namespaces) are not accepted as C library
46+
/// functions.
47+
/// FIXME: If I understand it correctly, this discards calls where C++ code
48+
/// refers a C library function through the namespace `std::` via headers
49+
/// like <cstdlib>.
50+
CLibrary,
51+
52+
/// Matches "simple" functions that are not methods. (Static methods are
53+
/// methods.)
54+
SimpleFunc,
55+
56+
/// Matches a C++ method (may be static, may be virtual, may be an
57+
/// overloaded operator, a constructor or a destructor).
58+
CXXMethod,
59+
60+
/// Match any CallEvent that is not an ObjCMethodCall.
61+
/// FIXME: Previously this was the default behavior of CallDescription, but
62+
/// its use should be replaced by a more specific mode almost everywhere.
63+
Unspecified,
64+
65+
/// FIXME: Add support for ObjCMethodCall events (I'm not adding it because
66+
/// I'm not familiar with Objective-C). Note that currently an early return
67+
/// in `bool matches(const CallEvent &Call) const;` discards all
68+
/// Objective-C method calls.
69+
};
70+
71+
private:
4472
friend class CallEvent;
4573
using MaybeCount = std::optional<unsigned>;
4674

@@ -50,20 +78,26 @@ class CallDescription {
5078
std::vector<std::string> QualifiedName;
5179
MaybeCount RequiredArgs;
5280
MaybeCount RequiredParams;
53-
int Flags;
81+
Mode MatchAs;
5482

5583
public:
5684
/// Constructs a CallDescription object.
5785
///
86+
/// @param MatchAs Specifies the kind of the call that should be matched.
87+
///
5888
/// @param QualifiedName The list of the name qualifiers of the function that
5989
/// will be matched. The user is allowed to skip any of the qualifiers.
6090
/// For example, {"std", "basic_string", "c_str"} would match both
6191
/// std::basic_string<...>::c_str() and std::__1::basic_string<...>::c_str().
6292
///
63-
/// @param RequiredArgs The number of arguments that is expected to match a
64-
/// call. Omit this parameter to match every occurrence of call with a given
65-
/// name regardless the number of arguments.
66-
CallDescription(CallDescriptionFlags Flags, ArrayRef<StringRef> QualifiedName,
93+
/// @param RequiredArgs The expected number of arguments that are passed to
94+
/// the function. Omit this parameter (or pass std::nullopt) to match every
95+
/// occurrence without checking the argument count in the call.
96+
///
97+
/// @param RequiredParams The expected number of parameters in the function
98+
/// definition that is called. Omit this parameter to match every occurrence
99+
/// without checking the parameter count in the definition.
100+
CallDescription(Mode MatchAs, ArrayRef<StringRef> QualifiedName,
67101
MaybeCount RequiredArgs = std::nullopt,
68102
MaybeCount RequiredParams = std::nullopt);
69103

@@ -222,6 +256,10 @@ template <typename T> class CallDescriptionMap {
222256
}
223257
};
224258

259+
/// Enumerators of this enum class are used to construct CallDescription
260+
/// objects; in that context the fully qualified name is needlessly verbose.
261+
using CDM = CallDescription::Mode;
262+
225263
/// An immutable set of CallDescriptions.
226264
/// Checkers can efficiently decide if a given CallEvent matches any
227265
/// CallDescription in the set.

clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -124,48 +124,47 @@ class CStringChecker : public Checker< eval::Call,
124124
const CallEvent &)>;
125125

126126
CallDescriptionMap<FnCheck> Callbacks = {
127-
{{CDF_MaybeBuiltin, {"memcpy"}, 3},
127+
{{CDM::CLibrary, {"memcpy"}, 3},
128128
std::bind(&CStringChecker::evalMemcpy, _1, _2, _3, CK_Regular)},
129-
{{CDF_MaybeBuiltin, {"wmemcpy"}, 3},
129+
{{CDM::CLibrary, {"wmemcpy"}, 3},
130130
std::bind(&CStringChecker::evalMemcpy, _1, _2, _3, CK_Wide)},
131-
{{CDF_MaybeBuiltin, {"mempcpy"}, 3},
131+
{{CDM::CLibrary, {"mempcpy"}, 3},
132132
std::bind(&CStringChecker::evalMempcpy, _1, _2, _3, CK_Regular)},
133-
{{CDF_None, {"wmempcpy"}, 3},
133+
{{CDM::Unspecified, {"wmempcpy"}, 3},
134134
std::bind(&CStringChecker::evalMempcpy, _1, _2, _3, CK_Wide)},
135-
{{CDF_MaybeBuiltin, {"memcmp"}, 3},
135+
{{CDM::CLibrary, {"memcmp"}, 3},
136136
std::bind(&CStringChecker::evalMemcmp, _1, _2, _3, CK_Regular)},
137-
{{CDF_MaybeBuiltin, {"wmemcmp"}, 3},
137+
{{CDM::CLibrary, {"wmemcmp"}, 3},
138138
std::bind(&CStringChecker::evalMemcmp, _1, _2, _3, CK_Wide)},
139-
{{CDF_MaybeBuiltin, {"memmove"}, 3},
139+
{{CDM::CLibrary, {"memmove"}, 3},
140140
std::bind(&CStringChecker::evalMemmove, _1, _2, _3, CK_Regular)},
141-
{{CDF_MaybeBuiltin, {"wmemmove"}, 3},
141+
{{CDM::CLibrary, {"wmemmove"}, 3},
142142
std::bind(&CStringChecker::evalMemmove, _1, _2, _3, CK_Wide)},
143-
{{CDF_MaybeBuiltin, {"memset"}, 3}, &CStringChecker::evalMemset},
144-
{{CDF_MaybeBuiltin, {"explicit_memset"}, 3}, &CStringChecker::evalMemset},
145-
{{CDF_MaybeBuiltin, {"strcpy"}, 2}, &CStringChecker::evalStrcpy},
146-
{{CDF_MaybeBuiltin, {"strncpy"}, 3}, &CStringChecker::evalStrncpy},
147-
{{CDF_MaybeBuiltin, {"stpcpy"}, 2}, &CStringChecker::evalStpcpy},
148-
{{CDF_MaybeBuiltin, {"strlcpy"}, 3}, &CStringChecker::evalStrlcpy},
149-
{{CDF_MaybeBuiltin, {"strcat"}, 2}, &CStringChecker::evalStrcat},
150-
{{CDF_MaybeBuiltin, {"strncat"}, 3}, &CStringChecker::evalStrncat},
151-
{{CDF_MaybeBuiltin, {"strlcat"}, 3}, &CStringChecker::evalStrlcat},
152-
{{CDF_MaybeBuiltin, {"strlen"}, 1}, &CStringChecker::evalstrLength},
153-
{{CDF_MaybeBuiltin, {"wcslen"}, 1}, &CStringChecker::evalstrLength},
154-
{{CDF_MaybeBuiltin, {"strnlen"}, 2}, &CStringChecker::evalstrnLength},
155-
{{CDF_MaybeBuiltin, {"wcsnlen"}, 2}, &CStringChecker::evalstrnLength},
156-
{{CDF_MaybeBuiltin, {"strcmp"}, 2}, &CStringChecker::evalStrcmp},
157-
{{CDF_MaybeBuiltin, {"strncmp"}, 3}, &CStringChecker::evalStrncmp},
158-
{{CDF_MaybeBuiltin, {"strcasecmp"}, 2}, &CStringChecker::evalStrcasecmp},
159-
{{CDF_MaybeBuiltin, {"strncasecmp"}, 3},
160-
&CStringChecker::evalStrncasecmp},
161-
{{CDF_MaybeBuiltin, {"strsep"}, 2}, &CStringChecker::evalStrsep},
162-
{{CDF_MaybeBuiltin, {"bcopy"}, 3}, &CStringChecker::evalBcopy},
163-
{{CDF_MaybeBuiltin, {"bcmp"}, 3},
143+
{{CDM::CLibrary, {"memset"}, 3}, &CStringChecker::evalMemset},
144+
{{CDM::CLibrary, {"explicit_memset"}, 3}, &CStringChecker::evalMemset},
145+
{{CDM::CLibrary, {"strcpy"}, 2}, &CStringChecker::evalStrcpy},
146+
{{CDM::CLibrary, {"strncpy"}, 3}, &CStringChecker::evalStrncpy},
147+
{{CDM::CLibrary, {"stpcpy"}, 2}, &CStringChecker::evalStpcpy},
148+
{{CDM::CLibrary, {"strlcpy"}, 3}, &CStringChecker::evalStrlcpy},
149+
{{CDM::CLibrary, {"strcat"}, 2}, &CStringChecker::evalStrcat},
150+
{{CDM::CLibrary, {"strncat"}, 3}, &CStringChecker::evalStrncat},
151+
{{CDM::CLibrary, {"strlcat"}, 3}, &CStringChecker::evalStrlcat},
152+
{{CDM::CLibrary, {"strlen"}, 1}, &CStringChecker::evalstrLength},
153+
{{CDM::CLibrary, {"wcslen"}, 1}, &CStringChecker::evalstrLength},
154+
{{CDM::CLibrary, {"strnlen"}, 2}, &CStringChecker::evalstrnLength},
155+
{{CDM::CLibrary, {"wcsnlen"}, 2}, &CStringChecker::evalstrnLength},
156+
{{CDM::CLibrary, {"strcmp"}, 2}, &CStringChecker::evalStrcmp},
157+
{{CDM::CLibrary, {"strncmp"}, 3}, &CStringChecker::evalStrncmp},
158+
{{CDM::CLibrary, {"strcasecmp"}, 2}, &CStringChecker::evalStrcasecmp},
159+
{{CDM::CLibrary, {"strncasecmp"}, 3}, &CStringChecker::evalStrncasecmp},
160+
{{CDM::CLibrary, {"strsep"}, 2}, &CStringChecker::evalStrsep},
161+
{{CDM::CLibrary, {"bcopy"}, 3}, &CStringChecker::evalBcopy},
162+
{{CDM::CLibrary, {"bcmp"}, 3},
164163
std::bind(&CStringChecker::evalMemcmp, _1, _2, _3, CK_Regular)},
165-
{{CDF_MaybeBuiltin, {"bzero"}, 2}, &CStringChecker::evalBzero},
166-
{{CDF_MaybeBuiltin, {"explicit_bzero"}, 2}, &CStringChecker::evalBzero},
167-
{{CDF_MaybeBuiltin, {"sprintf"}, 2}, &CStringChecker::evalSprintf},
168-
{{CDF_MaybeBuiltin, {"snprintf"}, 2}, &CStringChecker::evalSnprintf},
164+
{{CDM::CLibrary, {"bzero"}, 2}, &CStringChecker::evalBzero},
165+
{{CDM::CLibrary, {"explicit_bzero"}, 2}, &CStringChecker::evalBzero},
166+
{{CDM::CLibrary, {"sprintf"}, 2}, &CStringChecker::evalSprintf},
167+
{{CDM::CLibrary, {"snprintf"}, 2}, &CStringChecker::evalSnprintf},
169168
};
170169

171170
// These require a bit of special handling.

clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -718,28 +718,24 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {
718718
{{{"isupper"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
719719
{{{"isxdigit"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
720720

721-
{{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrncat)}},
721+
{{CDM::CLibrary, {BI.getName(Builtin::BIstrncat)}},
722722
TR::Prop({{1, 2}}, {{0, ReturnValueIndex}})},
723-
{{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrlcpy)}},
723+
{{CDM::CLibrary, {BI.getName(Builtin::BIstrlcpy)}},
724724
TR::Prop({{1, 2}}, {{0}})},
725-
{{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrlcat)}},
725+
{{CDM::CLibrary, {BI.getName(Builtin::BIstrlcat)}},
726726
TR::Prop({{1, 2}}, {{0}})},
727-
{{CDF_MaybeBuiltin, {{"snprintf"}}},
727+
{{CDM::CLibrary, {{"snprintf"}}},
728728
TR::Prop({{1}, 3}, {{0, ReturnValueIndex}})},
729-
{{CDF_MaybeBuiltin, {{"sprintf"}}},
729+
{{CDM::CLibrary, {{"sprintf"}}},
730730
TR::Prop({{1}, 2}, {{0, ReturnValueIndex}})},
731-
{{CDF_MaybeBuiltin, {{"strcpy"}}},
731+
{{CDM::CLibrary, {{"strcpy"}}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
732+
{{CDM::CLibrary, {{"stpcpy"}}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
733+
{{CDM::CLibrary, {{"strcat"}}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
734+
{{CDM::CLibrary, {{"wcsncat"}}},
732735
TR::Prop({{1}}, {{0, ReturnValueIndex}})},
733-
{{CDF_MaybeBuiltin, {{"stpcpy"}}},
734-
TR::Prop({{1}}, {{0, ReturnValueIndex}})},
735-
{{CDF_MaybeBuiltin, {{"strcat"}}},
736-
TR::Prop({{1}}, {{0, ReturnValueIndex}})},
737-
{{CDF_MaybeBuiltin, {{"wcsncat"}}},
738-
TR::Prop({{1}}, {{0, ReturnValueIndex}})},
739-
{{CDF_MaybeBuiltin, {{"strdup"}}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
740-
{{CDF_MaybeBuiltin, {{"strdupa"}}},
741-
TR::Prop({{0}}, {{ReturnValueIndex}})},
742-
{{CDF_MaybeBuiltin, {{"wcsdup"}}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
736+
{{CDM::CLibrary, {{"strdup"}}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
737+
{{CDM::CLibrary, {{"strdupa"}}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
738+
{{CDM::CLibrary, {{"wcsdup"}}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
743739

744740
// Sinks
745741
{{{"system"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
@@ -753,31 +749,29 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {
753749
{{{"execvp"}}, TR::Sink({{0, 1}}, MsgSanitizeSystemArgs)},
754750
{{{"execvpe"}}, TR::Sink({{0, 1, 2}}, MsgSanitizeSystemArgs)},
755751
{{{"dlopen"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
756-
{{CDF_MaybeBuiltin, {{"malloc"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
757-
{{CDF_MaybeBuiltin, {{"calloc"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
758-
{{CDF_MaybeBuiltin, {{"alloca"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
759-
{{CDF_MaybeBuiltin, {{"memccpy"}}},
760-
TR::Sink({{3}}, MsgTaintedBufferSize)},
761-
{{CDF_MaybeBuiltin, {{"realloc"}}},
762-
TR::Sink({{1}}, MsgTaintedBufferSize)},
752+
{{CDM::CLibrary, {{"malloc"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
753+
{{CDM::CLibrary, {{"calloc"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
754+
{{CDM::CLibrary, {{"alloca"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
755+
{{CDM::CLibrary, {{"memccpy"}}}, TR::Sink({{3}}, MsgTaintedBufferSize)},
756+
{{CDM::CLibrary, {{"realloc"}}}, TR::Sink({{1}}, MsgTaintedBufferSize)},
763757
{{{{"setproctitle"}}}, TR::Sink({{0}, 1}, MsgUncontrolledFormatString)},
764758
{{{{"setproctitle_fast"}}},
765759
TR::Sink({{0}, 1}, MsgUncontrolledFormatString)},
766760

767761
// SinkProps
768-
{{CDF_MaybeBuiltin, BI.getName(Builtin::BImemcpy)},
762+
{{CDM::CLibrary, BI.getName(Builtin::BImemcpy)},
769763
TR::SinkProp({{2}}, {{1, 2}}, {{0, ReturnValueIndex}},
770764
MsgTaintedBufferSize)},
771-
{{CDF_MaybeBuiltin, {BI.getName(Builtin::BImemmove)}},
765+
{{CDM::CLibrary, {BI.getName(Builtin::BImemmove)}},
772766
TR::SinkProp({{2}}, {{1, 2}}, {{0, ReturnValueIndex}},
773767
MsgTaintedBufferSize)},
774-
{{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrncpy)}},
768+
{{CDM::CLibrary, {BI.getName(Builtin::BIstrncpy)}},
775769
TR::SinkProp({{2}}, {{1, 2}}, {{0, ReturnValueIndex}},
776770
MsgTaintedBufferSize)},
777-
{{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrndup)}},
771+
{{CDM::CLibrary, {BI.getName(Builtin::BIstrndup)}},
778772
TR::SinkProp({{1}}, {{0, 1}}, {{ReturnValueIndex}},
779773
MsgTaintedBufferSize)},
780-
{{CDF_MaybeBuiltin, {{"bcopy"}}},
774+
{{CDM::CLibrary, {{"bcopy"}}},
781775
TR::SinkProp({{2}}, {{0, 2}}, {{1}}, MsgTaintedBufferSize)}};
782776

783777
// `getenv` returns taint only in untrusted environments.

clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,13 +410,13 @@ class MallocChecker
410410
{{{"malloc"}, 3}, &MallocChecker::checkKernelMalloc},
411411
{{{"calloc"}, 2}, &MallocChecker::checkCalloc},
412412
{{{"valloc"}, 1}, &MallocChecker::checkBasicAlloc},
413-
{{CDF_MaybeBuiltin, {"strndup"}, 2}, &MallocChecker::checkStrdup},
414-
{{CDF_MaybeBuiltin, {"strdup"}, 1}, &MallocChecker::checkStrdup},
413+
{{CDM::CLibrary, {"strndup"}, 2}, &MallocChecker::checkStrdup},
414+
{{CDM::CLibrary, {"strdup"}, 1}, &MallocChecker::checkStrdup},
415415
{{{"_strdup"}, 1}, &MallocChecker::checkStrdup},
416416
{{{"kmalloc"}, 2}, &MallocChecker::checkKernelMalloc},
417417
{{{"if_nameindex"}, 1}, &MallocChecker::checkIfNameIndex},
418-
{{CDF_MaybeBuiltin, {"wcsdup"}, 1}, &MallocChecker::checkStrdup},
419-
{{CDF_MaybeBuiltin, {"_wcsdup"}, 1}, &MallocChecker::checkStrdup},
418+
{{CDM::CLibrary, {"wcsdup"}, 1}, &MallocChecker::checkStrdup},
419+
{{CDM::CLibrary, {"_wcsdup"}, 1}, &MallocChecker::checkStrdup},
420420
{{{"g_malloc"}, 1}, &MallocChecker::checkBasicAlloc},
421421
{{{"g_malloc0"}, 1}, &MallocChecker::checkGMalloc0},
422422
{{{"g_try_malloc"}, 1}, &MallocChecker::checkBasicAlloc},

clang/lib/StaticAnalyzer/Core/CallDescription.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ static MaybeCount readRequiredParams(MaybeCount RequiredArgs,
3535
return std::nullopt;
3636
}
3737

38-
ento::CallDescription::CallDescription(CallDescriptionFlags Flags,
38+
ento::CallDescription::CallDescription(Mode MatchAs,
3939
ArrayRef<StringRef> QualifiedName,
4040
MaybeCount RequiredArgs /*= None*/,
4141
MaybeCount RequiredParams /*= None*/)
4242
: RequiredArgs(RequiredArgs),
4343
RequiredParams(readRequiredParams(RequiredArgs, RequiredParams)),
44-
Flags(Flags) {
44+
MatchAs(MatchAs) {
4545
assert(!QualifiedName.empty());
4646
this->QualifiedName.reserve(QualifiedName.size());
4747
llvm::transform(QualifiedName, std::back_inserter(this->QualifiedName),
@@ -52,7 +52,8 @@ ento::CallDescription::CallDescription(CallDescriptionFlags Flags,
5252
ento::CallDescription::CallDescription(ArrayRef<StringRef> QualifiedName,
5353
MaybeCount RequiredArgs /*= None*/,
5454
MaybeCount RequiredParams /*= None*/)
55-
: CallDescription(CDF_None, QualifiedName, RequiredArgs, RequiredParams) {}
55+
: CallDescription(Mode::Unspecified, QualifiedName, RequiredArgs,
56+
RequiredParams) {}
5657

5758
bool ento::CallDescription::matches(const CallEvent &Call) const {
5859
// FIXME: Add ObjC Message support.
@@ -74,14 +75,20 @@ bool ento::CallDescription::matchesAsWritten(const CallExpr &CE) const {
7475
return matchesImpl(FD, CE.getNumArgs(), FD->param_size());
7576
}
7677

77-
bool ento::CallDescription::matchesImpl(const FunctionDecl *Callee,
78-
size_t ArgCount,
78+
bool ento::CallDescription::matchesImpl(const FunctionDecl *FD, size_t ArgCount,
7979
size_t ParamCount) const {
80-
const auto *FD = Callee;
8180
if (!FD)
8281
return false;
8382

84-
if (Flags & CDF_MaybeBuiltin) {
83+
const bool isMethod = isa<CXXMethodDecl>(FD);
84+
85+
if (MatchAs == Mode::SimpleFunc && isMethod)
86+
return false;
87+
88+
if (MatchAs == Mode::CXXMethod && !isMethod)
89+
return false;
90+
91+
if (MatchAs == Mode::CLibrary) {
8592
return CheckerContext::isCLibraryFunction(FD, getFunctionName()) &&
8693
(!RequiredArgs || *RequiredArgs <= ArgCount) &&
8794
(!RequiredParams || *RequiredParams <= ParamCount);

0 commit comments

Comments
 (0)