aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
diff options
context:
space:
mode:
authorGabor Marton <gabor.marton@ericsson.com>2020-03-31 17:41:10 +0200
committerGabor Marton <gabor.marton@ericsson.com>2020-05-29 16:24:26 +0200
commit41928c97b6a17264938fc765a6a0656d8b6e86ed (patch)
tree928adcc0ef1f68b666723721d8cc54d44b241ef6 /clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
parent205085d4ccf9c367ba70de9d8f0dd74d6f567c24 (diff)
downloadllvm-41928c97b6a17264938fc765a6a0656d8b6e86ed.zip
llvm-41928c97b6a17264938fc765a6a0656d8b6e86ed.tar.gz
llvm-41928c97b6a17264938fc765a6a0656d8b6e86ed.tar.bz2
[analyzer] ApiModeling: Add buffer size arg constraint with multiplier involved
Summary: Further develop the buffer size argumentum constraint so it can handle sizes that we can get by multiplying two variables. Reviewers: Szelethus, NoQ, steakhal Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, ASDenysPetrov, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77148
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp29
1 files changed, 26 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index f661f29..bd2f505 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -215,9 +215,16 @@ class StdLibraryFunctionsChecker
// Represents a buffer argument with an additional size argument.
// E.g. the first two arguments here:
// ctime_s(char *buffer, rsize_t bufsz, const time_t *time);
+ // Another example:
+ // size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+ // // Here, ptr is the buffer, and its minimum size is `size * nmemb`.
class BufferSizeConstraint : public ValueConstraint {
// The argument which holds the size of the buffer.
ArgNo SizeArgN;
+ // The argument which is a multiplier to size. This is set in case of
+ // `fread` like functions where the size is computed as a multiplication of
+ // two arguments.
+ llvm::Optional<ArgNo> SizeMultiplierArgN;
// The operator we use in apply. This is negated in negate().
BinaryOperator::Opcode Op = BO_LE;
@@ -225,17 +232,27 @@ class StdLibraryFunctionsChecker
BufferSizeConstraint(ArgNo Buffer, ArgNo BufSize)
: ValueConstraint(Buffer), SizeArgN(BufSize) {}
+ BufferSizeConstraint(ArgNo Buffer, ArgNo BufSize, ArgNo BufSizeMultiplier)
+ : ValueConstraint(Buffer), SizeArgN(BufSize),
+ SizeMultiplierArgN(BufSizeMultiplier) {}
+
ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
const Summary &Summary,
CheckerContext &C) const override {
+ SValBuilder &SvalBuilder = C.getSValBuilder();
// The buffer argument.
SVal BufV = getArgSVal(Call, getArgNo());
// The size argument.
SVal SizeV = getArgSVal(Call, SizeArgN);
+ // Multiply with another argument if given.
+ if (SizeMultiplierArgN) {
+ SVal SizeMulV = getArgSVal(Call, *SizeMultiplierArgN);
+ SizeV = SvalBuilder.evalBinOp(State, BO_Mul, SizeV, SizeMulV,
+ Summary.getArgType(SizeArgN));
+ }
// The dynamic size of the buffer argument, got from the analyzer engine.
SVal BufDynSize = getDynamicSizeWithOffset(State, BufV);
- SValBuilder &SvalBuilder = C.getSValBuilder();
SVal Feasible = SvalBuilder.evalBinOp(State, Op, SizeV, BufDynSize,
SvalBuilder.getContext().BoolTy);
if (auto F = Feasible.getAs<DefinedOrUnknownSVal>())
@@ -744,8 +761,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
IntRangeVector Ranges) {
return std::make_shared<RangeConstraint>(ArgN, Kind, Ranges);
};
- auto BufferSize = [](ArgNo BufArgN, ArgNo SizeArgN) {
- return std::make_shared<BufferSizeConstraint>(BufArgN, SizeArgN);
+ auto BufferSize = [](auto... Args) {
+ return std::make_shared<BufferSizeConstraint>(Args...);
};
struct {
auto operator()(RangeKind Kind, IntRangeVector Ranges) {
@@ -988,6 +1005,12 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
EvalCallAsPure)
.ArgConstraint(
BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1))));
+ addToFunctionSummaryMap(
+ "__buf_size_arg_constraint_mul",
+ Summary(ArgTypes{ConstVoidPtrTy, SizeTy, SizeTy}, RetType{IntTy},
+ EvalCallAsPure)
+ .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1),
+ /*BufSizeMultiplier=*/ArgNo(2))));
}
}