52#include "llvm/ADT/STLExtras.h"
53#include "llvm/ADT/SmallString.h"
54#include "llvm/ADT/StringExtras.h"
55#include "llvm/Support/FormatVariadic.h"
64class StdLibraryFunctionsChecker
65 :
public Checker<check::PreCall, check::PostCall, eval::Call> {
71 enum InvalidationKind {
80 enum RangeKind { OutOfRange, WithinRange };
82 static RangeKind negateKind(RangeKind K) {
89 llvm_unreachable(
"Unknown range kind");
98 typedef std::vector<std::pair<RangeInt, RangeInt>> IntRangeVector;
103 typedef uint32_t ArgNo;
105 static const ArgNo
Ret;
109 static void printArgDesc(ArgNo, llvm::raw_ostream &Out);
117 static void appendInsideRangeDesc(llvm::APSInt RMin, llvm::APSInt RMax,
119 llvm::raw_ostream &Out);
122 static void appendOutOfRangeDesc(llvm::APSInt RMin, llvm::APSInt RMax,
124 llvm::raw_ostream &Out);
126 class ValueConstraint;
135 using ValueConstraintPtr = std::shared_ptr<ValueConstraint>;
147 class ValueConstraint {
149 ValueConstraint(ArgNo ArgN) : ArgN(ArgN) {}
150 virtual ~ValueConstraint() {}
155 const Summary &Summary,
160 enum DescriptionKind {
178 llvm::raw_ostream &Out)
const {
183 "Description not implemented for summary case constraints");
200 const Summary &Summary,
201 llvm::raw_ostream &Out)
const {
202 if (
auto N = getArgSVal(
Call, getArgNo()).getAs<NonLoc>()) {
203 if (
const llvm::APSInt *Int = N->getAsInteger()) {
217 virtual std::vector<ArgNo> getArgsToTrack()
const {
return {ArgN}; }
220 virtual ValueConstraintPtr negate()
const {
221 llvm_unreachable(
"Not implemented");
231 assert(ValidArg &&
"Arg out of range!");
235 return checkSpecificValidity(FD);
239 ArgNo getArgNo()
const {
return ArgN; }
250 virtual bool checkSpecificValidity(
const FunctionDecl *FD)
const {
265 class RangeConstraint :
public ValueConstraint {
272 IntRangeVector Ranges;
277 StringRef Description;
280 RangeConstraint(ArgNo ArgN, RangeKind Kind,
const IntRangeVector &Ranges,
282 : ValueConstraint(ArgN),
Kind(
Kind), Ranges(Ranges), Description(Desc) {
285 const IntRangeVector &getRanges()
const {
return Ranges; }
288 const Summary &Summary,
293 llvm::raw_ostream &Out)
const override;
296 const Summary &Summary,
297 llvm::raw_ostream &Out)
const override;
299 ValueConstraintPtr negate()
const override {
300 RangeConstraint Tmp(*
this);
301 Tmp.Kind = negateKind(Kind);
302 return std::make_shared<RangeConstraint>(Tmp);
306 bool checkSpecificValidity(
const FunctionDecl *FD)
const override {
307 const bool ValidArg =
310 "This constraint should be applied on an integral type");
319 using RangeApplyFunction =
320 std::function<
bool(
const llvm::APSInt &Min,
const llvm::APSInt &Max)>;
325 const RangeApplyFunction &F)
const;
337 const RangeApplyFunction &F)
const;
341 const RangeApplyFunction &F)
const {
344 applyOnOutOfRange(BVF, ArgT, F);
347 applyOnWithinRange(BVF, ArgT, F);
354 class ComparisonConstraint :
public ValueConstraint {
361 : ValueConstraint(ArgN),
Opcode(
Opcode), OtherArgN(OtherArgN) {}
362 ArgNo getOtherArgNo()
const {
return OtherArgN; }
365 const Summary &Summary,
370 class NotNullConstraint :
public ValueConstraint {
371 using ValueConstraint::ValueConstraint;
373 bool CannotBeNull =
true;
376 NotNullConstraint(ArgNo ArgN,
bool CannotBeNull =
true)
377 : ValueConstraint(ArgN), CannotBeNull(CannotBeNull) {}
380 const Summary &Summary,
385 llvm::raw_ostream &Out)
const override;
388 const Summary &Summary,
389 llvm::raw_ostream &Out)
const override;
391 ValueConstraintPtr negate()
const override {
392 NotNullConstraint Tmp(*
this);
393 Tmp.CannotBeNull = !this->CannotBeNull;
394 return std::make_shared<NotNullConstraint>(Tmp);
398 bool checkSpecificValidity(
const FunctionDecl *FD)
const override {
399 const bool ValidArg = getArgType(FD, ArgN)->isPointerType();
401 "This constraint should be applied only on a pointer type");
412 class NotNullBufferConstraint :
public ValueConstraint {
413 using ValueConstraint::ValueConstraint;
415 std::optional<ArgNo> SizeArg2N;
417 bool CannotBeNull =
true;
420 NotNullBufferConstraint(ArgNo ArgN, ArgNo SizeArg1N,
421 std::optional<ArgNo> SizeArg2N,
422 bool CannotBeNull =
true)
423 : ValueConstraint(ArgN), SizeArg1N(SizeArg1N), SizeArg2N(SizeArg2N),
424 CannotBeNull(CannotBeNull) {}
427 const Summary &Summary,
432 llvm::raw_ostream &Out)
const override;
435 const Summary &Summary,
436 llvm::raw_ostream &Out)
const override;
438 ValueConstraintPtr negate()
const override {
439 NotNullBufferConstraint Tmp(*
this);
440 Tmp.CannotBeNull = !this->CannotBeNull;
441 return std::make_shared<NotNullBufferConstraint>(Tmp);
445 bool checkSpecificValidity(
const FunctionDecl *FD)
const override {
446 const bool ValidArg = getArgType(FD, ArgN)->isPointerType();
448 "This constraint should be applied only on a pointer type");
463 class BufferSizeConstraint :
public ValueConstraint {
465 std::optional<llvm::APSInt> ConcreteSize;
467 std::optional<ArgNo> SizeArgN;
471 std::optional<ArgNo> SizeMultiplierArgN;
476 BufferSizeConstraint(ArgNo Buffer, llvm::APSInt BufMinSize)
477 : ValueConstraint(Buffer), ConcreteSize(BufMinSize) {}
478 BufferSizeConstraint(ArgNo Buffer, ArgNo BufSize)
479 : ValueConstraint(Buffer), SizeArgN(BufSize) {}
480 BufferSizeConstraint(ArgNo Buffer, ArgNo BufSize, ArgNo BufSizeMultiplier)
481 : ValueConstraint(Buffer), SizeArgN(BufSize),
482 SizeMultiplierArgN(BufSizeMultiplier) {}
485 const Summary &Summary,
490 llvm::raw_ostream &Out)
const override;
493 const Summary &Summary,
494 llvm::raw_ostream &Out)
const override;
496 std::vector<ArgNo> getArgsToTrack()
const override {
497 std::vector<ArgNo> Result{ArgN};
499 Result.push_back(*SizeArgN);
500 if (SizeMultiplierArgN)
501 Result.push_back(*SizeMultiplierArgN);
505 ValueConstraintPtr negate()
const override {
506 BufferSizeConstraint Tmp(*
this);
508 return std::make_shared<BufferSizeConstraint>(Tmp);
512 bool checkSpecificValidity(
const FunctionDecl *FD)
const override {
513 const bool ValidArg = getArgType(FD, ArgN)->isPointerType();
515 "This constraint should be applied only on a pointer type");
521 using ConstraintSet = std::vector<ValueConstraintPtr>;
530 class ErrnoConstraintBase {
534 const Summary &Summary,
542 virtual ~ErrnoConstraintBase() {}
545 ErrnoConstraintBase() =
default;
555 class ResetErrnoConstraint :
public ErrnoConstraintBase {
558 const Summary &Summary,
568 class NoErrnoConstraint :
public ErrnoConstraintBase {
571 const Summary &Summary,
581 class FailureErrnoConstraint :
public ErrnoConstraintBase {
584 const Summary &Summary,
589 C.getLocationContext(),
C.getASTContext().IntTy,
601 class SuccessErrnoConstraint :
public ErrnoConstraintBase {
604 const Summary &Summary,
610 return "'errno' becomes undefined after the call";
618 class ErrnoMustBeCheckedConstraint :
public ErrnoConstraintBase {
621 const Summary &Summary,
624 Call.getOriginExpr());
628 return "reading 'errno' is required to find out if the call has failed";
654 ConstraintSet Constraints;
655 const ErrnoConstraintBase &ErrnoConstraint;
659 SummaryCase(ConstraintSet &&Constraints,
const ErrnoConstraintBase &ErrnoC,
661 : Constraints(
std::move(Constraints)), ErrnoConstraint(ErrnoC),
664 SummaryCase(
const ConstraintSet &Constraints,
665 const ErrnoConstraintBase &ErrnoC, StringRef Note)
666 : Constraints(Constraints), ErrnoConstraint(ErrnoC),
Note(
Note) {}
668 const ConstraintSet &getConstraints()
const {
return Constraints; }
669 const ErrnoConstraintBase &getErrnoConstraint()
const {
670 return ErrnoConstraint;
672 StringRef getNote()
const {
return Note; }
675 using ArgTypes = std::vector<std::optional<QualType>>;
676 using RetType = std::optional<QualType>;
688 using ArgQualTypes = std::vector<QualType>;
697 Signature(ArgTypes ArgTys, RetType RetTy) {
698 for (std::optional<QualType> Arg : ArgTys) {
703 assertArgTypeSuitableForSignature(*Arg);
704 this->ArgTys.push_back(*Arg);
711 assertRetTypeSuitableForSignature(*RetTy);
712 this->RetTy = *RetTy;
720 static void assertArgTypeSuitableForSignature(
QualType T) {
722 "We should have no void types in the spec");
724 "We should only have canonical types in the spec");
726 static void assertRetTypeSuitableForSignature(
QualType T) {
728 "We should only have canonical types in the spec");
733 assert(FD &&
"Function must be set");
740 using SummaryCases = std::vector<SummaryCase>;
759 const InvalidationKind InvalidationKd;
761 ConstraintSet ArgConstraints;
768 Summary(InvalidationKind InvalidationKd) : InvalidationKd(InvalidationKd) {}
770 Summary &Case(ConstraintSet &&CS,
const ErrnoConstraintBase &ErrnoC,
771 StringRef
Note =
"") {
772 Cases.push_back(SummaryCase(std::move(CS), ErrnoC,
Note));
775 Summary &Case(
const ConstraintSet &CS,
const ErrnoConstraintBase &ErrnoC,
776 StringRef
Note =
"") {
777 Cases.push_back(SummaryCase(CS, ErrnoC,
Note));
780 Summary &ArgConstraint(ValueConstraintPtr VC) {
781 assert(VC->getArgNo() != Ret &&
782 "Arg constraint should not refer to the return value");
783 ArgConstraints.push_back(VC);
787 InvalidationKind getInvalidationKd()
const {
return InvalidationKd; }
788 const SummaryCases &getCases()
const {
return Cases; }
789 const ConstraintSet &getArgConstraints()
const {
return ArgConstraints; }
791 QualType getArgType(ArgNo ArgN)
const {
792 return StdLibraryFunctionsChecker::getArgType(FD, ArgN);
797 bool matchesAndSet(
const Signature &Sign,
const FunctionDecl *FD) {
798 bool Result = Sign.matches(FD) && validateByConstraints(FD);
800 assert(!this->FD &&
"FD must not be set more than once");
809 bool validateByConstraints(
const FunctionDecl *FD)
const {
810 for (
const SummaryCase &Case : Cases)
811 for (
const ValueConstraintPtr &Constraint : Case.getConstraints())
812 if (!Constraint->checkValidity(FD))
814 for (
const ValueConstraintPtr &Constraint : ArgConstraints)
815 if (!Constraint->checkValidity(FD))
823 using FunctionSummaryMapType = llvm::DenseMap<const FunctionDecl *, Summary>;
824 mutable FunctionSummaryMapType FunctionSummaryMap;
826 mutable std::unique_ptr<BugType> BT_InvalidArg;
827 mutable bool SummariesInitialized =
false;
830 return ArgN ==
Ret ?
Call.getReturnValue() :
Call.getArgSVal(ArgN);
833 assert(
Call.getDecl() &&
834 "Call was found by a summary, should have declaration");
835 return cast<NamedDecl>(
Call.getDecl())->getNameAsString();
844 bool AddTestFunctions =
false;
846 bool DisplayLoadedSummaries =
false;
847 bool ModelPOSIX =
false;
848 bool ShouldAssumeControlledEnvironment =
false;
851 std::optional<Summary> findFunctionSummary(
const FunctionDecl *FD,
853 std::optional<Summary> findFunctionSummary(
const CallEvent &
Call,
859 const ValueConstraint *VC,
const ValueConstraint *NegatedVC,
861 assert(
Call.getDecl() &&
862 "Function found in summary must have a declaration available");
864 llvm::raw_svector_ostream MsgOs(Msg);
867 printArgDesc(VC->getArgNo(), MsgOs);
868 MsgOs <<
" to '" << getFunctionName(
Call) <<
"' ";
870 NegatedVC->describeArgumentValue(
Call, N->
getState(), Summary, MsgOs);
874 MsgOs <<
"is out of the accepted range; It ";
875 VC->describe(ValueConstraint::Violation,
Call,
C.getState(), Summary,
877 Msg[0] = toupper(Msg[0]);
879 BT_InvalidArg = std::make_unique<BugType>(
880 CheckName,
"Function call with invalid argument",
882 auto R = std::make_unique<PathSensitiveBugReport>(*BT_InvalidArg, Msg, N);
884 for (ArgNo ArgN : VC->getArgsToTrack()) {
886 R->markInteresting(
Call.getArgSVal(ArgN));
888 R->addRange(
Call.getArgSourceRange(ArgN));
891 C.emitReport(std::move(R));
899 const NoErrnoConstraint ErrnoUnchanged{};
900 const ResetErrnoConstraint ErrnoIrrelevant{};
901 const ErrnoMustBeCheckedConstraint ErrnoMustBeChecked{};
902 const SuccessErrnoConstraint ErrnoMustNotBeChecked{};
903 const FailureErrnoConstraint ErrnoNEZeroIrrelevant{};
906int StdLibraryFunctionsChecker::ErrnoConstraintBase::Tag = 0;
908const StdLibraryFunctionsChecker::ArgNo StdLibraryFunctionsChecker::Ret =
909 std::numeric_limits<ArgNo>::max();
919void StdLibraryFunctionsChecker::printArgDesc(
920 StdLibraryFunctionsChecker::ArgNo ArgN, llvm::raw_ostream &Out) {
921 Out << std::to_string(ArgN + 1);
922 Out << llvm::getOrdinalSuffix(ArgN + 1);
926void StdLibraryFunctionsChecker::printArgValueInfo(ArgNo ArgN,
929 llvm::raw_ostream &Out) {
930 if (
const llvm::APSInt *Val =
931 State->getStateManager().getSValBuilder().getKnownValue(
932 State, getArgSVal(
Call, ArgN)))
933 Out <<
" (which is " << *Val <<
")";
936void StdLibraryFunctionsChecker::appendInsideRangeDesc(llvm::APSInt RMin,
940 llvm::raw_ostream &Out) {
941 if (RMin.isZero() && RMax.isZero())
943 else if (RMin == RMax)
949 Out <<
"<= " << RMax;
954 Out <<
">= " << RMin;
955 }
else if (RMin.isNegative() == RMax.isNegative() &&
956 RMin.getLimitedValue() == RMax.getLimitedValue() - 1) {
957 Out << RMin <<
" or " << RMax;
959 Out <<
"between " << RMin <<
" and " << RMax;
963void StdLibraryFunctionsChecker::appendOutOfRangeDesc(llvm::APSInt RMin,
967 llvm::raw_ostream &Out) {
968 if (RMin.isZero() && RMax.isZero())
970 else if (RMin == RMax) {
971 Out <<
"not equal to " << RMin;
982 }
else if (RMin.isNegative() == RMax.isNegative() &&
983 RMin.getLimitedValue() == RMax.getLimitedValue() - 1) {
984 Out <<
"not " << RMin <<
" and not " << RMax;
986 Out <<
"not between " << RMin <<
" and " << RMax;
990void StdLibraryFunctionsChecker::RangeConstraint::applyOnWithinRange(
995 for (
auto [Start, End] : getRanges()) {
996 const llvm::APSInt &Min = BVF.getValue(Start, ArgT);
997 const llvm::APSInt &Max = BVF.getValue(End, ArgT);
1004void StdLibraryFunctionsChecker::RangeConstraint::applyOnOutOfRange(
1009 const IntRangeVector &R = getRanges();
1010 size_t E = R.size();
1012 const llvm::APSInt &MinusInf = BVF.
getMinValue(ArgT);
1013 const llvm::APSInt &PlusInf = BVF.
getMaxValue(ArgT);
1015 const llvm::APSInt &RangeLeft = BVF.getValue(R[0].first - 1ULL, ArgT);
1016 const llvm::APSInt &RangeRight = BVF.getValue(R[E - 1].second + 1ULL, ArgT);
1019 for (
size_t I = 1; I != E; ++I) {
1020 const llvm::APSInt &Min = BVF.getValue(R[I - 1].second + 1ULL, ArgT);
1021 const llvm::APSInt &Max = BVF.getValue(R[I].first - 1ULL, ArgT);
1028 if (RangeLeft != PlusInf) {
1029 assert(MinusInf <= RangeLeft);
1030 if (!F(MinusInf, RangeLeft))
1034 if (RangeRight != MinusInf) {
1035 assert(RangeRight <= PlusInf);
1036 if (!F(RangeRight, PlusInf))
1046 QualType T = Summary.getArgType(getArgNo());
1048 if (
auto N =
V.getAs<
NonLoc>()) {
1049 auto ExcludeRangeFromArg = [&](
const llvm::APSInt &Min,
1050 const llvm::APSInt &Max) {
1052 return static_cast<bool>(State);
1056 applyOnRange(negateKind(Kind),
C.getSValBuilder().getBasicValueFactory(), T,
1057 ExcludeRangeFromArg);
1063void StdLibraryFunctionsChecker::RangeConstraint::describe(
1065 const Summary &Summary, llvm::raw_ostream &Out)
const {
1068 QualType T = Summary.getArgType(getArgNo());
1070 Out << ((DK == Violation) ?
"should be " :
"is ");
1071 if (!Description.empty()) {
1074 unsigned I = Ranges.size();
1075 if (Kind == WithinRange) {
1076 for (
const std::pair<RangeInt, RangeInt> &R : Ranges) {
1077 appendInsideRangeDesc(BVF.getValue(R.first, T),
1078 BVF.getValue(R.second, T), T, BVF, Out);
1083 for (
const std::pair<RangeInt, RangeInt> &R : Ranges) {
1084 appendOutOfRangeDesc(BVF.getValue(R.first, T),
1085 BVF.getValue(R.second, T), T, BVF, Out);
1093bool StdLibraryFunctionsChecker::RangeConstraint::describeArgumentValue(
1095 llvm::raw_ostream &Out)
const {
1096 unsigned int NRanges = 0;
1097 bool HaveAllRanges =
true;
1104 if (
auto N =
V.getAs<
NonLoc>()) {
1105 if (
const llvm::APSInt *Int = N->getAsInteger()) {
1110 QualType T = Summary.getArgType(getArgNo());
1112 llvm::raw_svector_ostream MoreInfoOs(MoreInfo);
1113 auto ApplyF = [&](
const llvm::APSInt &Min,
const llvm::APSInt &Max) {
1116 MoreInfoOs <<
" or ";
1117 appendInsideRangeDesc(Min, Max, T, BVF, MoreInfoOs);
1120 HaveAllRanges =
false;
1125 applyOnRange(Kind, BVF, T, ApplyF);
1126 assert(NRanges > 0);
1127 if (!HaveAllRanges || NRanges == 1) {
1136ProgramStateRef StdLibraryFunctionsChecker::ComparisonConstraint::apply(
1143 QualType T = Summary.getArgType(getArgNo());
1147 ArgNo OtherArg = getOtherArgNo();
1148 SVal OtherV = getArgSVal(
Call, OtherArg);
1149 QualType OtherT = Summary.getArgType(OtherArg);
1151 OtherV = SVB.
evalCast(OtherV, T, OtherT);
1152 if (
auto CompV = SVB.
evalBinOp(State, Op,
V, OtherV, CondT)
1154 State = State->assume(*CompV,
true);
1169 return State->assume(L, CannotBeNull);
1172void StdLibraryFunctionsChecker::NotNullConstraint::describe(
1174 const Summary &Summary, llvm::raw_ostream &Out)
const {
1175 assert(CannotBeNull &&
1176 "Describe should not be used when the value must be NULL");
1177 if (DK == Violation)
1178 Out <<
"should not be NULL";
1180 Out <<
"is not NULL";
1183bool StdLibraryFunctionsChecker::NotNullConstraint::describeArgumentValue(
1185 llvm::raw_ostream &Out)
const {
1186 assert(!CannotBeNull &&
"This function is used when the value is NULL");
1191ProgramStateRef StdLibraryFunctionsChecker::NotNullBufferConstraint::apply(
1201 std::optional<DefinedOrUnknownSVal> SizeArg1 =
1203 std::optional<DefinedOrUnknownSVal> SizeArg2;
1207 auto IsArgZero = [State](std::optional<DefinedOrUnknownSVal> Val) {
1210 auto [IsNonNull,
IsNull] = State->assume(*Val);
1211 return IsNull && !IsNonNull;
1214 if (IsArgZero(SizeArg1) || IsArgZero(SizeArg2))
1217 return State->assume(L, CannotBeNull);
1220void StdLibraryFunctionsChecker::NotNullBufferConstraint::describe(
1222 const Summary &Summary, llvm::raw_ostream &Out)
const {
1223 assert(CannotBeNull &&
1224 "Describe should not be used when the value must be NULL");
1225 if (DK == Violation)
1226 Out <<
"should not be NULL";
1228 Out <<
"is not NULL";
1231bool StdLibraryFunctionsChecker::NotNullBufferConstraint::describeArgumentValue(
1233 llvm::raw_ostream &Out)
const {
1234 assert(!CannotBeNull &&
"This function is used when the value is NULL");
1239ProgramStateRef StdLibraryFunctionsChecker::BufferSizeConstraint::apply(
1244 SVal BufV = getArgSVal(
Call, getArgNo());
1247 const SVal SizeV = [
this, &State, &
Call, &Summary, &SvalBuilder]() {
1251 assert(SizeArgN &&
"The constraint must be either a concrete value or "
1252 "encoded in an argument.");
1254 SVal SizeV = getArgSVal(
Call, *SizeArgN);
1256 if (SizeMultiplierArgN) {
1257 SVal SizeMulV = getArgSVal(
Call, *SizeMultiplierArgN);
1258 SizeV = SvalBuilder.
evalBinOp(State, BO_Mul, SizeV, SizeMulV,
1259 Summary.getArgType(*SizeArgN));
1267 SVal Feasible = SvalBuilder.
evalBinOp(State, Op, SizeV, BufDynSize,
1270 return State->assume(*F,
true);
1278 llvm_unreachable(
"Size argument or the dynamic size is Undefined");
1281void StdLibraryFunctionsChecker::BufferSizeConstraint::describe(
1283 const Summary &Summary, llvm::raw_ostream &Out)
const {
1284 Out << ((DK == Violation) ?
"should be " :
"is ");
1285 Out <<
"a buffer with size equal to or greater than ";
1287 Out << *ConcreteSize;
1288 }
else if (SizeArgN) {
1289 Out <<
"the value of the ";
1290 printArgDesc(*SizeArgN, Out);
1291 printArgValueInfo(*SizeArgN, State,
Call, Out);
1292 if (SizeMultiplierArgN) {
1293 Out <<
" times the ";
1294 printArgDesc(*SizeMultiplierArgN, Out);
1295 printArgValueInfo(*SizeMultiplierArgN, State,
Call, Out);
1300bool StdLibraryFunctionsChecker::BufferSizeConstraint::describeArgumentValue(
1302 llvm::raw_ostream &Out)
const {
1303 SVal BufV = getArgSVal(
Call, getArgNo());
1305 if (
const llvm::APSInt *Val =
1306 State->getStateManager().getSValBuilder().getKnownValue(State,
1308 Out <<
"is a buffer with size " << *Val;
1314void StdLibraryFunctionsChecker::checkPreCall(
const CallEvent &
Call,
1316 std::optional<Summary> FoundSummary = findFunctionSummary(
Call,
C);
1320 const Summary &Summary = *FoundSummary;
1325 for (
const ValueConstraintPtr &Constraint : Summary.getArgConstraints()) {
1326 ValueConstraintPtr NegatedConstraint = Constraint->negate();
1329 NegatedConstraint->apply(NewState,
Call, Summary,
C);
1331 if (FailureSt && !SuccessSt) {
1333 reportBug(
Call, N, Constraint.get(), NegatedConstraint.get(), Summary,
1342 NewState = SuccessSt;
1343 if (NewState != State) {
1345 llvm::raw_svector_ostream Os(Msg);
1346 Os <<
"Assuming that the ";
1347 printArgDesc(Constraint->getArgNo(), Os);
1349 Os << getFunctionName(
Call);
1351 Constraint->describe(ValueConstraint::Assumption,
Call, NewState, Summary,
1353 const auto ArgSVal =
Call.getArgSVal(Constraint->getArgNo());
1354 NewNode =
C.addTransition(
1356 C.getNoteTag([Msg = std::move(Msg), ArgSVal](
1358 if (BR.isInteresting(ArgSVal))
1365void StdLibraryFunctionsChecker::checkPostCall(
const CallEvent &
Call,
1367 std::optional<Summary> FoundSummary = findFunctionSummary(
Call,
C);
1372 const Summary &Summary = *FoundSummary;
1377 for (
const SummaryCase &Case : Summary.getCases()) {
1379 for (
const ValueConstraintPtr &Constraint : Case.getConstraints()) {
1380 NewState = Constraint->apply(NewState,
Call, Summary,
C);
1386 NewState = Case.getErrnoConstraint().apply(NewState,
Call, Summary,
C);
1399 cast<NamedDecl>(
Call.getDecl())->getDeclName();
1401 std::string ErrnoNote = Case.getErrnoConstraint().describe(
C);
1402 std::string CaseNote;
1403 if (Case.getNote().empty()) {
1404 if (!ErrnoNote.empty())
1406 llvm::formatv(
"After calling '{0}' {1}", FunctionName, ErrnoNote);
1408 CaseNote = llvm::formatv(Case.getNote().str().c_str(), FunctionName);
1410 const SVal RV =
Call.getReturnValue();
1412 if (Summary.getInvalidationKd() == EvalCallAsPure) {
1415 if (!CaseNote.empty()) {
1432 Pred =
C.addTransition(NewState, Pred, Tag);
1435 if (!CaseNote.empty() || !ErrnoNote.empty()) {
1437 C.getNoteTag([CaseNote, ErrnoNote,
1445 std::optional<Loc> ErrnoLoc =
1447 bool ErrnoImportant = !ErrnoNote.empty() && ErrnoLoc &&
1449 if (ErrnoImportant) {
1451 if (CaseNote.empty())
1453 return llvm::formatv(
"{0}; {1}", CaseNote, ErrnoNote);
1460 Pred =
C.addTransition(NewState, Pred, Tag);
1465 if (Pred ==
Node && NewState != State)
1466 C.addTransition(NewState);
1470bool StdLibraryFunctionsChecker::evalCall(
const CallEvent &
Call,
1472 std::optional<Summary> FoundSummary = findFunctionSummary(
Call,
C);
1476 const Summary &Summary = *FoundSummary;
1477 switch (Summary.getInvalidationKd()) {
1478 case EvalCallAsPure: {
1481 const auto *CE = cast<CallExpr>(
Call.getOriginExpr());
1482 SVal V =
C.getSValBuilder().conjureSymbolVal(
1483 CE, LC, CE->getType().getCanonicalType(),
C.blockCount());
1484 State = State->BindExpr(CE, LC,
V);
1486 C.addTransition(State);
1495 llvm_unreachable(
"Unknown invalidation kind!");
1498bool StdLibraryFunctionsChecker::Signature::matches(
1512 auto RemoveRestrict = [&FD](
QualType T) {
1519 if (!isIrrelevant(RetTy)) {
1521 if (RetTy != FDRetTy)
1526 for (
auto [Idx, ArgTy] : llvm::enumerate(ArgTys)) {
1527 if (isIrrelevant(ArgTy))
1531 if (ArgTy != FDArgTy)
1538std::optional<StdLibraryFunctionsChecker::Summary>
1539StdLibraryFunctionsChecker::findFunctionSummary(
const FunctionDecl *FD,
1542 return std::nullopt;
1544 initFunctionSummaries(
C);
1547 if (FSMI == FunctionSummaryMap.end())
1548 return std::nullopt;
1549 return FSMI->second;
1552std::optional<StdLibraryFunctionsChecker::Summary>
1553StdLibraryFunctionsChecker::findFunctionSummary(
const CallEvent &
Call,
1557 return std::nullopt;
1558 return findFunctionSummary(FD,
C);
1561void StdLibraryFunctionsChecker::initFunctionSummaries(
1563 if (SummariesInitialized)
1565 SummariesInitialized =
true;
1577 LookupType(
const ASTContext &ACtx) : ACtx(ACtx) {}
1580 std::optional<QualType> operator()(StringRef Name) {
1583 if (LookupRes.empty())
1584 return std::nullopt;
1591 for (
Decl *D : LookupRes)
1592 if (
auto *TD = dyn_cast<TypedefNameDecl>(D))
1599 for (
Decl *D : LookupRes)
1600 if (
auto *TD = dyn_cast<TypeDecl>(D))
1602 return std::nullopt;
1608 class GetRestrictTy {
1612 GetRestrictTy(
const ASTContext &ACtx) : ACtx(ACtx) {}
1616 std::optional<QualType> operator()(std::optional<QualType> Ty) {
1618 return operator()(*Ty);
1619 return std::nullopt;
1621 } getRestrictTy(ACtx);
1622 class GetPointerTy {
1626 GetPointerTy(
const ASTContext &ACtx) : ACtx(ACtx) {}
1628 std::optional<QualType> operator()(std::optional<QualType> Ty) {
1630 return operator()(*Ty);
1631 return std::nullopt;
1633 } getPointerTy(ACtx);
1636 std::optional<QualType> operator()(std::optional<QualType> Ty) {
1637 return Ty ? std::optional<QualType>(Ty->withConst()) :
std::nullopt;
1646 std::optional<RangeInt> operator()(
QualType Ty) {
1649 std::optional<RangeInt> operator()(std::optional<QualType> Ty) {
1651 return operator()(*Ty);
1653 return std::nullopt;
1672 const QualType VoidPtrTy = getPointerTy(VoidTy);
1673 const QualType IntPtrTy = getPointerTy(IntTy);
1675 getPointerTy(UnsignedIntTy);
1676 const QualType VoidPtrRestrictTy = getRestrictTy(VoidPtrTy);
1678 getPointerTy(getConstTy(VoidTy));
1679 const QualType CharPtrTy = getPointerTy(CharTy);
1680 const QualType CharPtrRestrictTy = getRestrictTy(CharPtrTy);
1682 getPointerTy(getConstTy(CharTy));
1683 const QualType ConstCharPtrRestrictTy = getRestrictTy(ConstCharPtrTy);
1684 const QualType Wchar_tPtrTy = getPointerTy(WCharTy);
1686 getPointerTy(getConstTy(WCharTy));
1687 const QualType ConstVoidPtrRestrictTy = getRestrictTy(ConstVoidPtrTy);
1688 const QualType SizePtrTy = getPointerTy(SizeTy);
1689 const QualType SizePtrRestrictTy = getRestrictTy(SizePtrTy);
1691 const RangeInt IntMax = BVF.
getMaxValue(IntTy).getLimitedValue();
1692 const RangeInt UnsignedIntMax =
1694 const RangeInt LongMax = BVF.
getMaxValue(LongTy).getLimitedValue();
1695 const RangeInt SizeMax = BVF.
getMaxValue(SizeTy).getLimitedValue();
1703 const RangeInt UCharRangeMax =
1713 struct AddToFunctionSummaryMap {
1715 FunctionSummaryMapType ⤅
1716 bool DisplayLoadedSummaries;
1717 AddToFunctionSummaryMap(
const ASTContext &ACtx, FunctionSummaryMapType &FSM,
1718 bool DisplayLoadedSummaries)
1719 : ACtx(ACtx), Map(FSM), DisplayLoadedSummaries(DisplayLoadedSummaries) {
1727 bool operator()(StringRef Name, Signature Sign, Summary Sum) {
1728 if (Sign.isInvalid())
1732 if (LookupRes.empty())
1734 for (
Decl *D : LookupRes) {
1735 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
1736 if (Sum.matchesAndSet(Sign, FD)) {
1738 assert(Res.second &&
"Function already has a summary set!");
1740 if (DisplayLoadedSummaries) {
1741 llvm::errs() <<
"Loaded summary for: ";
1742 FD->
print(llvm::errs());
1743 llvm::errs() <<
"\n";
1753 void operator()(std::vector<StringRef> Names, Signature Sign, Summary Sum) {
1754 for (StringRef Name : Names)
1755 operator()(Name, Sign, Sum);
1757 } addToFunctionSummaryMap(ACtx, FunctionSummaryMap, DisplayLoadedSummaries);
1760 auto ArgumentCondition = [](ArgNo ArgN, RangeKind
Kind, IntRangeVector Ranges,
1761 StringRef Desc =
"") {
1762 return std::make_shared<RangeConstraint>(ArgN, Kind, Ranges, Desc);
1764 auto BufferSize = [](
auto... Args) {
1765 return std::make_shared<BufferSizeConstraint>(Args...);
1768 auto operator()(RangeKind Kind, IntRangeVector Ranges) {
1769 return std::make_shared<RangeConstraint>(Ret, Kind, Ranges);
1772 return std::make_shared<ComparisonConstraint>(Ret, Op, OtherArgN);
1774 } ReturnValueCondition;
1776 auto operator()(RangeInt
b, RangeInt e) {
1777 return IntRangeVector{std::pair<RangeInt, RangeInt>{
b, e}};
1779 auto operator()(RangeInt
b, std::optional<RangeInt> e) {
1781 return IntRangeVector{std::pair<RangeInt, RangeInt>{
b, *e}};
1782 return IntRangeVector{};
1784 auto operator()(std::pair<RangeInt, RangeInt> i0,
1785 std::pair<RangeInt, std::optional<RangeInt>> i1) {
1787 return IntRangeVector{i0, {i1.first, *(i1.second)}};
1788 return IntRangeVector{i0};
1791 auto SingleValue = [](RangeInt
v) {
1792 return IntRangeVector{std::pair<RangeInt, RangeInt>{
v,
v}};
1794 auto LessThanOrEq = BO_LE;
1795 auto NotNull = [&](ArgNo ArgN) {
1796 return std::make_shared<NotNullConstraint>(ArgN);
1798 auto IsNull = [&](ArgNo ArgN) {
1799 return std::make_shared<NotNullConstraint>(ArgN,
false);
1801 auto NotNullBuffer = [&](ArgNo ArgN, ArgNo SizeArg1N, ArgNo SizeArg2N) {
1802 return std::make_shared<NotNullBufferConstraint>(ArgN, SizeArg1N,
1806 std::optional<QualType> FileTy = lookupTy(
"FILE");
1807 std::optional<QualType> FilePtrTy = getPointerTy(FileTy);
1808 std::optional<QualType> FilePtrRestrictTy = getRestrictTy(FilePtrTy);
1810 std::optional<QualType> FPosTTy = lookupTy(
"fpos_t");
1811 std::optional<QualType> FPosTPtrTy = getPointerTy(FPosTTy);
1812 std::optional<QualType> ConstFPosTPtrTy = getPointerTy(getConstTy(FPosTTy));
1813 std::optional<QualType> FPosTPtrRestrictTy = getRestrictTy(FPosTPtrTy);
1815 constexpr llvm::StringLiteral GenericSuccessMsg(
1816 "Assuming that '{0}' is successful");
1817 constexpr llvm::StringLiteral GenericFailureMsg(
"Assuming that '{0}' fails");
1834 addToFunctionSummaryMap(
1835 "isalnum", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1836 Summary(EvalCallAsPure)
1838 .Case({ArgumentCondition(0
U, WithinRange,
1839 {{
'0',
'9'}, {
'A',
'Z'}, {
'a',
'z'}}),
1840 ReturnValueCondition(OutOfRange, SingleValue(0))},
1841 ErrnoIrrelevant,
"Assuming the character is alphanumeric")
1845 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1850 {{
'0',
'9'}, {
'A',
'Z'}, {
'a',
'z'}, {128, UCharRangeMax}}),
1851 ReturnValueCondition(WithinRange, SingleValue(0))},
1852 ErrnoIrrelevant,
"Assuming the character is non-alphanumeric")
1853 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
1854 {{EOFv, EOFv}, {0, UCharRangeMax}},
1855 "an unsigned char value or EOF")));
1856 addToFunctionSummaryMap(
1857 "isalpha", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1858 Summary(EvalCallAsPure)
1859 .Case({ArgumentCondition(0
U, WithinRange, {{
'A',
'Z'}, {
'a',
'z'}}),
1860 ReturnValueCondition(OutOfRange, SingleValue(0))},
1861 ErrnoIrrelevant,
"Assuming the character is alphabetical")
1863 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1865 .Case({ArgumentCondition(
1867 {{
'A',
'Z'}, {
'a',
'z'}, {128, UCharRangeMax}}),
1868 ReturnValueCondition(WithinRange, SingleValue(0))},
1869 ErrnoIrrelevant,
"Assuming the character is non-alphabetical"));
1870 addToFunctionSummaryMap(
1871 "isascii", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1872 Summary(EvalCallAsPure)
1873 .Case({ArgumentCondition(0
U, WithinRange,
Range(0, 127)),
1874 ReturnValueCondition(OutOfRange, SingleValue(0))},
1875 ErrnoIrrelevant,
"Assuming the character is an ASCII character")
1876 .Case({ArgumentCondition(0
U, OutOfRange,
Range(0, 127)),
1877 ReturnValueCondition(WithinRange, SingleValue(0))},
1879 "Assuming the character is not an ASCII character"));
1880 addToFunctionSummaryMap(
1881 "isblank", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1882 Summary(EvalCallAsPure)
1883 .Case({ArgumentCondition(0
U, WithinRange, {{
'\t',
'\t'}, {
' ',
' '}}),
1884 ReturnValueCondition(OutOfRange, SingleValue(0))},
1885 ErrnoIrrelevant,
"Assuming the character is a blank character")
1886 .Case({ArgumentCondition(0
U, OutOfRange, {{
'\t',
'\t'}, {
' ',
' '}}),
1887 ReturnValueCondition(WithinRange, SingleValue(0))},
1889 "Assuming the character is not a blank character"));
1890 addToFunctionSummaryMap(
1891 "iscntrl", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1892 Summary(EvalCallAsPure)
1893 .Case({ArgumentCondition(0
U, WithinRange, {{0, 32}, {127, 127}}),
1894 ReturnValueCondition(OutOfRange, SingleValue(0))},
1896 "Assuming the character is a control character")
1897 .Case({ArgumentCondition(0
U, OutOfRange, {{0, 32}, {127, 127}}),
1898 ReturnValueCondition(WithinRange, SingleValue(0))},
1900 "Assuming the character is not a control character"));
1901 addToFunctionSummaryMap(
1902 "isdigit", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1903 Summary(EvalCallAsPure)
1904 .Case({ArgumentCondition(0
U, WithinRange,
Range(
'0',
'9')),
1905 ReturnValueCondition(OutOfRange, SingleValue(0))},
1906 ErrnoIrrelevant,
"Assuming the character is a digit")
1907 .Case({ArgumentCondition(0
U, OutOfRange,
Range(
'0',
'9')),
1908 ReturnValueCondition(WithinRange, SingleValue(0))},
1909 ErrnoIrrelevant,
"Assuming the character is not a digit"));
1910 addToFunctionSummaryMap(
1911 "isgraph", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1912 Summary(EvalCallAsPure)
1913 .Case({ArgumentCondition(0
U, WithinRange,
Range(33, 126)),
1914 ReturnValueCondition(OutOfRange, SingleValue(0))},
1916 "Assuming the character has graphical representation")
1918 {ArgumentCondition(0
U, OutOfRange,
Range(33, 126)),
1919 ReturnValueCondition(WithinRange, SingleValue(0))},
1921 "Assuming the character does not have graphical representation"));
1922 addToFunctionSummaryMap(
1923 "islower", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1924 Summary(EvalCallAsPure)
1926 .Case({ArgumentCondition(0
U, WithinRange,
Range(
'a',
'z')),
1927 ReturnValueCondition(OutOfRange, SingleValue(0))},
1928 ErrnoIrrelevant,
"Assuming the character is a lowercase letter")
1930 .Case({ArgumentCondition(0
U, WithinRange,
Range(0, 127)),
1931 ArgumentCondition(0
U, OutOfRange,
Range(
'a',
'z')),
1932 ReturnValueCondition(WithinRange, SingleValue(0))},
1934 "Assuming the character is not a lowercase letter")
1936 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1939 .Case({ArgumentCondition(0
U, OutOfRange,
Range(0, UCharRangeMax)),
1940 ReturnValueCondition(WithinRange, SingleValue(0))},
1942 addToFunctionSummaryMap(
1943 "isprint", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1944 Summary(EvalCallAsPure)
1945 .Case({ArgumentCondition(0
U, WithinRange,
Range(32, 126)),
1946 ReturnValueCondition(OutOfRange, SingleValue(0))},
1947 ErrnoIrrelevant,
"Assuming the character is printable")
1948 .Case({ArgumentCondition(0
U, OutOfRange,
Range(32, 126)),
1949 ReturnValueCondition(WithinRange, SingleValue(0))},
1950 ErrnoIrrelevant,
"Assuming the character is non-printable"));
1951 addToFunctionSummaryMap(
1952 "ispunct", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1953 Summary(EvalCallAsPure)
1954 .Case({ArgumentCondition(
1956 {{
'!',
'/'}, {
':',
'@'}, {
'[',
'`'}, {
'{',
'~'}}),
1957 ReturnValueCondition(OutOfRange, SingleValue(0))},
1958 ErrnoIrrelevant,
"Assuming the character is a punctuation mark")
1959 .Case({ArgumentCondition(
1961 {{
'!',
'/'}, {
':',
'@'}, {
'[',
'`'}, {
'{',
'~'}}),
1962 ReturnValueCondition(WithinRange, SingleValue(0))},
1964 "Assuming the character is not a punctuation mark"));
1965 addToFunctionSummaryMap(
1966 "isspace", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1967 Summary(EvalCallAsPure)
1969 .Case({ArgumentCondition(0
U, WithinRange, {{9, 13}, {
' ',
' '}}),
1970 ReturnValueCondition(OutOfRange, SingleValue(0))},
1972 "Assuming the character is a whitespace character")
1974 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1976 .Case({ArgumentCondition(0
U, OutOfRange,
1977 {{9, 13}, {
' ',
' '}, {128, UCharRangeMax}}),
1978 ReturnValueCondition(WithinRange, SingleValue(0))},
1980 "Assuming the character is not a whitespace character"));
1981 addToFunctionSummaryMap(
1982 "isupper", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1983 Summary(EvalCallAsPure)
1985 .Case({ArgumentCondition(0
U, WithinRange,
Range(
'A',
'Z')),
1986 ReturnValueCondition(OutOfRange, SingleValue(0))},
1988 "Assuming the character is an uppercase letter")
1990 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1993 .Case({ArgumentCondition(0
U, OutOfRange,
1994 {{
'A',
'Z'}, {128, UCharRangeMax}}),
1995 ReturnValueCondition(WithinRange, SingleValue(0))},
1997 "Assuming the character is not an uppercase letter"));
1998 addToFunctionSummaryMap(
1999 "isxdigit", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2000 Summary(EvalCallAsPure)
2001 .Case({ArgumentCondition(0
U, WithinRange,
2002 {{
'0',
'9'}, {
'A',
'F'}, {
'a',
'f'}}),
2003 ReturnValueCondition(OutOfRange, SingleValue(0))},
2005 "Assuming the character is a hexadecimal digit")
2006 .Case({ArgumentCondition(0
U, OutOfRange,
2007 {{
'0',
'9'}, {
'A',
'F'}, {
'a',
'f'}}),
2008 ReturnValueCondition(WithinRange, SingleValue(0))},
2010 "Assuming the character is not a hexadecimal digit"));
2011 addToFunctionSummaryMap(
2012 "toupper", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2013 Summary(EvalCallAsPure)
2014 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
2015 {{EOFv, EOFv}, {0, UCharRangeMax}},
2016 "an unsigned char value or EOF")));
2017 addToFunctionSummaryMap(
2018 "tolower", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2019 Summary(EvalCallAsPure)
2020 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
2021 {{EOFv, EOFv}, {0, UCharRangeMax}},
2022 "an unsigned char value or EOF")));
2023 addToFunctionSummaryMap(
2024 "toascii", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2025 Summary(EvalCallAsPure)
2026 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
2027 {{EOFv, EOFv}, {0, UCharRangeMax}},
2028 "an unsigned char value or EOF")));
2031 addToFunctionSummaryMap(
2032 {
"getc",
"fgetc"}, Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2034 .Case({ReturnValueCondition(WithinRange,
2035 {{EOFv, EOFv}, {0, UCharRangeMax}})},
2037 addToFunctionSummaryMap(
2038 "getchar", Signature(ArgTypes{}, RetType{IntTy}),
2040 .Case({ReturnValueCondition(WithinRange,
2041 {{EOFv, EOFv}, {0, UCharRangeMax}})},
2047 .Case({ArgumentCondition(1U, WithinRange,
Range(1, SizeMax)),
2048 ArgumentCondition(2U, WithinRange,
Range(1, SizeMax)),
2049 ReturnValueCondition(BO_LT, ArgNo(2)),
2050 ReturnValueCondition(WithinRange,
Range(0, SizeMax))},
2051 ErrnoNEZeroIrrelevant, GenericFailureMsg)
2052 .Case({ArgumentCondition(1U, WithinRange,
Range(1, SizeMax)),
2053 ReturnValueCondition(BO_EQ, ArgNo(2)),
2054 ReturnValueCondition(WithinRange,
Range(0, SizeMax))},
2055 ErrnoMustNotBeChecked, GenericSuccessMsg)
2056 .Case({ArgumentCondition(1U, WithinRange, SingleValue(0)),
2057 ReturnValueCondition(WithinRange, SingleValue(0))},
2058 ErrnoMustNotBeChecked,
2059 "Assuming that argument 'size' to '{0}' is 0")
2060 .ArgConstraint(NotNullBuffer(ArgNo(0), ArgNo(1), ArgNo(2)))
2061 .ArgConstraint(NotNull(ArgNo(3)))
2062 .ArgConstraint(BufferSize(ArgNo(0), ArgNo(1),
2067 addToFunctionSummaryMap(
2069 Signature(ArgTypes{VoidPtrRestrictTy, SizeTy, SizeTy, FilePtrRestrictTy},
2074 addToFunctionSummaryMap(
"fwrite",
2075 Signature(ArgTypes{ConstVoidPtrRestrictTy, SizeTy,
2076 SizeTy, FilePtrRestrictTy},
2080 std::optional<QualType> Ssize_tTy = lookupTy(
"ssize_t");
2081 std::optional<RangeInt> Ssize_tMax = getMaxValue(Ssize_tTy);
2085 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
2086 ReturnValueCondition(WithinRange,
Range(-1, Ssize_tMax))},
2092 addToFunctionSummaryMap(
2093 "read", Signature(ArgTypes{IntTy, VoidPtrTy, SizeTy}, RetType{Ssize_tTy}),
2096 addToFunctionSummaryMap(
2098 Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy}, RetType{Ssize_tTy}),
2101 auto GetLineSummary =
2103 .Case({ReturnValueCondition(WithinRange,
2104 Range({-1, -1}, {1, Ssize_tMax}))},
2107 QualType CharPtrPtrRestrictTy = getRestrictTy(getPointerTy(CharPtrTy));
2114 addToFunctionSummaryMap(
2117 ArgTypes{CharPtrPtrRestrictTy, SizePtrRestrictTy, FilePtrRestrictTy},
2118 RetType{Ssize_tTy}),
2122 addToFunctionSummaryMap(
2124 Signature(ArgTypes{CharPtrPtrRestrictTy, SizePtrRestrictTy, IntTy,
2126 RetType{Ssize_tTy}),
2130 Summary GetenvSummary =
2132 .ArgConstraint(NotNull(ArgNo(0)))
2133 .Case({NotNull(Ret)}, ErrnoIrrelevant,
2134 "Assuming the environment variable exists");
2136 if (!ShouldAssumeControlledEnvironment)
2137 GetenvSummary.Case({NotNull(Ret)->negate()}, ErrnoIrrelevant,
2138 "Assuming the environment variable does not exist");
2141 addToFunctionSummaryMap(
2142 "getenv", Signature(ArgTypes{ConstCharPtrTy}, RetType{CharPtrTy}),
2143 std::move(GetenvSummary));
2147 const auto ReturnsZeroOrMinusOne =
2148 ConstraintSet{ReturnValueCondition(WithinRange,
Range(-1, 0))};
2149 const auto ReturnsZero =
2150 ConstraintSet{ReturnValueCondition(WithinRange, SingleValue(0))};
2151 const auto ReturnsMinusOne =
2152 ConstraintSet{ReturnValueCondition(WithinRange, SingleValue(-1))};
2153 const auto ReturnsNonnegative =
2154 ConstraintSet{ReturnValueCondition(WithinRange,
Range(0, IntMax))};
2155 const auto ReturnsNonZero =
2156 ConstraintSet{ReturnValueCondition(OutOfRange, SingleValue(0))};
2157 const auto ReturnsFileDescriptor =
2158 ConstraintSet{ReturnValueCondition(WithinRange,
Range(-1, IntMax))};
2159 const auto &ReturnsValidFileDescriptor = ReturnsNonnegative;
2161 auto ValidFileDescriptorOrAtFdcwd = [&](ArgNo ArgN) {
2162 return std::make_shared<RangeConstraint>(
2163 ArgN, WithinRange,
Range({AT_FDCWDv, AT_FDCWDv}, {0, IntMax}),
2164 "a valid file descriptor or AT_FDCWD");
2168 addToFunctionSummaryMap(
2170 Signature(ArgTypes{ConstCharPtrRestrictTy, ConstCharPtrRestrictTy},
2171 RetType{FilePtrTy}),
2173 .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
2174 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2175 .ArgConstraint(NotNull(ArgNo(0)))
2176 .ArgConstraint(NotNull(ArgNo(1))));
2179 addToFunctionSummaryMap(
2180 "tmpfile", Signature(ArgTypes{}, RetType{FilePtrTy}),
2182 .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
2183 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg));
2187 addToFunctionSummaryMap(
2189 Signature(ArgTypes{ConstCharPtrRestrictTy, ConstCharPtrRestrictTy,
2191 RetType{FilePtrTy}),
2193 .Case({ReturnValueCondition(BO_EQ, ArgNo(2))},
2194 ErrnoMustNotBeChecked, GenericSuccessMsg)
2195 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2196 .ArgConstraint(NotNull(ArgNo(1)))
2197 .ArgConstraint(NotNull(ArgNo(2))));
2200 addToFunctionSummaryMap(
2201 "fclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2203 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2204 .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
2205 ErrnoNEZeroIrrelevant, GenericFailureMsg)
2206 .ArgConstraint(NotNull(ArgNo(0))));
2212 addToFunctionSummaryMap(
2213 "fseek", Signature(ArgTypes{FilePtrTy, LongTy, IntTy}, RetType{IntTy}),
2215 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2216 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2217 .ArgConstraint(NotNull(ArgNo(0)))
2218 .ArgConstraint(ArgumentCondition(2, WithinRange, {{0, 2}})));
2224 addToFunctionSummaryMap(
2226 Signature(ArgTypes{FilePtrRestrictTy, FPosTPtrRestrictTy},
2229 .Case(ReturnsZero, ErrnoUnchanged, GenericSuccessMsg)
2230 .Case(ReturnsNonZero, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2231 .ArgConstraint(NotNull(ArgNo(0)))
2232 .ArgConstraint(NotNull(ArgNo(1))));
2238 addToFunctionSummaryMap(
2240 Signature(ArgTypes{FilePtrTy, ConstFPosTPtrTy}, RetType{IntTy}),
2242 .Case(ReturnsZero, ErrnoUnchanged, GenericSuccessMsg)
2243 .Case(ReturnsNonZero, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2244 .ArgConstraint(NotNull(ArgNo(0)))
2245 .ArgConstraint(NotNull(ArgNo(1))));
2251 addToFunctionSummaryMap(
2252 "ftell", Signature(ArgTypes{FilePtrTy}, RetType{LongTy}),
2254 .Case({ReturnValueCondition(WithinRange,
Range(1, LongMax))},
2255 ErrnoUnchanged, GenericSuccessMsg)
2256 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2257 .ArgConstraint(NotNull(ArgNo(0))));
2260 addToFunctionSummaryMap(
2261 "fileno", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2263 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2265 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2266 .ArgConstraint(NotNull(ArgNo(0))));
2270 addToFunctionSummaryMap(
"rewind",
2271 Signature(ArgTypes{FilePtrTy}, RetType{VoidTy}),
2273 .Case({}, ErrnoMustBeChecked)
2274 .ArgConstraint(NotNull(ArgNo(0))));
2277 addToFunctionSummaryMap(
2278 "clearerr", Signature(ArgTypes{FilePtrTy}, RetType{VoidTy}),
2279 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2282 addToFunctionSummaryMap(
2283 "feof", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2284 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2287 addToFunctionSummaryMap(
2288 "ferror", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2289 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2292 addToFunctionSummaryMap(
2293 "a64l", Signature(ArgTypes{ConstCharPtrTy}, RetType{LongTy}),
2294 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2297 addToFunctionSummaryMap(
"l64a",
2298 Signature(ArgTypes{LongTy}, RetType{CharPtrTy}),
2300 .ArgConstraint(ArgumentCondition(
2301 0, WithinRange,
Range(0, LongMax))));
2304 addToFunctionSummaryMap(
2305 "open", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{IntTy}),
2307 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2309 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2310 .ArgConstraint(NotNull(ArgNo(0))));
2313 addToFunctionSummaryMap(
2315 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy}, RetType{IntTy}),
2317 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2319 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2320 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2321 .ArgConstraint(NotNull(ArgNo(1))));
2324 addToFunctionSummaryMap(
2325 "access", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{IntTy}),
2327 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2328 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2329 .ArgConstraint(NotNull(ArgNo(0))));
2332 addToFunctionSummaryMap(
2334 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy, IntTy},
2337 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2338 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2339 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2340 .ArgConstraint(NotNull(ArgNo(1))));
2343 addToFunctionSummaryMap(
2344 "dup", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2346 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2348 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2350 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2353 addToFunctionSummaryMap(
2354 "dup2", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
2356 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2358 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2359 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
2361 ArgumentCondition(1, WithinRange,
Range(0, IntMax))));
2364 addToFunctionSummaryMap(
2365 "fdatasync", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2367 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2368 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2370 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2373 addToFunctionSummaryMap(
2375 Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy, IntTy},
2378 .ArgConstraint(NotNull(ArgNo(0)))
2379 .ArgConstraint(NotNull(ArgNo(1))));
2382 addToFunctionSummaryMap(
2383 "fsync", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2385 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2386 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2388 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2390 std::optional<QualType> Off_tTy = lookupTy(
"off_t");
2393 addToFunctionSummaryMap(
2395 Signature(ArgTypes{ConstCharPtrTy, Off_tTy}, RetType{IntTy}),
2397 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2398 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2399 .ArgConstraint(NotNull(ArgNo(0))));
2402 addToFunctionSummaryMap(
2404 Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{IntTy}),
2406 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2407 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2408 .ArgConstraint(NotNull(ArgNo(0)))
2409 .ArgConstraint(NotNull(ArgNo(1))));
2412 addToFunctionSummaryMap(
2414 Signature(ArgTypes{ConstCharPtrTy, IntTy, ConstCharPtrTy},
2417 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2418 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2419 .ArgConstraint(NotNull(ArgNo(0)))
2420 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(1)))
2421 .ArgConstraint(NotNull(ArgNo(2))));
2424 addToFunctionSummaryMap(
2425 "lockf", Signature(ArgTypes{IntTy, IntTy, Off_tTy}, RetType{IntTy}),
2427 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2428 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2430 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2432 std::optional<QualType> Mode_tTy = lookupTy(
"mode_t");
2435 addToFunctionSummaryMap(
2436 "creat", Signature(ArgTypes{ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
2438 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2440 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2441 .ArgConstraint(NotNull(ArgNo(0))));
2444 addToFunctionSummaryMap(
2445 "sleep", Signature(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}),
2448 ArgumentCondition(0, WithinRange,
Range(0, UnsignedIntMax))));
2450 std::optional<QualType> DirTy = lookupTy(
"DIR");
2451 std::optional<QualType> DirPtrTy = getPointerTy(DirTy);
2454 addToFunctionSummaryMap(
2455 "dirfd", Signature(ArgTypes{DirPtrTy}, RetType{IntTy}),
2457 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2459 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2460 .ArgConstraint(NotNull(ArgNo(0))));
2463 addToFunctionSummaryMap(
2464 "alarm", Signature(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}),
2467 ArgumentCondition(0, WithinRange,
Range(0, UnsignedIntMax))));
2470 addToFunctionSummaryMap(
2471 "closedir", Signature(ArgTypes{DirPtrTy}, RetType{IntTy}),
2473 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2474 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2475 .ArgConstraint(NotNull(ArgNo(0))));
2478 addToFunctionSummaryMap(
2479 "strdup", Signature(ArgTypes{ConstCharPtrTy}, RetType{CharPtrTy}),
2480 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2483 addToFunctionSummaryMap(
2485 Signature(ArgTypes{ConstCharPtrTy, SizeTy}, RetType{CharPtrTy}),
2487 .ArgConstraint(NotNull(ArgNo(0)))
2489 ArgumentCondition(1, WithinRange,
Range(0, SizeMax))));
2492 addToFunctionSummaryMap(
2493 "wcsdup", Signature(ArgTypes{ConstWchar_tPtrTy}, RetType{Wchar_tPtrTy}),
2494 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2497 addToFunctionSummaryMap(
2498 "mkstemp", Signature(ArgTypes{CharPtrTy}, RetType{IntTy}),
2500 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2502 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2503 .ArgConstraint(NotNull(ArgNo(0))));
2507 addToFunctionSummaryMap(
2508 "mkdtemp", Signature(ArgTypes{CharPtrTy}, RetType{CharPtrTy}),
2509 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2513 addToFunctionSummaryMap(
2514 "getcwd", Signature(ArgTypes{CharPtrTy, SizeTy}, RetType{CharPtrTy}),
2517 ArgumentCondition(1, WithinRange,
Range(0, SizeMax))));
2520 addToFunctionSummaryMap(
2521 "mkdir", Signature(ArgTypes{ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
2523 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2524 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2525 .ArgConstraint(NotNull(ArgNo(0))));
2528 addToFunctionSummaryMap(
2530 Signature(ArgTypes{IntTy, ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
2532 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2533 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2534 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2535 .ArgConstraint(NotNull(ArgNo(1))));
2537 std::optional<QualType> Dev_tTy = lookupTy(
"dev_t");
2540 addToFunctionSummaryMap(
2542 Signature(ArgTypes{ConstCharPtrTy, Mode_tTy, Dev_tTy}, RetType{IntTy}),
2544 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2545 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2546 .ArgConstraint(NotNull(ArgNo(0))));
2549 addToFunctionSummaryMap(
2551 Signature(ArgTypes{IntTy, ConstCharPtrTy, Mode_tTy, Dev_tTy},
2554 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2555 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2556 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2557 .ArgConstraint(NotNull(ArgNo(1))));
2560 addToFunctionSummaryMap(
2561 "chmod", Signature(ArgTypes{ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
2563 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2564 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2565 .ArgConstraint(NotNull(ArgNo(0))));
2568 addToFunctionSummaryMap(
2570 Signature(ArgTypes{IntTy, ConstCharPtrTy, Mode_tTy, IntTy},
2573 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2574 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2575 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2576 .ArgConstraint(NotNull(ArgNo(1))));
2579 addToFunctionSummaryMap(
2580 "fchmod", Signature(ArgTypes{IntTy, Mode_tTy}, RetType{IntTy}),
2582 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2583 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2585 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2587 std::optional<QualType> Uid_tTy = lookupTy(
"uid_t");
2588 std::optional<QualType> Gid_tTy = lookupTy(
"gid_t");
2592 addToFunctionSummaryMap(
2594 Signature(ArgTypes{IntTy, ConstCharPtrTy, Uid_tTy, Gid_tTy, IntTy},
2597 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2598 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2599 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2600 .ArgConstraint(NotNull(ArgNo(1))));
2603 addToFunctionSummaryMap(
2605 Signature(ArgTypes{ConstCharPtrTy, Uid_tTy, Gid_tTy}, RetType{IntTy}),
2607 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2608 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2609 .ArgConstraint(NotNull(ArgNo(0))));
2612 addToFunctionSummaryMap(
2614 Signature(ArgTypes{ConstCharPtrTy, Uid_tTy, Gid_tTy}, RetType{IntTy}),
2616 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2617 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2618 .ArgConstraint(NotNull(ArgNo(0))));
2621 addToFunctionSummaryMap(
2622 "fchown", Signature(ArgTypes{IntTy, Uid_tTy, Gid_tTy}, RetType{IntTy}),
2624 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2625 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2627 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2630 addToFunctionSummaryMap(
2631 "rmdir", Signature(ArgTypes{ConstCharPtrTy}, RetType{IntTy}),
2633 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2634 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2635 .ArgConstraint(NotNull(ArgNo(0))));
2638 addToFunctionSummaryMap(
2639 "chdir", Signature(ArgTypes{ConstCharPtrTy}, RetType{IntTy}),
2641 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2642 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2643 .ArgConstraint(NotNull(ArgNo(0))));
2646 addToFunctionSummaryMap(
2648 Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{IntTy}),
2650 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2651 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2652 .ArgConstraint(NotNull(ArgNo(0)))
2653 .ArgConstraint(NotNull(ArgNo(1))));
2657 addToFunctionSummaryMap(
2659 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy, ConstCharPtrTy, IntTy},
2662 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2663 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2664 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2665 .ArgConstraint(NotNull(ArgNo(1)))
2666 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(2)))
2667 .ArgConstraint(NotNull(ArgNo(3))));
2670 addToFunctionSummaryMap(
2671 "unlink", Signature(ArgTypes{ConstCharPtrTy}, RetType{IntTy}),
2673 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2674 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2675 .ArgConstraint(NotNull(ArgNo(0))));
2678 addToFunctionSummaryMap(
2680 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy}, RetType{IntTy}),
2682 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2683 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2684 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2685 .ArgConstraint(NotNull(ArgNo(1))));
2687 std::optional<QualType> StructStatTy = lookupTy(
"stat");
2688 std::optional<QualType> StructStatPtrTy = getPointerTy(StructStatTy);
2689 std::optional<QualType> StructStatPtrRestrictTy =
2690 getRestrictTy(StructStatPtrTy);
2693 addToFunctionSummaryMap(
2694 "fstat", Signature(ArgTypes{IntTy, StructStatPtrTy}, RetType{IntTy}),
2696 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2697 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2698 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
2699 .ArgConstraint(NotNull(ArgNo(1))));
2702 addToFunctionSummaryMap(
2704 Signature(ArgTypes{ConstCharPtrRestrictTy, StructStatPtrRestrictTy},
2707 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2708 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2709 .ArgConstraint(NotNull(ArgNo(0)))
2710 .ArgConstraint(NotNull(ArgNo(1))));
2713 addToFunctionSummaryMap(
2715 Signature(ArgTypes{ConstCharPtrRestrictTy, StructStatPtrRestrictTy},
2718 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2719 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2720 .ArgConstraint(NotNull(ArgNo(0)))
2721 .ArgConstraint(NotNull(ArgNo(1))));
2725 addToFunctionSummaryMap(
2727 Signature(ArgTypes{IntTy, ConstCharPtrRestrictTy,
2728 StructStatPtrRestrictTy, IntTy},
2731 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2732 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2733 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2734 .ArgConstraint(NotNull(ArgNo(1)))
2735 .ArgConstraint(NotNull(ArgNo(2))));
2739 addToFunctionSummaryMap(
2740 "opendir", Signature(ArgTypes{ConstCharPtrTy}, RetType{DirPtrTy}),
2741 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2745 addToFunctionSummaryMap(
"fdopendir",
2746 Signature(ArgTypes{IntTy}, RetType{DirPtrTy}),
2748 .ArgConstraint(ArgumentCondition(
2749 0, WithinRange,
Range(0, IntMax))));
2752 addToFunctionSummaryMap(
2753 "isatty", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2755 .Case({ReturnValueCondition(WithinRange,
Range(0, 1))},
2758 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2762 addToFunctionSummaryMap(
2764 Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}),
2766 .ArgConstraint(NotNull(ArgNo(0)))
2767 .ArgConstraint(NotNull(ArgNo(1))));
2771 addToFunctionSummaryMap(
2772 "pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2773 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2776 addToFunctionSummaryMap(
2777 "close", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2779 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2780 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2782 ArgumentCondition(0, WithinRange,
Range(-1, IntMax))));
2785 addToFunctionSummaryMap(
"fpathconf",
2786 Signature(ArgTypes{IntTy, IntTy}, RetType{LongTy}),
2788 .ArgConstraint(ArgumentCondition(
2789 0, WithinRange,
Range(0, IntMax))));
2792 addToFunctionSummaryMap(
2793 "pathconf", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{LongTy}),
2794 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2798 addToFunctionSummaryMap(
2800 Signature(ArgTypes{IntTy, ConstCharPtrTy}, RetType{FilePtrTy}),
2802 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
2803 .ArgConstraint(NotNull(ArgNo(1))));
2806 addToFunctionSummaryMap(
2807 "rewinddir", Signature(ArgTypes{DirPtrTy}, RetType{VoidTy}),
2808 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2811 addToFunctionSummaryMap(
2812 "seekdir", Signature(ArgTypes{DirPtrTy, LongTy}, RetType{VoidTy}),
2813 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2816 addToFunctionSummaryMap(
2817 "rand_r", Signature(ArgTypes{UnsignedIntPtrTy}, RetType{IntTy}),
2818 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2821 addToFunctionSummaryMap(
2823 Signature(ArgTypes{FilePtrTy, Off_tTy, IntTy}, RetType{IntTy}),
2825 .Case(ReturnsZeroOrMinusOne, ErrnoIrrelevant)
2826 .ArgConstraint(NotNull(ArgNo(0))));
2829 addToFunctionSummaryMap(
2830 "ftello", Signature(ArgTypes{FilePtrTy}, RetType{Off_tTy}),
2831 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2836 addToFunctionSummaryMap(
2838 Signature(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, Off_tTy},
2839 RetType{VoidPtrTy}),
2841 .ArgConstraint(ArgumentCondition(1, WithinRange,
Range(1, SizeMax)))
2843 ArgumentCondition(4, WithinRange,
Range(-1, IntMax))));
2845 std::optional<QualType> Off64_tTy = lookupTy(
"off64_t");
2849 addToFunctionSummaryMap(
2851 Signature(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, Off64_tTy},
2852 RetType{VoidPtrTy}),
2854 .ArgConstraint(ArgumentCondition(1, WithinRange,
Range(1, SizeMax)))
2856 ArgumentCondition(4, WithinRange,
Range(-1, IntMax))));
2859 addToFunctionSummaryMap(
2860 "pipe", Signature(ArgTypes{IntPtrTy}, RetType{IntTy}),
2862 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2863 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2864 .ArgConstraint(NotNull(ArgNo(0))));
2871 addToFunctionSummaryMap(
2872 "lseek", Signature(ArgTypes{IntTy, Off_tTy, IntTy}, RetType{Off_tTy}),
2874 .Case(ReturnsNonnegative, ErrnoIrrelevant)
2875 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2877 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2881 addToFunctionSummaryMap(
2883 Signature(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy},
2884 RetType{Ssize_tTy}),
2886 .Case({ArgumentCondition(2, WithinRange,
Range(1, IntMax)),
2887 ReturnValueCondition(LessThanOrEq, ArgNo(2)),
2888 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
2889 ErrnoMustNotBeChecked, GenericSuccessMsg)
2890 .Case({ArgumentCondition(2, WithinRange, SingleValue(0)),
2891 ReturnValueCondition(WithinRange, SingleValue(0))},
2892 ErrnoMustNotBeChecked,
2893 "Assuming that argument 'bufsize' is 0")
2894 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2895 .ArgConstraint(NotNull(ArgNo(0)))
2896 .ArgConstraint(NotNull(ArgNo(1)))
2897 .ArgConstraint(BufferSize(ArgNo(1),
2900 ArgumentCondition(2, WithinRange,
Range(0, SizeMax))));
2904 addToFunctionSummaryMap(
2907 ArgTypes{IntTy, ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy},
2908 RetType{Ssize_tTy}),
2910 .Case({ArgumentCondition(3, WithinRange,
Range(1, IntMax)),
2911 ReturnValueCondition(LessThanOrEq, ArgNo(3)),
2912 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
2913 ErrnoMustNotBeChecked, GenericSuccessMsg)
2914 .Case({ArgumentCondition(3, WithinRange, SingleValue(0)),
2915 ReturnValueCondition(WithinRange, SingleValue(0))},
2916 ErrnoMustNotBeChecked,
2917 "Assuming that argument 'bufsize' is 0")
2918 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2919 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2920 .ArgConstraint(NotNull(ArgNo(1)))
2921 .ArgConstraint(NotNull(ArgNo(2)))
2922 .ArgConstraint(BufferSize(ArgNo(2),
2925 ArgumentCondition(3, WithinRange,
Range(0, SizeMax))));
2929 addToFunctionSummaryMap(
2931 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy, ConstCharPtrTy},
2934 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2935 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2936 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2937 .ArgConstraint(NotNull(ArgNo(1)))
2938 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(2)))
2939 .ArgConstraint(NotNull(ArgNo(3))));
2944 addToFunctionSummaryMap(
2946 Signature(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy},
2947 RetType{CharPtrTy}),
2948 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2950 QualType CharPtrConstPtr = getPointerTy(getConstTy(CharPtrTy));
2953 addToFunctionSummaryMap(
2955 Signature(ArgTypes{ConstCharPtrTy, CharPtrConstPtr}, RetType{IntTy}),
2957 .Case({ReturnValueCondition(WithinRange, SingleValue(-1))},
2959 .ArgConstraint(NotNull(ArgNo(0))));
2962 addToFunctionSummaryMap(
2964 Signature(ArgTypes{ConstCharPtrTy, CharPtrConstPtr}, RetType{IntTy}),
2966 .Case({ReturnValueCondition(WithinRange, SingleValue(-1))},
2968 .ArgConstraint(NotNull(ArgNo(0))));
2971 addToFunctionSummaryMap(
2973 Signature(ArgTypes{IntTy, CharPtrConstPtr, ConstCharPtrTy},
2976 .Case({ReturnValueCondition(WithinRange,
Range(-1, UCharRangeMax))},
2978 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
2979 .ArgConstraint(NotNull(ArgNo(1)))
2980 .ArgConstraint(NotNull(ArgNo(2))));
2982 std::optional<QualType> StructSockaddrTy = lookupTy(
"sockaddr");
2983 std::optional<QualType> StructSockaddrPtrTy =
2984 getPointerTy(StructSockaddrTy);
2985 std::optional<QualType> ConstStructSockaddrPtrTy =
2986 getPointerTy(getConstTy(StructSockaddrTy));
2987 std::optional<QualType> StructSockaddrPtrRestrictTy =
2988 getRestrictTy(StructSockaddrPtrTy);
2989 std::optional<QualType> ConstStructSockaddrPtrRestrictTy =
2990 getRestrictTy(ConstStructSockaddrPtrTy);
2991 std::optional<QualType> Socklen_tTy = lookupTy(
"socklen_t");
2992 std::optional<QualType> Socklen_tPtrTy = getPointerTy(Socklen_tTy);
2993 std::optional<QualType> Socklen_tPtrRestrictTy =
2994 getRestrictTy(Socklen_tPtrTy);
2995 std::optional<RangeInt> Socklen_tMax = getMaxValue(Socklen_tTy);
3005 addToFunctionSummaryMap(
3006 "socket", Signature(ArgTypes{IntTy, IntTy, IntTy}, RetType{IntTy}),
3008 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
3010 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg));
3014 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
3016 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3017 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)));
3018 if (!addToFunctionSummaryMap(
3022 Signature(ArgTypes{IntTy, StructSockaddrPtrRestrictTy,
3023 Socklen_tPtrRestrictTy},
3026 addToFunctionSummaryMap(
3028 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tPtrRestrictTy},
3034 if (!addToFunctionSummaryMap(
3036 Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy},
3039 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3040 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3042 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3043 .ArgConstraint(NotNull(ArgNo(1)))
3045 BufferSize(ArgNo(1), ArgNo(2)))
3047 ArgumentCondition(2, WithinRange,
Range(0, Socklen_tMax)))))
3049 addToFunctionSummaryMap(
3051 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tTy}, RetType{IntTy}),
3053 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3054 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3056 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3058 ArgumentCondition(2, WithinRange,
Range(0, Socklen_tMax))));
3062 if (!addToFunctionSummaryMap(
3064 Signature(ArgTypes{IntTy, StructSockaddrPtrRestrictTy,
3065 Socklen_tPtrRestrictTy},
3068 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3069 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3071 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3072 .ArgConstraint(NotNull(ArgNo(1)))
3073 .ArgConstraint(NotNull(ArgNo(2)))))
3074 addToFunctionSummaryMap(
3076 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tPtrRestrictTy},
3079 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3080 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3082 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3086 if (!addToFunctionSummaryMap(
3088 Signature(ArgTypes{IntTy, StructSockaddrPtrRestrictTy,
3089 Socklen_tPtrRestrictTy},
3092 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3093 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3095 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3096 .ArgConstraint(NotNull(ArgNo(1)))
3097 .ArgConstraint(NotNull(ArgNo(2)))))
3098 addToFunctionSummaryMap(
3100 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tPtrRestrictTy},
3103 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3104 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3106 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3110 if (!addToFunctionSummaryMap(
3112 Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy},
3115 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3116 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3118 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3119 .ArgConstraint(NotNull(ArgNo(1)))))
3120 addToFunctionSummaryMap(
3122 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tTy}, RetType{IntTy}),
3124 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3125 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3127 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3131 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
3132 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3133 ErrnoMustNotBeChecked, GenericSuccessMsg)
3134 .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
3135 ArgumentCondition(2, WithinRange, SingleValue(0))},
3136 ErrnoMustNotBeChecked, GenericSuccessMsg)
3137 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3138 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3139 .ArgConstraint(BufferSize(ArgNo(1),
3141 if (!addToFunctionSummaryMap(
3147 Signature(ArgTypes{IntTy, VoidPtrRestrictTy, SizeTy, IntTy,
3148 StructSockaddrPtrRestrictTy,
3149 Socklen_tPtrRestrictTy},
3150 RetType{Ssize_tTy}),
3152 addToFunctionSummaryMap(
3154 Signature(ArgTypes{IntTy, VoidPtrRestrictTy, SizeTy, IntTy,
3156 RetType{Ssize_tTy}),
3161 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
3162 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3163 ErrnoMustNotBeChecked, GenericSuccessMsg)
3164 .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
3165 ArgumentCondition(2, WithinRange, SingleValue(0))},
3166 ErrnoMustNotBeChecked, GenericSuccessMsg)
3167 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3168 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3169 .ArgConstraint(BufferSize(ArgNo(1),
3171 if (!addToFunctionSummaryMap(
3176 Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy,
3177 ConstStructSockaddrPtrTy, Socklen_tTy},
3178 RetType{Ssize_tTy}),
3180 addToFunctionSummaryMap(
3182 Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy,
Irrelevant,
3184 RetType{Ssize_tTy}),
3188 addToFunctionSummaryMap(
3189 "listen", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
3191 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3192 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3194 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3197 addToFunctionSummaryMap(
3199 Signature(ArgTypes{IntTy, VoidPtrTy, SizeTy, IntTy},
3200 RetType{Ssize_tTy}),
3202 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
3203 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3204 ErrnoMustNotBeChecked, GenericSuccessMsg)
3205 .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
3206 ArgumentCondition(2, WithinRange, SingleValue(0))},
3207 ErrnoMustNotBeChecked, GenericSuccessMsg)
3208 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3209 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3210 .ArgConstraint(BufferSize(ArgNo(1),
3213 std::optional<QualType> StructMsghdrTy = lookupTy(
"msghdr");
3214 std::optional<QualType> StructMsghdrPtrTy = getPointerTy(StructMsghdrTy);
3215 std::optional<QualType> ConstStructMsghdrPtrTy =
3216 getPointerTy(getConstTy(StructMsghdrTy));
3219 addToFunctionSummaryMap(
3221 Signature(ArgTypes{IntTy, StructMsghdrPtrTy, IntTy},
3222 RetType{Ssize_tTy}),
3224 .Case({ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3225 ErrnoMustNotBeChecked, GenericSuccessMsg)
3226 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3228 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3231 addToFunctionSummaryMap(
3233 Signature(ArgTypes{IntTy, ConstStructMsghdrPtrTy, IntTy},
3234 RetType{Ssize_tTy}),
3236 .Case({ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3237 ErrnoMustNotBeChecked, GenericSuccessMsg)
3238 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3240 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3244 addToFunctionSummaryMap(
3246 Signature(ArgTypes{IntTy, IntTy, IntTy, ConstVoidPtrTy, Socklen_tTy},
3249 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3250 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3251 .ArgConstraint(NotNull(ArgNo(3)))
3253 BufferSize(ArgNo(3), ArgNo(4)))
3255 ArgumentCondition(4, WithinRange,
Range(0, Socklen_tMax))));
3260 addToFunctionSummaryMap(
3262 Signature(ArgTypes{IntTy, IntTy, IntTy, VoidPtrRestrictTy,
3263 Socklen_tPtrRestrictTy},
3266 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3267 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3268 .ArgConstraint(NotNull(ArgNo(3)))
3269 .ArgConstraint(NotNull(ArgNo(4))));
3272 addToFunctionSummaryMap(
3274 Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy},
3275 RetType{Ssize_tTy}),
3277 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
3278 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3279 ErrnoMustNotBeChecked, GenericSuccessMsg)
3280 .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
3281 ArgumentCondition(2, WithinRange, SingleValue(0))},
3282 ErrnoMustNotBeChecked, GenericSuccessMsg)
3283 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3284 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3285 .ArgConstraint(BufferSize(ArgNo(1),
3289 addToFunctionSummaryMap(
3291 Signature(ArgTypes{IntTy, IntTy, IntTy, IntPtrTy}, RetType{IntTy}),
3293 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3294 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3295 .ArgConstraint(NotNull(ArgNo(3))));
3298 addToFunctionSummaryMap(
3299 "shutdown", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
3301 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3302 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3304 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3313 addToFunctionSummaryMap(
3315 Signature(ArgTypes{ConstStructSockaddrPtrRestrictTy, Socklen_tTy,
3316 CharPtrRestrictTy, Socklen_tTy, CharPtrRestrictTy,
3317 Socklen_tTy, IntTy},
3321 BufferSize(ArgNo(0), ArgNo(1)))
3323 ArgumentCondition(1, WithinRange,
Range(0, Socklen_tMax)))
3325 BufferSize(ArgNo(2), ArgNo(3)))
3327 ArgumentCondition(3, WithinRange,
Range(0, Socklen_tMax)))
3329 BufferSize(ArgNo(4), ArgNo(5)))
3331 ArgumentCondition(5, WithinRange,
Range(0, Socklen_tMax))));
3333 std::optional<QualType> StructUtimbufTy = lookupTy(
"utimbuf");
3334 std::optional<QualType> StructUtimbufPtrTy = getPointerTy(StructUtimbufTy);
3337 addToFunctionSummaryMap(
3339 Signature(ArgTypes{ConstCharPtrTy, StructUtimbufPtrTy}, RetType{IntTy}),
3341 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3342 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3343 .ArgConstraint(NotNull(ArgNo(0))));
3345 std::optional<QualType> StructTimespecTy = lookupTy(
"timespec");
3346 std::optional<QualType> StructTimespecPtrTy =
3347 getPointerTy(StructTimespecTy);
3348 std::optional<QualType> ConstStructTimespecPtrTy =
3349 getPointerTy(getConstTy(StructTimespecTy));
3352 addToFunctionSummaryMap(
3354 Signature(ArgTypes{IntTy, ConstStructTimespecPtrTy}, RetType{IntTy}),
3356 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3357 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3359 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3363 addToFunctionSummaryMap(
3366 ArgTypes{IntTy, ConstCharPtrTy, ConstStructTimespecPtrTy, IntTy},
3369 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3370 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3371 .ArgConstraint(NotNull(ArgNo(1))));
3373 std::optional<QualType> StructTimevalTy = lookupTy(
"timeval");
3374 std::optional<QualType> ConstStructTimevalPtrTy =
3375 getPointerTy(getConstTy(StructTimevalTy));
3378 addToFunctionSummaryMap(
3380 Signature(ArgTypes{ConstCharPtrTy, ConstStructTimevalPtrTy},
3383 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3384 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3385 .ArgConstraint(NotNull(ArgNo(0))));
3388 addToFunctionSummaryMap(
3390 Signature(ArgTypes{ConstStructTimespecPtrTy, StructTimespecPtrTy},
3393 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3394 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3395 .ArgConstraint(NotNull(ArgNo(0))));
3397 std::optional<QualType> Time_tTy = lookupTy(
"time_t");
3398 std::optional<QualType> ConstTime_tPtrTy =
3399 getPointerTy(getConstTy(Time_tTy));
3400 std::optional<QualType> ConstTime_tPtrRestrictTy =
3401 getRestrictTy(ConstTime_tPtrTy);
3403 std::optional<QualType> StructTmTy = lookupTy(
"tm");
3404 std::optional<QualType> StructTmPtrTy = getPointerTy(StructTmTy);
3405 std::optional<QualType> StructTmPtrRestrictTy =
3406 getRestrictTy(StructTmPtrTy);
3407 std::optional<QualType> ConstStructTmPtrTy =
3408 getPointerTy(getConstTy(StructTmTy));
3409 std::optional<QualType> ConstStructTmPtrRestrictTy =
3410 getRestrictTy(ConstStructTmPtrTy);
3413 addToFunctionSummaryMap(
3415 Signature(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}),
3416 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3420 addToFunctionSummaryMap(
3422 Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
3423 RetType{StructTmPtrTy}),
3425 .ArgConstraint(NotNull(ArgNo(0)))
3426 .ArgConstraint(NotNull(ArgNo(1))));
3429 addToFunctionSummaryMap(
3431 Signature(ArgTypes{ConstStructTmPtrRestrictTy, CharPtrRestrictTy},
3432 RetType{CharPtrTy}),
3434 .ArgConstraint(NotNull(ArgNo(0)))
3435 .ArgConstraint(NotNull(ArgNo(1)))
3436 .ArgConstraint(BufferSize(ArgNo(1),
3437 BVF.getValue(26, IntTy))));
3440 addToFunctionSummaryMap(
3442 Signature(ArgTypes{ConstTime_tPtrTy, CharPtrTy}, RetType{CharPtrTy}),
3444 .ArgConstraint(NotNull(ArgNo(0)))
3445 .ArgConstraint(NotNull(ArgNo(1)))
3446 .ArgConstraint(BufferSize(
3448 BVF.getValue(26, IntTy))));
3452 addToFunctionSummaryMap(
3454 Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
3455 RetType{StructTmPtrTy}),
3457 .ArgConstraint(NotNull(ArgNo(0)))
3458 .ArgConstraint(NotNull(ArgNo(1))));
3461 addToFunctionSummaryMap(
3462 "gmtime", Signature(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}),
3463 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3465 std::optional<QualType> Clockid_tTy = lookupTy(
"clockid_t");
3468 addToFunctionSummaryMap(
3470 Signature(ArgTypes{Clockid_tTy, StructTimespecPtrTy}, RetType{IntTy}),
3472 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3473 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3474 .ArgConstraint(NotNull(ArgNo(1))));
3476 std::optional<QualType> StructItimervalTy = lookupTy(
"itimerval");
3477 std::optional<QualType> StructItimervalPtrTy =
3478 getPointerTy(StructItimervalTy);
3481 addToFunctionSummaryMap(
3483 Signature(ArgTypes{IntTy, StructItimervalPtrTy}, RetType{IntTy}),
3485 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3486 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3487 .ArgConstraint(NotNull(ArgNo(1))));
3489 std::optional<QualType> Pthread_cond_tTy = lookupTy(
"pthread_cond_t");
3490 std::optional<QualType> Pthread_cond_tPtrTy =
3491 getPointerTy(Pthread_cond_tTy);
3492 std::optional<QualType> Pthread_tTy = lookupTy(
"pthread_t");
3493 std::optional<QualType> Pthread_tPtrTy = getPointerTy(Pthread_tTy);
3494 std::optional<QualType> Pthread_tPtrRestrictTy =
3495 getRestrictTy(Pthread_tPtrTy);
3496 std::optional<QualType> Pthread_mutex_tTy = lookupTy(
"pthread_mutex_t");
3497 std::optional<QualType> Pthread_mutex_tPtrTy =
3498 getPointerTy(Pthread_mutex_tTy);
3499 std::optional<QualType> Pthread_mutex_tPtrRestrictTy =
3500 getRestrictTy(Pthread_mutex_tPtrTy);
3501 std::optional<QualType> Pthread_attr_tTy = lookupTy(
"pthread_attr_t");
3502 std::optional<QualType> Pthread_attr_tPtrTy =
3503 getPointerTy(Pthread_attr_tTy);
3504 std::optional<QualType> ConstPthread_attr_tPtrTy =
3505 getPointerTy(getConstTy(Pthread_attr_tTy));
3506 std::optional<QualType> ConstPthread_attr_tPtrRestrictTy =
3507 getRestrictTy(ConstPthread_attr_tPtrTy);
3508 std::optional<QualType> Pthread_mutexattr_tTy =
3509 lookupTy(
"pthread_mutexattr_t");
3510 std::optional<QualType> ConstPthread_mutexattr_tPtrTy =
3511 getPointerTy(getConstTy(Pthread_mutexattr_tTy));
3512 std::optional<QualType> ConstPthread_mutexattr_tPtrRestrictTy =
3513 getRestrictTy(ConstPthread_mutexattr_tPtrTy);
3515 QualType PthreadStartRoutineTy = getPointerTy(
3521 addToFunctionSummaryMap(
3522 {
"pthread_cond_signal",
"pthread_cond_broadcast"},
3523 Signature(ArgTypes{Pthread_cond_tPtrTy}, RetType{IntTy}),
3524 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3529 addToFunctionSummaryMap(
3531 Signature(ArgTypes{Pthread_tPtrRestrictTy,
3532 ConstPthread_attr_tPtrRestrictTy,
3533 PthreadStartRoutineTy, VoidPtrRestrictTy},
3536 .ArgConstraint(NotNull(ArgNo(0)))
3537 .ArgConstraint(NotNull(ArgNo(2))));
3541 addToFunctionSummaryMap(
3542 {
"pthread_attr_destroy",
"pthread_attr_init"},
3543 Signature(ArgTypes{Pthread_attr_tPtrTy}, RetType{IntTy}),
3544 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3550 addToFunctionSummaryMap(
3551 {
"pthread_attr_getstacksize",
"pthread_attr_getguardsize"},
3552 Signature(ArgTypes{ConstPthread_attr_tPtrRestrictTy, SizePtrRestrictTy},
3555 .ArgConstraint(NotNull(ArgNo(0)))
3556 .ArgConstraint(NotNull(ArgNo(1))));
3560 addToFunctionSummaryMap(
3561 {
"pthread_attr_setstacksize",
"pthread_attr_setguardsize"},
3562 Signature(ArgTypes{Pthread_attr_tPtrTy, SizeTy}, RetType{IntTy}),
3564 .ArgConstraint(NotNull(ArgNo(0)))
3566 ArgumentCondition(1, WithinRange,
Range(0, SizeMax))));
3570 addToFunctionSummaryMap(
3571 "pthread_mutex_init",
3572 Signature(ArgTypes{Pthread_mutex_tPtrRestrictTy,
3573 ConstPthread_mutexattr_tPtrRestrictTy},
3575 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3581 addToFunctionSummaryMap(
3582 {
"pthread_mutex_destroy",
"pthread_mutex_lock",
"pthread_mutex_trylock",
3583 "pthread_mutex_unlock"},
3584 Signature(ArgTypes{Pthread_mutex_tPtrTy}, RetType{IntTy}),
3585 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3589 if (AddTestFunctions) {
3590 const RangeInt IntMin = BVF.
getMinValue(IntTy).getLimitedValue();
3592 addToFunctionSummaryMap(
3593 "__not_null", Signature(ArgTypes{IntPtrTy}, RetType{IntTy}),
3594 Summary(EvalCallAsPure).ArgConstraint(NotNull(ArgNo(0))));
3596 addToFunctionSummaryMap(
3597 "__not_null_buffer",
3598 Signature(ArgTypes{VoidPtrTy, IntTy, IntTy}, RetType{IntTy}),
3599 Summary(EvalCallAsPure)
3600 .ArgConstraint(NotNullBuffer(ArgNo(0), ArgNo(1), ArgNo(2))));
3603 addToFunctionSummaryMap(
3604 "__single_val_0", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3605 Summary(EvalCallAsPure)
3606 .ArgConstraint(ArgumentCondition(0
U, WithinRange, SingleValue(0))));
3607 addToFunctionSummaryMap(
3608 "__single_val_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3609 Summary(EvalCallAsPure)
3610 .ArgConstraint(ArgumentCondition(0
U, WithinRange, SingleValue(1))));
3611 addToFunctionSummaryMap(
3612 "__range_1_2", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3613 Summary(EvalCallAsPure)
3614 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
Range(1, 2))));
3615 addToFunctionSummaryMap(
3616 "__range_m1_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3617 Summary(EvalCallAsPure)
3618 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
Range(-1, 1))));
3619 addToFunctionSummaryMap(
3620 "__range_m2_m1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3621 Summary(EvalCallAsPure)
3622 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
Range(-2, -1))));
3623 addToFunctionSummaryMap(
3624 "__range_m10_10", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3625 Summary(EvalCallAsPure)
3626 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
Range(-10, 10))));
3627 addToFunctionSummaryMap(
"__range_m1_inf",
3628 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3629 Summary(EvalCallAsPure)
3630 .ArgConstraint(ArgumentCondition(
3631 0
U, WithinRange,
Range(-1, IntMax))));
3632 addToFunctionSummaryMap(
"__range_0_inf",
3633 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3634 Summary(EvalCallAsPure)
3635 .ArgConstraint(ArgumentCondition(
3636 0
U, WithinRange,
Range(0, IntMax))));
3637 addToFunctionSummaryMap(
"__range_1_inf",
3638 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3639 Summary(EvalCallAsPure)
3640 .ArgConstraint(ArgumentCondition(
3641 0
U, WithinRange,
Range(1, IntMax))));
3642 addToFunctionSummaryMap(
"__range_minf_m1",
3643 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3644 Summary(EvalCallAsPure)
3645 .ArgConstraint(ArgumentCondition(
3646 0
U, WithinRange,
Range(IntMin, -1))));
3647 addToFunctionSummaryMap(
"__range_minf_0",
3648 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3649 Summary(EvalCallAsPure)
3650 .ArgConstraint(ArgumentCondition(
3651 0
U, WithinRange,
Range(IntMin, 0))));
3652 addToFunctionSummaryMap(
"__range_minf_1",
3653 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3654 Summary(EvalCallAsPure)
3655 .ArgConstraint(ArgumentCondition(
3656 0
U, WithinRange,
Range(IntMin, 1))));
3657 addToFunctionSummaryMap(
"__range_1_2__4_6",
3658 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3659 Summary(EvalCallAsPure)
3660 .ArgConstraint(ArgumentCondition(
3661 0
U, WithinRange,
Range({1, 2}, {4, 6}))));
3662 addToFunctionSummaryMap(
3663 "__range_1_2__4_inf", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3664 Summary(EvalCallAsPure)
3665 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
3666 Range({1, 2}, {4, IntMax}))));
3669 addToFunctionSummaryMap(
3670 "__single_val_out_0", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3671 Summary(EvalCallAsPure)
3672 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(0))));
3673 addToFunctionSummaryMap(
3674 "__single_val_out_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3675 Summary(EvalCallAsPure)
3676 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(1))));
3677 addToFunctionSummaryMap(
3678 "__range_out_1_2", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3679 Summary(EvalCallAsPure)
3680 .ArgConstraint(ArgumentCondition(0
U, OutOfRange,
Range(1, 2))));
3681 addToFunctionSummaryMap(
3682 "__range_out_m1_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3683 Summary(EvalCallAsPure)
3684 .ArgConstraint(ArgumentCondition(0
U, OutOfRange,
Range(-1, 1))));
3685 addToFunctionSummaryMap(
3686 "__range_out_m2_m1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3687 Summary(EvalCallAsPure)
3688 .ArgConstraint(ArgumentCondition(0
U, OutOfRange,
Range(-2, -1))));
3689 addToFunctionSummaryMap(
3690 "__range_out_m10_10", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3691 Summary(EvalCallAsPure)
3692 .ArgConstraint(ArgumentCondition(0
U, OutOfRange,
Range(-10, 10))));
3693 addToFunctionSummaryMap(
"__range_out_m1_inf",
3694 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3695 Summary(EvalCallAsPure)
3696 .ArgConstraint(ArgumentCondition(
3697 0
U, OutOfRange,
Range(-1, IntMax))));
3698 addToFunctionSummaryMap(
"__range_out_0_inf",
3699 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3700 Summary(EvalCallAsPure)
3701 .ArgConstraint(ArgumentCondition(
3702 0
U, OutOfRange,
Range(0, IntMax))));
3703 addToFunctionSummaryMap(
"__range_out_1_inf",
3704 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3705 Summary(EvalCallAsPure)
3706 .ArgConstraint(ArgumentCondition(
3707 0
U, OutOfRange,
Range(1, IntMax))));
3708 addToFunctionSummaryMap(
"__range_out_minf_m1",
3709 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3710 Summary(EvalCallAsPure)
3711 .ArgConstraint(ArgumentCondition(
3712 0
U, OutOfRange,
Range(IntMin, -1))));
3713 addToFunctionSummaryMap(
"__range_out_minf_0",
3714 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3715 Summary(EvalCallAsPure)
3716 .ArgConstraint(ArgumentCondition(
3717 0
U, OutOfRange,
Range(IntMin, 0))));
3718 addToFunctionSummaryMap(
"__range_out_minf_1",
3719 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3720 Summary(EvalCallAsPure)
3721 .ArgConstraint(ArgumentCondition(
3722 0
U, OutOfRange,
Range(IntMin, 1))));
3723 addToFunctionSummaryMap(
"__range_out_1_2__4_6",
3724 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3725 Summary(EvalCallAsPure)
3726 .ArgConstraint(ArgumentCondition(
3727 0
U, OutOfRange,
Range({1, 2}, {4, 6}))));
3728 addToFunctionSummaryMap(
3729 "__range_out_1_2__4_inf", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3730 Summary(EvalCallAsPure)
3732 ArgumentCondition(0
U, OutOfRange,
Range({1, 2}, {4, IntMax}))));
3735 addToFunctionSummaryMap(
3736 "__within", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3737 Summary(EvalCallAsPure)
3738 .ArgConstraint(ArgumentCondition(0
U, WithinRange, SingleValue(1))));
3739 addToFunctionSummaryMap(
3740 "__out_of", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3741 Summary(EvalCallAsPure)
3742 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(1))));
3744 addToFunctionSummaryMap(
3745 "__two_constrained_args",
3746 Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
3747 Summary(EvalCallAsPure)
3748 .ArgConstraint(ArgumentCondition(0
U, WithinRange, SingleValue(1)))
3749 .ArgConstraint(ArgumentCondition(1U, WithinRange, SingleValue(1))));
3750 addToFunctionSummaryMap(
3751 "__arg_constrained_twice", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3752 Summary(EvalCallAsPure)
3753 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(1)))
3754 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(2))));
3755 addToFunctionSummaryMap(
3757 Signature(ArgTypes{
Irrelevant, IntTy}, RetType{IntTy}),
3758 Summary(EvalCallAsPure).ArgConstraint(NotNull(ArgNo(0))));
3759 addToFunctionSummaryMap(
3761 Signature(ArgTypes{VoidPtrTy, ConstCharPtrTy}, RetType{IntTy}),
3762 Summary(EvalCallAsPure)
3763 .ArgConstraint(NotNull(ArgNo(0)))
3764 .ArgConstraint(NotNull(ArgNo(1))));
3765 addToFunctionSummaryMap(
3766 "__buf_size_arg_constraint",
3767 Signature(ArgTypes{ConstVoidPtrTy, SizeTy}, RetType{IntTy}),
3768 Summary(EvalCallAsPure)
3770 BufferSize(ArgNo(0), ArgNo(1))));
3771 addToFunctionSummaryMap(
3772 "__buf_size_arg_constraint_mul",
3773 Signature(ArgTypes{ConstVoidPtrTy, SizeTy, SizeTy}, RetType{IntTy}),
3774 Summary(EvalCallAsPure)
3775 .ArgConstraint(BufferSize(ArgNo(0), ArgNo(1),
3777 addToFunctionSummaryMap(
3778 "__buf_size_arg_constraint_concrete",
3779 Signature(ArgTypes{ConstVoidPtrTy}, RetType{IntTy}),
3780 Summary(EvalCallAsPure)
3781 .ArgConstraint(BufferSize(ArgNo(0),
3782 BVF.getValue(10, IntTy))));
3783 addToFunctionSummaryMap(
3784 {
"__test_restrict_param_0",
"__test_restrict_param_1",
3785 "__test_restrict_param_2"},
3786 Signature(ArgTypes{VoidPtrRestrictTy}, RetType{VoidTy}),
3787 Summary(EvalCallAsPure));
3790 addToFunctionSummaryMap(
3791 "__test_case_note", Signature(ArgTypes{}, RetType{IntTy}),
3792 Summary(EvalCallAsPure)
3793 .Case({ReturnValueCondition(WithinRange, SingleValue(0))},
3794 ErrnoIrrelevant,
"Function returns 0")
3795 .Case({ReturnValueCondition(WithinRange, SingleValue(1))},
3796 ErrnoIrrelevant,
"Function returns 1"));
3797 addToFunctionSummaryMap(
3798 "__test_case_range_1_2__4_6",
3799 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3800 Summary(EvalCallAsPure)
3801 .Case({ArgumentCondition(0
U, WithinRange,
3802 IntRangeVector{{IntMin, 0}, {3, 3}}),
3803 ReturnValueCondition(WithinRange, SingleValue(1))},
3805 .Case({ArgumentCondition(0
U, WithinRange,
3806 IntRangeVector{{3, 3}, {7, IntMax}}),
3807 ReturnValueCondition(WithinRange, SingleValue(2))},
3809 .Case({ArgumentCondition(0
U, WithinRange,
3810 IntRangeVector{{IntMin, 0}, {7, IntMax}}),
3811 ReturnValueCondition(WithinRange, SingleValue(3))},
3813 .Case({ArgumentCondition(
3815 IntRangeVector{{IntMin, 0}, {3, 3}, {7, IntMax}}),
3816 ReturnValueCondition(WithinRange, SingleValue(4))},
3821void ento::registerStdCLibraryFunctionsChecker(
CheckerManager &mgr) {
3825 Checker->DisplayLoadedSummaries =
3828 Checker->ShouldAssumeControlledEnvironment =
3829 Opts.ShouldAssumeControlledEnvironment;
3832bool ento::shouldRegisterStdCLibraryFunctionsChecker(
3837void ento::registerStdCLibraryFunctionsTesterChecker(
CheckerManager &mgr) {
3839 Checker->AddTestFunctions =
true;
3842bool ento::shouldRegisterStdCLibraryFunctionsTesterChecker(
static bool isInvalid(LocType Loc, bool *Invalid)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const LangOptions & getLangOpts() const
QualType getRestrictType(QualType T) const
Return the uniqued reference to the type for a restrict qualified type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType UnsignedCharTy
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Stores options for the analyzer from the command line.
bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName, bool SearchInParents=false) const
Interprets an option's string value as a boolean.
static Opcode negateComparisonOp(Opcode Opc)
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
The name of a declaration.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
QualType getReturnType() const
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
size_t param_size() const
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
A (possibly-)qualified type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
void removeLocalRestrict()
const llvm::APSInt & getMaxValue(const llvm::APSInt &v)
ASTContext & getContext() const
const llvm::APSInt & getMinValue(const llvm::APSInt &v)
Represents an abstract call to a function or method along a particular path.
const AnalyzerOptions & getAnalyzerOptions() const
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
CheckerNameRef getCurrentCheckerName() const
This wrapper is used to ensure that only StringRefs originating from the CheckerRegistry are used as ...
ProgramStateRef assumeInclusiveRange(ProgramStateRef State, NonLoc Value, const llvm::APSInt &From, const llvm::APSInt &To, bool InBound)
const ProgramStateRef & getState() const
The tag upon which the TagVisitor reacts.
const ExplodedNode * getErrorNode() const
void markNotInteresting(SymbolRef sym)
bool isInteresting(SymbolRef sym) const
SValBuilder & getSValBuilder()
ConstraintManager & getConstraintManager()
A Range represents the closed range [from, to].
BasicValueFactory & getBasicValueFactory()
ASTContext & getContext()
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy)
Cast a given SVal to another SVal using given QualType's.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
QualType getConditionType() const
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
bool trackExpressionValue(const ExplodedNode *N, const Expr *E, PathSensitiveBugReport &R, TrackingOptions Opts={})
Attempts to add visitors to track expression value back to its point of origin.
const char *const LogicError
std::optional< Loc > getErrnoLoc(ProgramStateRef State)
Returns the location that points to the MemoryRegion where the 'errno' value is stored.
ProgramStateRef setErrnoForStdSuccess(ProgramStateRef State, CheckerContext &C)
Set errno state for the common case when a standard function is successful.
ProgramStateRef setErrnoState(ProgramStateRef State, ErrnoCheckState EState)
Set the errno check state, do not modify the errno value.
ProgramStateRef setErrnoStdMustBeChecked(ProgramStateRef State, CheckerContext &C, const Expr *InvalE)
Set errno state for the common case when a standard function indicates failure only by errno.
ProgramStateRef setErrnoForStdFailure(ProgramStateRef State, CheckerContext &C, NonLoc ErrnoSym)
Set errno state for the common case when a standard function fails.
@ Irrelevant
We do not know anything about 'errno'.
SVal getDynamicExtentWithOffset(ProgramStateRef State, SVal BufV)
Get the dynamic extent for a symbolic value that represents a buffer.
std::optional< int > tryExpandAsInteger(StringRef Macro, const Preprocessor &PP)
Try to parse the value of a defined preprocessor macro.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
bool matches(const til::SExpr *E1, const til::SExpr *E2)
Extra information about a function prototype.