24using namespace errno_modeling;
28class ErrnoTesterChecker :
public Checker<eval::Call> {
73 {{{
"ErrnoTesterChecker_setErrno"}, 1}, &ErrnoTesterChecker::evalSetErrno},
74 {{{
"ErrnoTesterChecker_getErrno"}, 0}, &ErrnoTesterChecker::evalGetErrno},
75 {{{
"ErrnoTesterChecker_setErrnoIfError"}, 0},
76 &ErrnoTesterChecker::evalSetErrnoIfError},
77 {{{
"ErrnoTesterChecker_setErrnoIfErrorRange"}, 0},
78 &ErrnoTesterChecker::evalSetErrnoIfErrorRange},
79 {{{
"ErrnoTesterChecker_setErrnoCheckState"}, 0},
80 &ErrnoTesterChecker::evalSetErrnoCheckState}};
96 assert(ErrnoVal &&
"Errno value should be available.");
98 State->BindExpr(
Call.getOriginExpr(),
C.getLocationContext(), *ErrnoVal);
100 C.addTransition(State);
109 Call.getOriginExpr(),
C.getLocationContext(), SVB.
makeIntVal(0,
true));
113 Call.getOriginExpr(),
C.getLocationContext(), SVB.
makeIntVal(1,
true));
116 C.addTransition(StateSuccess);
117 C.addTransition(StateFailure);
126 Call.getOriginExpr(),
C.getLocationContext(), SVB.
makeIntVal(0,
true));
130 Call.getOriginExpr(),
C.getLocationContext(), SVB.
makeIntVal(1,
true));
132 nullptr,
Call.getOriginExpr(),
C.getLocationContext(),
C.blockCount());
133 StateFailure = StateFailure->assume(ErrnoVal,
true);
134 assert(StateFailure &&
"Failed to assume on an initial value.");
138 C.addTransition(StateSuccess);
139 C.addTransition(StateFailure);
148 Call.getOriginExpr(),
C.getLocationContext(), SVB.
makeIntVal(0,
true));
152 Call.getOriginExpr(),
C.getLocationContext(), SVB.
makeIntVal(1,
true));
156 Call.getOriginExpr(),
C.getLocationContext(), SVB.
makeIntVal(2,
true));
159 C.addTransition(StateSuccess,
161 "sets 'errno' to an unspecified value."));
162 C.addTransition(StateFailure1);
166 "should be checked to test for failure."));
171 const EvalFn *Fn = TestCalls.lookup(
Call);
174 return C.isDifferent();
183bool ento::shouldRegisterErrnoTesterChecker(
const CheckerManager &Mgr) {
An immutable map from CallDescriptions to arbitrary data.
Represents an abstract call to a function or method along a particular path.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
ProgramStateRef setErrnoValue(ProgramStateRef State, const LocationContext *LCtx, SVal Value, ErrnoCheckState EState)
Set value of 'errno' to any SVal, if possible.
ProgramStateRef setErrnoState(ProgramStateRef State, ErrnoCheckState EState)
Set the errno check state, do not modify the errno value.
const NoteTag * getErrnoNoteTag(CheckerContext &C, const std::string &Message)
Create a NoteTag that displays the message if the 'errno' memory region is marked as interesting,...
std::optional< SVal > getErrnoValue(ProgramStateRef State)
Returns the value of 'errno', if 'errno' was found in the AST.
@ MustBeChecked
Value of 'errno' should be checked to find out if a previous function call has failed.
@ Irrelevant
We do not know anything about 'errno'.
@ MustNotBeChecked
Value of 'errno' is not allowed to be read, it can contain an unspecified value.