[PATCH] D119004: [NFC][analyzer] Allow CallDescriptions to be matched with CallExprs
Kristóf Umann via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 4 08:23:58 PST 2022
Szelethus created this revision.
Szelethus added reviewers: NoQ, steakhal, xazax.hun, martong, ASDenysPetrov.
Herald added subscribers: manas, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware.
Szelethus requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
As of now, we have two interfaces to for defining signatures: `StdLibraryFunctionsChecker::Signature` and `CallDescription`. An example for how `Signature`s are used can be seen here:
addToFunctionSummaryMap(
"isprint", Signature(ArgTypes{IntTy}, RetType{IntTy}),
Summary(EvalCallAsPure)
.Case({ArgumentCondition(0U, WithinRange, Range(32, 126)),
ReturnValueCondition(OutOfRange, SingleValue(0))})
.Case({ArgumentCondition(0U, OutOfRange, Range(32, 126)),
ReturnValueCondition(WithinRange, SingleValue(0))}));
The name of the function is searched for in translation unit's identifier table, then the `Signature` is matched against each decl `Decl` with the same name. Ideally, this yields a `FunctionDecl`, which is mapped to its `Summary`.
This works well for C functions, but doesn't support C++ at all.
`CallDescription` emerged with a strong emphasis on recognizing C++ functions. The common example brough up is `std::string`, which in some standard library implementations is actually called something like `std::__cxx11::basic_string`, but not in others. Matching this can be a nightmare for checker developers. For this reason, `CallDescription`s can be defined like this:
InnerPointerChecker()
: AppendFn({"std", "basic_string", "append"}),
AssignFn({"std", "basic_string", "assign"}),
AddressofFn({"std", "addressof"}),
ClearFn({"std", "basic_string", "clear"}),
CStrFn({"std", "basic_string", "c_str"}), DataFn({"std", "data"}, 1),
DataMemberFn({"std", "basic_string", "data"}),
EraseFn({"std", "basic_string", "erase"}),
InsertFn({"std", "basic_string", "insert"}),
PopBackFn({"std", "basic_string", "pop_back"}),
PushBackFn({"std", "basic_string", "push_back"}),
ReplaceFn({"std", "basic_string", "replace"}),
ReserveFn({"std", "basic_string", "reserve"}),
ResizeFn({"std", "basic_string", "resize"}),
ShrinkToFitFn({"std", "basic_string", "shrink_to_fit"}),
SwapFn({"std", "basic_string", "swap"}) {}
Any identifier which matches //at least// these identifiers are considered a match (which sometimes leads to incorrect matching, e.g. D81745 <https://reviews.llvm.org/D81745>).
`CallDescription`s are (usually) not used for digging up `FunctionDecl`s from the translation unit, but rather during symbolic execution to check in a pre/post call event whether the called function matches the `CallDescription`:
bool InnerPointerChecker::isInnerPointerAccessFunction(
const CallEvent &Call) const {
return matchesAny(Call, CStrFn, DataFn, DataMemberFn);
}
Most of the new checkers implementing pre/post condition checks on functions now use `CallDescriptionMap` or `CallDescriptionSet`. Its up to debate whether the newer `Signature` approach is better, but its not obvious, and converting from one to the other may be non-trivial as well.
---
Now, onto this patch. Since `CallDescription`s can only be matched against `CallEvent`s that are created during symbolic execution, it was not possible to use it in syntactic-only contexts. For example, even though `InnerPointerChecker` can check with its set of `CallDescription`s whether a function call is interested during analysis, its unable to check without hassle whether a non-analyzer piece of code also calls such a function.
The patch adds the ability to use `CallDescription`s in syntactic contexts as well. While we already have that in `Signature`, we still want to leverage the ability to use dynamic information when we have it (function pointers, for example). This could be done with `Signature` as well (`StdLibraryFunctionsChecker` does it), but it makes it even less of a drop-in replacement.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D119004
Files:
clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h
clang/lib/StaticAnalyzer/Core/CallDescription.cpp
clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D119004.405962.patch
Type: text/x-patch
Size: 9332 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220204/5cb551f7/attachment-0001.bin>
More information about the cfe-commits
mailing list