diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h @@ -40,12 +40,14 @@ /// arguments and the name of the function. class CallDescription { friend class CallEvent; + using MaybeUInt = Optional; + mutable Optional II; // The list of the qualified names used to identify the specified CallEvent, // e.g. "{a, b}" represent the qualified names, like "a::b". std::vector QualifiedName; - Optional RequiredArgs; - Optional RequiredParams; + MaybeUInt RequiredArgs; + MaybeUInt RequiredParams; int Flags; public: @@ -60,13 +62,13 @@ /// call. Omit this parameter to match every occurrence of call with a given /// name regardless the number of arguments. CallDescription(int Flags, ArrayRef QualifiedName, - Optional RequiredArgs = None, - Optional RequiredParams = None); + MaybeUInt RequiredArgs = None, + MaybeUInt RequiredParams = None); /// Construct a CallDescription with default flags. CallDescription(ArrayRef QualifiedName, - Optional RequiredArgs = None, - Optional RequiredParams = None); + MaybeUInt RequiredArgs = None, + MaybeUInt RequiredParams = None); CallDescription(std::nullptr_t) = delete; diff --git a/clang/lib/StaticAnalyzer/Core/CallDescription.cpp b/clang/lib/StaticAnalyzer/Core/CallDescription.cpp --- a/clang/lib/StaticAnalyzer/Core/CallDescription.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallDescription.cpp @@ -22,20 +22,22 @@ using namespace llvm; using namespace clang; +using MaybeUInt = Optional; + // A constructor helper. -static Optional readRequiredParams(Optional RequiredArgs, - Optional RequiredParams) { +static MaybeUInt readRequiredParams(MaybeUInt RequiredArgs, + MaybeUInt RequiredParams) { if (RequiredParams) return RequiredParams; if (RequiredArgs) - return static_cast(*RequiredArgs); + return RequiredArgs; return None; } -ento::CallDescription::CallDescription( - int Flags, ArrayRef QualifiedName, - Optional RequiredArgs /*= None*/, - Optional RequiredParams /*= None*/) +ento::CallDescription::CallDescription(int Flags, + ArrayRef QualifiedName, + MaybeUInt RequiredArgs /*= None*/, + MaybeUInt RequiredParams /*= None*/) : RequiredArgs(RequiredArgs), RequiredParams(readRequiredParams(RequiredArgs, RequiredParams)), Flags(Flags) { @@ -45,10 +47,9 @@ } /// Construct a CallDescription with default flags. -ento::CallDescription::CallDescription( - ArrayRef QualifiedName, - Optional RequiredArgs /*= None*/, - Optional RequiredParams /*= None*/) +ento::CallDescription::CallDescription(ArrayRef QualifiedName, + MaybeUInt RequiredArgs /*= None*/, + MaybeUInt RequiredParams /*= None*/) : CallDescription(0, QualifiedName, RequiredArgs, RequiredParams) {} bool ento::CallDescription::matches(const CallEvent &Call) const { @@ -62,8 +63,8 @@ if (Flags & CDF_MaybeBuiltin) { return CheckerContext::isCLibraryFunction(FD, getFunctionName()) && - (!RequiredArgs || RequiredArgs <= Call.getNumArgs()) && - (!RequiredParams || RequiredParams <= Call.parameters().size()); + (!RequiredArgs || *RequiredArgs <= Call.getNumArgs()) && + (!RequiredParams || *RequiredParams <= Call.parameters().size()); } if (!II.hasValue()) { @@ -87,9 +88,9 @@ const auto ExactMatchArgAndParamCounts = [](const CallEvent &Call, const CallDescription &CD) -> bool { const bool ArgsMatch = - !CD.RequiredArgs || CD.RequiredArgs == Call.getNumArgs(); + !CD.RequiredArgs || *CD.RequiredArgs == Call.getNumArgs(); const bool ParamsMatch = - !CD.RequiredParams || CD.RequiredParams == Call.parameters().size(); + !CD.RequiredParams || *CD.RequiredParams == Call.parameters().size(); return ArgsMatch && ParamsMatch; };