forked from OSchip/llvm-project
[analyzer][StreamChecker] Using function description objects - NFC.
Summary: Have a description object for the stream functions that can store different aspects of a single stream operation. I plan to extend the structure with other members, for example pre-callback and index of the stream argument. Reviewers: Szelethus, baloghadamsoftware, NoQ, martong, Charusso, xazax.hun Reviewed By: Szelethus Subscribers: rnkovacs, xazax.hun, baloghadamsoftware, szepet, a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, dkrupp, gamesh411, Charusso, martong, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D75158
This commit is contained in:
parent
7a42babeb8
commit
b293a7217b
|
@ -49,6 +49,15 @@ struct StreamState {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StreamChecker;
|
||||||
|
|
||||||
|
using FnCheck = std::function<void(const StreamChecker *, const CallEvent &,
|
||||||
|
CheckerContext &)>;
|
||||||
|
|
||||||
|
struct FnDescription {
|
||||||
|
FnCheck EvalFn;
|
||||||
|
};
|
||||||
|
|
||||||
class StreamChecker : public Checker<eval::Call,
|
class StreamChecker : public Checker<eval::Call,
|
||||||
check::DeadSymbols > {
|
check::DeadSymbols > {
|
||||||
mutable std::unique_ptr<BuiltinBug> BT_nullfp, BT_illegalwhence,
|
mutable std::unique_ptr<BuiltinBug> BT_nullfp, BT_illegalwhence,
|
||||||
|
@ -59,35 +68,33 @@ public:
|
||||||
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
|
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using FnCheck = std::function<void(const StreamChecker *, const CallEvent &,
|
|
||||||
CheckerContext &)>;
|
|
||||||
|
|
||||||
CallDescriptionMap<FnCheck> Callbacks = {
|
CallDescriptionMap<FnDescription> FnDescriptions = {
|
||||||
{{"fopen"}, &StreamChecker::evalFopen},
|
{{"fopen"}, {&StreamChecker::evalFopen}},
|
||||||
{{"freopen", 3}, &StreamChecker::evalFreopen},
|
{{"freopen", 3}, {&StreamChecker::evalFreopen}},
|
||||||
{{"tmpfile"}, &StreamChecker::evalFopen},
|
{{"tmpfile"}, {&StreamChecker::evalFopen}},
|
||||||
{{"fclose", 1}, &StreamChecker::evalFclose},
|
{{"fclose", 1}, {&StreamChecker::evalFclose}},
|
||||||
{{"fread", 4},
|
{{"fread", 4},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 3)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 3)}},
|
||||||
{{"fwrite", 4},
|
{{"fwrite", 4},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 3)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 3)}},
|
||||||
{{"fseek", 3}, &StreamChecker::evalFseek},
|
{{"fseek", 3}, {&StreamChecker::evalFseek}},
|
||||||
{{"ftell", 1},
|
{{"ftell", 1},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}},
|
||||||
{{"rewind", 1},
|
{{"rewind", 1},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}},
|
||||||
{{"fgetpos", 2},
|
{{"fgetpos", 2},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}},
|
||||||
{{"fsetpos", 2},
|
{{"fsetpos", 2},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}},
|
||||||
{{"clearerr", 1},
|
{{"clearerr", 1},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}},
|
||||||
{{"feof", 1},
|
{{"feof", 1},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}},
|
||||||
{{"ferror", 1},
|
{{"ferror", 1},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}},
|
||||||
{{"fileno", 1},
|
{{"fileno", 1},
|
||||||
std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)},
|
{std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}},
|
||||||
};
|
};
|
||||||
|
|
||||||
void evalFopen(const CallEvent &Call, CheckerContext &C) const;
|
void evalFopen(const CallEvent &Call, CheckerContext &C) const;
|
||||||
|
@ -125,11 +132,11 @@ bool StreamChecker::evalCall(const CallEvent &Call, CheckerContext &C) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FnCheck *Callback = Callbacks.lookup(Call);
|
const FnDescription *Description = FnDescriptions.lookup(Call);
|
||||||
if (!Callback)
|
if (!Description)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
(*Callback)(this, Call, C);
|
(Description->EvalFn)(this, Call, C);
|
||||||
|
|
||||||
return C.isDifferent();
|
return C.isDifferent();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue