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;
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; }
676 using RetType = std::optional<QualType>;
681 bool static isIrrelevant(
QualType T) {
return T.isNull(); }
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");
723 assert((
T.isNull() ||
T.isCanonical()) &&
724 "We should only have canonical types in the spec");
726 static void assertRetTypeSuitableForSignature(
QualType T) {
727 assert((
T.isNull() ||
T.isCanonical()) &&
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 const BugType BT_InvalidArg{
this,
"Function call with invalid argument"};
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]);
878 auto R = std::make_unique<PathSensitiveBugReport>(BT_InvalidArg, Msg, N);
880 for (ArgNo ArgN : VC->getArgsToTrack()) {
882 R->markInteresting(
Call.getArgSVal(ArgN));
884 R->addRange(
Call.getArgSourceRange(ArgN));
887 C.emitReport(std::move(R));
895 const NoErrnoConstraint ErrnoUnchanged{};
896 const ResetErrnoConstraint ErrnoIrrelevant{};
897 const ErrnoMustBeCheckedConstraint ErrnoMustBeChecked{};
898 const SuccessErrnoConstraint ErrnoMustNotBeChecked{};
899 const FailureErrnoConstraint ErrnoNEZeroIrrelevant{};
902int StdLibraryFunctionsChecker::ErrnoConstraintBase::Tag = 0;
904const StdLibraryFunctionsChecker::ArgNo StdLibraryFunctionsChecker::Ret =
905 std::numeric_limits<ArgNo>::max();
915void StdLibraryFunctionsChecker::printArgDesc(
916 StdLibraryFunctionsChecker::ArgNo ArgN, llvm::raw_ostream &Out) {
917 Out << std::to_string(ArgN + 1);
918 Out << llvm::getOrdinalSuffix(ArgN + 1);
922void StdLibraryFunctionsChecker::printArgValueInfo(ArgNo ArgN,
925 llvm::raw_ostream &Out) {
926 if (
const llvm::APSInt *Val =
927 State->getStateManager().getSValBuilder().getKnownValue(
928 State, getArgSVal(
Call, ArgN)))
929 Out <<
" (which is " << *Val <<
")";
932void StdLibraryFunctionsChecker::appendInsideRangeDesc(llvm::APSInt RMin,
936 llvm::raw_ostream &Out) {
937 if (RMin.isZero() && RMax.isZero())
939 else if (RMin == RMax)
945 Out <<
"<= " << RMax;
950 Out <<
">= " << RMin;
951 }
else if (RMin.isNegative() == RMax.isNegative() &&
952 RMin.getLimitedValue() == RMax.getLimitedValue() - 1) {
953 Out << RMin <<
" or " << RMax;
955 Out <<
"between " << RMin <<
" and " << RMax;
959void StdLibraryFunctionsChecker::appendOutOfRangeDesc(llvm::APSInt RMin,
963 llvm::raw_ostream &Out) {
964 if (RMin.isZero() && RMax.isZero())
966 else if (RMin == RMax) {
967 Out <<
"not equal to " << RMin;
978 }
else if (RMin.isNegative() == RMax.isNegative() &&
979 RMin.getLimitedValue() == RMax.getLimitedValue() - 1) {
980 Out <<
"not " << RMin <<
" and not " << RMax;
982 Out <<
"not between " << RMin <<
" and " << RMax;
986void StdLibraryFunctionsChecker::RangeConstraint::applyOnWithinRange(
991 for (
auto [Start, End] : getRanges()) {
992 const llvm::APSInt &
Min = BVF.getValue(Start, ArgT);
993 const llvm::APSInt &
Max = BVF.getValue(End, ArgT);
1000void StdLibraryFunctionsChecker::RangeConstraint::applyOnOutOfRange(
1005 const IntRangeVector &R = getRanges();
1006 size_t E = R.size();
1008 const llvm::APSInt &MinusInf = BVF.
getMinValue(ArgT);
1009 const llvm::APSInt &PlusInf = BVF.
getMaxValue(ArgT);
1011 const llvm::APSInt &RangeLeft = BVF.getValue(R[0].first - 1ULL, ArgT);
1012 const llvm::APSInt &RangeRight = BVF.getValue(R[
E - 1].second + 1ULL, ArgT);
1015 for (
size_t I = 1; I !=
E; ++I) {
1016 const llvm::APSInt &
Min = BVF.getValue(R[I - 1].second + 1ULL, ArgT);
1017 const llvm::APSInt &
Max = BVF.getValue(R[I].first - 1ULL, ArgT);
1024 if (RangeLeft != PlusInf) {
1025 assert(MinusInf <= RangeLeft);
1026 if (!F(MinusInf, RangeLeft))
1030 if (RangeRight != MinusInf) {
1031 assert(RangeRight <= PlusInf);
1032 if (!F(RangeRight, PlusInf))
1042 QualType T = Summary.getArgType(getArgNo());
1044 if (
auto N =
V.getAs<
NonLoc>()) {
1045 auto ExcludeRangeFromArg = [&](
const llvm::APSInt &
Min,
1046 const llvm::APSInt &
Max) {
1048 return static_cast<bool>(State);
1052 applyOnRange(negateKind(Kind),
C.getSValBuilder().getBasicValueFactory(),
T,
1053 ExcludeRangeFromArg);
1059void StdLibraryFunctionsChecker::RangeConstraint::describe(
1061 const Summary &Summary, llvm::raw_ostream &Out)
const {
1064 QualType T = Summary.getArgType(getArgNo());
1066 Out << ((DK == Violation) ?
"should be " :
"is ");
1067 if (!Description.empty()) {
1070 unsigned I = Ranges.size();
1071 if (Kind == WithinRange) {
1072 for (
const std::pair<RangeInt, RangeInt> &R : Ranges) {
1073 appendInsideRangeDesc(BVF.getValue(R.first,
T),
1074 BVF.getValue(R.second,
T),
T, BVF, Out);
1079 for (
const std::pair<RangeInt, RangeInt> &R : Ranges) {
1080 appendOutOfRangeDesc(BVF.getValue(R.first,
T),
1081 BVF.getValue(R.second,
T),
T, BVF, Out);
1089bool StdLibraryFunctionsChecker::RangeConstraint::describeArgumentValue(
1091 llvm::raw_ostream &Out)
const {
1092 unsigned int NRanges = 0;
1093 bool HaveAllRanges =
true;
1100 if (
auto N =
V.getAs<
NonLoc>()) {
1101 if (
const llvm::APSInt *Int = N->getAsInteger()) {
1106 QualType T = Summary.getArgType(getArgNo());
1108 llvm::raw_svector_ostream MoreInfoOs(MoreInfo);
1109 auto ApplyF = [&](
const llvm::APSInt &
Min,
const llvm::APSInt &
Max) {
1112 MoreInfoOs <<
" or ";
1113 appendInsideRangeDesc(
Min,
Max,
T, BVF, MoreInfoOs);
1116 HaveAllRanges =
false;
1121 applyOnRange(Kind, BVF,
T, ApplyF);
1122 assert(NRanges > 0);
1123 if (!HaveAllRanges || NRanges == 1) {
1132ProgramStateRef StdLibraryFunctionsChecker::ComparisonConstraint::apply(
1139 QualType T = Summary.getArgType(getArgNo());
1143 ArgNo OtherArg = getOtherArgNo();
1144 SVal OtherV = getArgSVal(
Call, OtherArg);
1145 QualType OtherT = Summary.getArgType(OtherArg);
1147 OtherV = SVB.
evalCast(OtherV,
T, OtherT);
1148 if (
auto CompV = SVB.
evalBinOp(State, Op,
V, OtherV, CondT)
1150 State = State->assume(*CompV,
true);
1165 return State->assume(L, CannotBeNull);
1168void StdLibraryFunctionsChecker::NotNullConstraint::describe(
1170 const Summary &Summary, llvm::raw_ostream &Out)
const {
1171 assert(CannotBeNull &&
1172 "Describe should not be used when the value must be NULL");
1173 if (DK == Violation)
1174 Out <<
"should not be NULL";
1176 Out <<
"is not NULL";
1179bool StdLibraryFunctionsChecker::NotNullConstraint::describeArgumentValue(
1181 llvm::raw_ostream &Out)
const {
1182 assert(!CannotBeNull &&
"This function is used when the value is NULL");
1187ProgramStateRef StdLibraryFunctionsChecker::NotNullBufferConstraint::apply(
1197 std::optional<DefinedOrUnknownSVal> SizeArg1 =
1199 std::optional<DefinedOrUnknownSVal> SizeArg2;
1203 auto IsArgZero = [State](std::optional<DefinedOrUnknownSVal> Val) {
1206 auto [IsNonNull,
IsNull] = State->assume(*Val);
1207 return IsNull && !IsNonNull;
1210 if (IsArgZero(SizeArg1) || IsArgZero(SizeArg2))
1213 return State->assume(L, CannotBeNull);
1216void StdLibraryFunctionsChecker::NotNullBufferConstraint::describe(
1218 const Summary &Summary, llvm::raw_ostream &Out)
const {
1219 assert(CannotBeNull &&
1220 "Describe should not be used when the value must be NULL");
1221 if (DK == Violation)
1222 Out <<
"should not be NULL";
1224 Out <<
"is not NULL";
1227bool StdLibraryFunctionsChecker::NotNullBufferConstraint::describeArgumentValue(
1229 llvm::raw_ostream &Out)
const {
1230 assert(!CannotBeNull &&
"This function is used when the value is NULL");
1235ProgramStateRef StdLibraryFunctionsChecker::BufferSizeConstraint::apply(
1240 SVal BufV = getArgSVal(
Call, getArgNo());
1243 const SVal SizeV = [
this, &State, &
Call, &Summary, &SvalBuilder]() {
1247 assert(SizeArgN &&
"The constraint must be either a concrete value or "
1248 "encoded in an argument.");
1250 SVal SizeV = getArgSVal(
Call, *SizeArgN);
1252 if (SizeMultiplierArgN) {
1253 SVal SizeMulV = getArgSVal(
Call, *SizeMultiplierArgN);
1254 SizeV = SvalBuilder.
evalBinOp(State, BO_Mul, SizeV, SizeMulV,
1255 Summary.getArgType(*SizeArgN));
1263 SVal Feasible = SvalBuilder.
evalBinOp(State, Op, SizeV, BufDynSize,
1266 return State->assume(*F,
true);
1274 llvm_unreachable(
"Size argument or the dynamic size is Undefined");
1277void StdLibraryFunctionsChecker::BufferSizeConstraint::describe(
1279 const Summary &Summary, llvm::raw_ostream &Out)
const {
1280 Out << ((DK == Violation) ?
"should be " :
"is ");
1281 Out <<
"a buffer with size equal to or greater than ";
1283 Out << *ConcreteSize;
1284 }
else if (SizeArgN) {
1285 Out <<
"the value of the ";
1286 printArgDesc(*SizeArgN, Out);
1287 printArgValueInfo(*SizeArgN, State,
Call, Out);
1288 if (SizeMultiplierArgN) {
1289 Out <<
" times the ";
1290 printArgDesc(*SizeMultiplierArgN, Out);
1291 printArgValueInfo(*SizeMultiplierArgN, State,
Call, Out);
1296bool StdLibraryFunctionsChecker::BufferSizeConstraint::describeArgumentValue(
1298 llvm::raw_ostream &Out)
const {
1299 SVal BufV = getArgSVal(
Call, getArgNo());
1301 if (
const llvm::APSInt *Val =
1302 State->getStateManager().getSValBuilder().getKnownValue(State,
1304 Out <<
"is a buffer with size " << *Val;
1310void StdLibraryFunctionsChecker::checkPreCall(
const CallEvent &
Call,
1312 std::optional<Summary> FoundSummary = findFunctionSummary(
Call,
C);
1316 const Summary &Summary = *FoundSummary;
1321 for (
const ValueConstraintPtr &Constraint : Summary.getArgConstraints()) {
1322 ValueConstraintPtr NegatedConstraint = Constraint->negate();
1325 NegatedConstraint->apply(NewState,
Call, Summary,
C);
1327 if (FailureSt && !SuccessSt) {
1329 reportBug(
Call, N, Constraint.get(), NegatedConstraint.get(), Summary,
1338 NewState = SuccessSt;
1339 if (NewState != State) {
1341 llvm::raw_svector_ostream Os(Msg);
1342 Os <<
"Assuming that the ";
1343 printArgDesc(Constraint->getArgNo(), Os);
1345 Os << getFunctionName(
Call);
1347 Constraint->describe(ValueConstraint::Assumption,
Call, NewState, Summary,
1349 const auto ArgSVal =
Call.getArgSVal(Constraint->getArgNo());
1350 NewNode =
C.addTransition(
1352 C.getNoteTag([Msg = std::move(Msg), ArgSVal](
1354 if (BR.isInteresting(ArgSVal))
1361void StdLibraryFunctionsChecker::checkPostCall(
const CallEvent &
Call,
1363 std::optional<Summary> FoundSummary = findFunctionSummary(
Call,
C);
1368 const Summary &Summary = *FoundSummary;
1373 for (
const SummaryCase &Case : Summary.getCases()) {
1375 for (
const ValueConstraintPtr &Constraint : Case.getConstraints()) {
1376 NewState = Constraint->apply(NewState,
Call, Summary,
C);
1382 NewState = Case.getErrnoConstraint().apply(NewState,
Call, Summary,
C);
1395 cast<NamedDecl>(
Call.getDecl())->getDeclName();
1397 std::string ErrnoNote = Case.getErrnoConstraint().describe(
C);
1398 std::string CaseNote;
1399 if (Case.getNote().empty()) {
1400 if (!ErrnoNote.empty())
1402 llvm::formatv(
"After calling '{0}' {1}", FunctionName, ErrnoNote);
1404 CaseNote = llvm::formatv(Case.getNote().str().c_str(), FunctionName);
1406 const SVal RV =
Call.getReturnValue();
1408 if (Summary.getInvalidationKd() == EvalCallAsPure) {
1411 if (!CaseNote.empty()) {
1428 Pred =
C.addTransition(NewState, Pred, Tag);
1431 if (!CaseNote.empty() || !ErrnoNote.empty()) {
1433 C.getNoteTag([CaseNote, ErrnoNote,
1441 std::optional<Loc> ErrnoLoc =
1443 bool ErrnoImportant = !ErrnoNote.empty() && ErrnoLoc &&
1445 if (ErrnoImportant) {
1447 if (CaseNote.empty())
1449 return llvm::formatv(
"{0}; {1}", CaseNote, ErrnoNote);
1456 Pred =
C.addTransition(NewState, Pred, Tag);
1461 if (Pred ==
Node && NewState != State)
1462 C.addTransition(NewState);
1466bool StdLibraryFunctionsChecker::evalCall(
const CallEvent &
Call,
1468 std::optional<Summary> FoundSummary = findFunctionSummary(
Call,
C);
1472 const Summary &Summary = *FoundSummary;
1473 switch (Summary.getInvalidationKd()) {
1474 case EvalCallAsPure: {
1477 const auto *CE = cast<CallExpr>(
Call.getOriginExpr());
1478 SVal V =
C.getSValBuilder().conjureSymbolVal(
1479 CE, LC, CE->getType().getCanonicalType(),
C.blockCount());
1480 State = State->BindExpr(CE, LC,
V);
1482 C.addTransition(State);
1491 llvm_unreachable(
"Unknown invalidation kind!");
1494bool StdLibraryFunctionsChecker::Signature::matches(
1508 auto RemoveRestrict = [&FD](
QualType T) {
1510 T.removeLocalRestrict();
1515 if (!isIrrelevant(RetTy)) {
1517 if (RetTy != FDRetTy)
1522 for (
auto [Idx, ArgTy] : llvm::enumerate(ArgTys)) {
1523 if (isIrrelevant(ArgTy))
1527 if (ArgTy != FDArgTy)
1534std::optional<StdLibraryFunctionsChecker::Summary>
1535StdLibraryFunctionsChecker::findFunctionSummary(
const FunctionDecl *FD,
1538 return std::nullopt;
1540 initFunctionSummaries(
C);
1543 if (FSMI == FunctionSummaryMap.end())
1544 return std::nullopt;
1545 return FSMI->second;
1548std::optional<StdLibraryFunctionsChecker::Summary>
1549StdLibraryFunctionsChecker::findFunctionSummary(
const CallEvent &
Call,
1553 return std::nullopt;
1554 return findFunctionSummary(FD,
C);
1557void StdLibraryFunctionsChecker::initFunctionSummaries(
1559 if (SummariesInitialized)
1561 SummariesInitialized =
true;
1573 LookupType(
const ASTContext &ACtx) : ACtx(ACtx) {}
1576 std::optional<QualType> operator()(StringRef Name) {
1579 if (LookupRes.empty())
1580 return std::nullopt;
1587 for (
Decl *
D : LookupRes)
1588 if (
auto *TD = dyn_cast<TypedefNameDecl>(
D))
1595 for (
Decl *
D : LookupRes)
1596 if (
auto *TD = dyn_cast<TypeDecl>(
D))
1598 return std::nullopt;
1604 class GetRestrictTy {
1608 GetRestrictTy(
const ASTContext &ACtx) : ACtx(ACtx) {}
1612 std::optional<QualType> operator()(std::optional<QualType> Ty) {
1614 return operator()(*Ty);
1615 return std::nullopt;
1617 } getRestrictTy(ACtx);
1618 class GetPointerTy {
1622 GetPointerTy(
const ASTContext &ACtx) : ACtx(ACtx) {}
1624 std::optional<QualType> operator()(std::optional<QualType> Ty) {
1626 return operator()(*Ty);
1627 return std::nullopt;
1629 } getPointerTy(ACtx);
1632 std::optional<QualType> operator()(std::optional<QualType> Ty) {
1633 return Ty ? std::optional<QualType>(Ty->withConst()) :
std::nullopt;
1642 std::optional<RangeInt> operator()(
QualType Ty) {
1645 std::optional<RangeInt> operator()(std::optional<QualType> Ty) {
1647 return operator()(*Ty);
1649 return std::nullopt;
1668 const QualType VoidPtrTy = getPointerTy(VoidTy);
1669 const QualType IntPtrTy = getPointerTy(IntTy);
1671 getPointerTy(UnsignedIntTy);
1672 const QualType VoidPtrRestrictTy = getRestrictTy(VoidPtrTy);
1674 getPointerTy(getConstTy(VoidTy));
1675 const QualType CharPtrTy = getPointerTy(CharTy);
1676 const QualType CharPtrRestrictTy = getRestrictTy(CharPtrTy);
1678 getPointerTy(getConstTy(CharTy));
1679 const QualType ConstCharPtrRestrictTy = getRestrictTy(ConstCharPtrTy);
1680 const QualType Wchar_tPtrTy = getPointerTy(WCharTy);
1682 getPointerTy(getConstTy(WCharTy));
1683 const QualType ConstVoidPtrRestrictTy = getRestrictTy(ConstVoidPtrTy);
1684 const QualType SizePtrTy = getPointerTy(SizeTy);
1685 const QualType SizePtrRestrictTy = getRestrictTy(SizePtrTy);
1687 const RangeInt IntMax = BVF.
getMaxValue(IntTy).getLimitedValue();
1688 const RangeInt UnsignedIntMax =
1690 const RangeInt LongMax = BVF.
getMaxValue(LongTy).getLimitedValue();
1691 const RangeInt SizeMax = BVF.
getMaxValue(SizeTy).getLimitedValue();
1699 const RangeInt UCharRangeMax =
1709 struct AddToFunctionSummaryMap {
1711 FunctionSummaryMapType ⤅
1712 bool DisplayLoadedSummaries;
1713 AddToFunctionSummaryMap(
const ASTContext &ACtx, FunctionSummaryMapType &FSM,
1714 bool DisplayLoadedSummaries)
1715 : ACtx(ACtx), Map(FSM), DisplayLoadedSummaries(DisplayLoadedSummaries) {
1723 bool operator()(StringRef Name, Signature Sign, Summary Sum) {
1724 if (Sign.isInvalid())
1728 if (LookupRes.empty())
1730 for (
Decl *
D : LookupRes) {
1731 if (
auto *FD = dyn_cast<FunctionDecl>(
D)) {
1732 if (Sum.matchesAndSet(Sign, FD)) {
1734 assert(Res.second &&
"Function already has a summary set!");
1736 if (DisplayLoadedSummaries) {
1737 llvm::errs() <<
"Loaded summary for: ";
1738 FD->
print(llvm::errs());
1739 llvm::errs() <<
"\n";
1750 for (StringRef Name : Names)
1751 operator()(Name, Sign, Sum);
1753 } addToFunctionSummaryMap(ACtx, FunctionSummaryMap, DisplayLoadedSummaries);
1756 auto ArgumentCondition = [](ArgNo ArgN, RangeKind
Kind, IntRangeVector Ranges,
1757 StringRef Desc =
"") {
1758 return std::make_shared<RangeConstraint>(ArgN, Kind, Ranges, Desc);
1760 auto BufferSize = [](
auto... Args) {
1761 return std::make_shared<BufferSizeConstraint>(Args...);
1764 auto operator()(RangeKind Kind, IntRangeVector Ranges) {
1765 return std::make_shared<RangeConstraint>(Ret, Kind, Ranges);
1768 return std::make_shared<ComparisonConstraint>(Ret, Op, OtherArgN);
1770 } ReturnValueCondition;
1772 auto operator()(RangeInt
b, RangeInt e) {
1773 return IntRangeVector{std::pair<RangeInt, RangeInt>{
b, e}};
1775 auto operator()(RangeInt
b, std::optional<RangeInt> e) {
1777 return IntRangeVector{std::pair<RangeInt, RangeInt>{
b, *e}};
1778 return IntRangeVector{};
1780 auto operator()(std::pair<RangeInt, RangeInt> i0,
1781 std::pair<RangeInt, std::optional<RangeInt>> i1) {
1783 return IntRangeVector{i0, {i1.first, *(i1.second)}};
1784 return IntRangeVector{i0};
1787 auto SingleValue = [](RangeInt
v) {
1788 return IntRangeVector{std::pair<RangeInt, RangeInt>{
v,
v}};
1790 auto LessThanOrEq = BO_LE;
1791 auto NotNull = [&](ArgNo ArgN) {
1792 return std::make_shared<NotNullConstraint>(ArgN);
1794 auto IsNull = [&](ArgNo ArgN) {
1795 return std::make_shared<NotNullConstraint>(ArgN,
false);
1797 auto NotNullBuffer = [&](ArgNo ArgN, ArgNo SizeArg1N, ArgNo SizeArg2N) {
1798 return std::make_shared<NotNullBufferConstraint>(ArgN, SizeArg1N,
1802 std::optional<QualType> FileTy = lookupTy(
"FILE");
1803 std::optional<QualType> FilePtrTy = getPointerTy(FileTy);
1804 std::optional<QualType> FilePtrRestrictTy = getRestrictTy(FilePtrTy);
1806 std::optional<QualType> FPosTTy = lookupTy(
"fpos_t");
1807 std::optional<QualType> FPosTPtrTy = getPointerTy(FPosTTy);
1808 std::optional<QualType> ConstFPosTPtrTy = getPointerTy(getConstTy(FPosTTy));
1809 std::optional<QualType> FPosTPtrRestrictTy = getRestrictTy(FPosTPtrTy);
1811 constexpr llvm::StringLiteral GenericSuccessMsg(
1812 "Assuming that '{0}' is successful");
1813 constexpr llvm::StringLiteral GenericFailureMsg(
"Assuming that '{0}' fails");
1830 addToFunctionSummaryMap(
1831 "isalnum", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1832 Summary(EvalCallAsPure)
1834 .Case({ArgumentCondition(0
U, WithinRange,
1835 {{
'0',
'9'}, {
'A',
'Z'}, {
'a',
'z'}}),
1836 ReturnValueCondition(OutOfRange, SingleValue(0))},
1837 ErrnoIrrelevant,
"Assuming the character is alphanumeric")
1841 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1846 {{
'0',
'9'}, {
'A',
'Z'}, {
'a',
'z'}, {128, UCharRangeMax}}),
1847 ReturnValueCondition(WithinRange, SingleValue(0))},
1848 ErrnoIrrelevant,
"Assuming the character is non-alphanumeric")
1849 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
1850 {{EOFv, EOFv}, {0, UCharRangeMax}},
1851 "an unsigned char value or EOF")));
1852 addToFunctionSummaryMap(
1853 "isalpha", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1854 Summary(EvalCallAsPure)
1855 .Case({ArgumentCondition(0
U, WithinRange, {{
'A',
'Z'}, {
'a',
'z'}}),
1856 ReturnValueCondition(OutOfRange, SingleValue(0))},
1857 ErrnoIrrelevant,
"Assuming the character is alphabetical")
1859 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1861 .Case({ArgumentCondition(
1863 {{
'A',
'Z'}, {
'a',
'z'}, {128, UCharRangeMax}}),
1864 ReturnValueCondition(WithinRange, SingleValue(0))},
1865 ErrnoIrrelevant,
"Assuming the character is non-alphabetical"));
1866 addToFunctionSummaryMap(
1867 "isascii", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1868 Summary(EvalCallAsPure)
1869 .Case({ArgumentCondition(0
U, WithinRange,
Range(0, 127)),
1870 ReturnValueCondition(OutOfRange, SingleValue(0))},
1871 ErrnoIrrelevant,
"Assuming the character is an ASCII character")
1872 .Case({ArgumentCondition(0
U, OutOfRange,
Range(0, 127)),
1873 ReturnValueCondition(WithinRange, SingleValue(0))},
1875 "Assuming the character is not an ASCII character"));
1876 addToFunctionSummaryMap(
1877 "isblank", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1878 Summary(EvalCallAsPure)
1879 .Case({ArgumentCondition(0
U, WithinRange, {{
'\t',
'\t'}, {
' ',
' '}}),
1880 ReturnValueCondition(OutOfRange, SingleValue(0))},
1881 ErrnoIrrelevant,
"Assuming the character is a blank character")
1882 .Case({ArgumentCondition(0
U, OutOfRange, {{
'\t',
'\t'}, {
' ',
' '}}),
1883 ReturnValueCondition(WithinRange, SingleValue(0))},
1885 "Assuming the character is not a blank character"));
1886 addToFunctionSummaryMap(
1887 "iscntrl", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1888 Summary(EvalCallAsPure)
1889 .Case({ArgumentCondition(0
U, WithinRange, {{0, 32}, {127, 127}}),
1890 ReturnValueCondition(OutOfRange, SingleValue(0))},
1892 "Assuming the character is a control character")
1893 .Case({ArgumentCondition(0
U, OutOfRange, {{0, 32}, {127, 127}}),
1894 ReturnValueCondition(WithinRange, SingleValue(0))},
1896 "Assuming the character is not a control character"));
1897 addToFunctionSummaryMap(
1898 "isdigit", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1899 Summary(EvalCallAsPure)
1900 .Case({ArgumentCondition(0
U, WithinRange,
Range(
'0',
'9')),
1901 ReturnValueCondition(OutOfRange, SingleValue(0))},
1902 ErrnoIrrelevant,
"Assuming the character is a digit")
1903 .Case({ArgumentCondition(0
U, OutOfRange,
Range(
'0',
'9')),
1904 ReturnValueCondition(WithinRange, SingleValue(0))},
1905 ErrnoIrrelevant,
"Assuming the character is not a digit"));
1906 addToFunctionSummaryMap(
1907 "isgraph", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1908 Summary(EvalCallAsPure)
1909 .Case({ArgumentCondition(0
U, WithinRange,
Range(33, 126)),
1910 ReturnValueCondition(OutOfRange, SingleValue(0))},
1912 "Assuming the character has graphical representation")
1914 {ArgumentCondition(0
U, OutOfRange,
Range(33, 126)),
1915 ReturnValueCondition(WithinRange, SingleValue(0))},
1917 "Assuming the character does not have graphical representation"));
1918 addToFunctionSummaryMap(
1919 "islower", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1920 Summary(EvalCallAsPure)
1922 .Case({ArgumentCondition(0
U, WithinRange,
Range(
'a',
'z')),
1923 ReturnValueCondition(OutOfRange, SingleValue(0))},
1924 ErrnoIrrelevant,
"Assuming the character is a lowercase letter")
1926 .Case({ArgumentCondition(0
U, WithinRange,
Range(0, 127)),
1927 ArgumentCondition(0
U, OutOfRange,
Range(
'a',
'z')),
1928 ReturnValueCondition(WithinRange, SingleValue(0))},
1930 "Assuming the character is not a lowercase letter")
1932 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1935 .Case({ArgumentCondition(0
U, OutOfRange,
Range(0, UCharRangeMax)),
1936 ReturnValueCondition(WithinRange, SingleValue(0))},
1938 addToFunctionSummaryMap(
1939 "isprint", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1940 Summary(EvalCallAsPure)
1941 .Case({ArgumentCondition(0
U, WithinRange,
Range(32, 126)),
1942 ReturnValueCondition(OutOfRange, SingleValue(0))},
1943 ErrnoIrrelevant,
"Assuming the character is printable")
1944 .Case({ArgumentCondition(0
U, OutOfRange,
Range(32, 126)),
1945 ReturnValueCondition(WithinRange, SingleValue(0))},
1946 ErrnoIrrelevant,
"Assuming the character is non-printable"));
1947 addToFunctionSummaryMap(
1948 "ispunct", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1949 Summary(EvalCallAsPure)
1950 .Case({ArgumentCondition(
1952 {{
'!',
'/'}, {
':',
'@'}, {
'[',
'`'}, {
'{',
'~'}}),
1953 ReturnValueCondition(OutOfRange, SingleValue(0))},
1954 ErrnoIrrelevant,
"Assuming the character is a punctuation mark")
1955 .Case({ArgumentCondition(
1957 {{
'!',
'/'}, {
':',
'@'}, {
'[',
'`'}, {
'{',
'~'}}),
1958 ReturnValueCondition(WithinRange, SingleValue(0))},
1960 "Assuming the character is not a punctuation mark"));
1961 addToFunctionSummaryMap(
1962 "isspace", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1963 Summary(EvalCallAsPure)
1965 .Case({ArgumentCondition(0
U, WithinRange, {{9, 13}, {
' ',
' '}}),
1966 ReturnValueCondition(OutOfRange, SingleValue(0))},
1968 "Assuming the character is a whitespace character")
1970 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1972 .Case({ArgumentCondition(0
U, OutOfRange,
1973 {{9, 13}, {
' ',
' '}, {128, UCharRangeMax}}),
1974 ReturnValueCondition(WithinRange, SingleValue(0))},
1976 "Assuming the character is not a whitespace character"));
1977 addToFunctionSummaryMap(
1978 "isupper", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1979 Summary(EvalCallAsPure)
1981 .Case({ArgumentCondition(0
U, WithinRange,
Range(
'A',
'Z')),
1982 ReturnValueCondition(OutOfRange, SingleValue(0))},
1984 "Assuming the character is an uppercase letter")
1986 .Case({ArgumentCondition(0
U, WithinRange, {{128, UCharRangeMax}})},
1989 .Case({ArgumentCondition(0
U, OutOfRange,
1990 {{
'A',
'Z'}, {128, UCharRangeMax}}),
1991 ReturnValueCondition(WithinRange, SingleValue(0))},
1993 "Assuming the character is not an uppercase letter"));
1994 addToFunctionSummaryMap(
1995 "isxdigit", Signature(ArgTypes{IntTy}, RetType{IntTy}),
1996 Summary(EvalCallAsPure)
1997 .Case({ArgumentCondition(0
U, WithinRange,
1998 {{
'0',
'9'}, {
'A',
'F'}, {
'a',
'f'}}),
1999 ReturnValueCondition(OutOfRange, SingleValue(0))},
2001 "Assuming the character is a hexadecimal digit")
2002 .Case({ArgumentCondition(0
U, OutOfRange,
2003 {{
'0',
'9'}, {
'A',
'F'}, {
'a',
'f'}}),
2004 ReturnValueCondition(WithinRange, SingleValue(0))},
2006 "Assuming the character is not a hexadecimal digit"));
2007 addToFunctionSummaryMap(
2008 "toupper", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2009 Summary(EvalCallAsPure)
2010 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
2011 {{EOFv, EOFv}, {0, UCharRangeMax}},
2012 "an unsigned char value or EOF")));
2013 addToFunctionSummaryMap(
2014 "tolower", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2015 Summary(EvalCallAsPure)
2016 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
2017 {{EOFv, EOFv}, {0, UCharRangeMax}},
2018 "an unsigned char value or EOF")));
2019 addToFunctionSummaryMap(
2020 "toascii", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2021 Summary(EvalCallAsPure)
2022 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
2023 {{EOFv, EOFv}, {0, UCharRangeMax}},
2024 "an unsigned char value or EOF")));
2026 addToFunctionSummaryMap(
2027 "getchar", Signature(ArgTypes{}, RetType{IntTy}),
2029 .Case({ReturnValueCondition(WithinRange,
2030 {{EOFv, EOFv}, {0, UCharRangeMax}})},
2036 .Case({ArgumentCondition(1U, WithinRange,
Range(1, SizeMax)),
2037 ArgumentCondition(2U, WithinRange,
Range(1, SizeMax)),
2038 ReturnValueCondition(BO_LT, ArgNo(2)),
2039 ReturnValueCondition(WithinRange,
Range(0, SizeMax))},
2040 ErrnoNEZeroIrrelevant, GenericFailureMsg)
2041 .Case({ArgumentCondition(1U, WithinRange,
Range(1, SizeMax)),
2042 ReturnValueCondition(BO_EQ, ArgNo(2)),
2043 ReturnValueCondition(WithinRange,
Range(0, SizeMax))},
2044 ErrnoMustNotBeChecked, GenericSuccessMsg)
2045 .Case({ArgumentCondition(1U, WithinRange, SingleValue(0)),
2046 ReturnValueCondition(WithinRange, SingleValue(0))},
2047 ErrnoMustNotBeChecked,
2048 "Assuming that argument 'size' to '{0}' is 0")
2049 .ArgConstraint(NotNullBuffer(ArgNo(0), ArgNo(1), ArgNo(2)))
2050 .ArgConstraint(NotNull(ArgNo(3)))
2051 .ArgConstraint(BufferSize(ArgNo(0), ArgNo(1),
2056 addToFunctionSummaryMap(
2058 Signature(ArgTypes{VoidPtrRestrictTy, SizeTy, SizeTy, FilePtrRestrictTy},
2063 addToFunctionSummaryMap(
"fwrite",
2064 Signature(ArgTypes{ConstVoidPtrRestrictTy, SizeTy,
2065 SizeTy, FilePtrRestrictTy},
2069 std::optional<QualType> Ssize_tTy = lookupTy(
"ssize_t");
2070 std::optional<RangeInt> Ssize_tMax = getMaxValue(Ssize_tTy);
2074 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
2075 ReturnValueCondition(WithinRange,
Range(-1, Ssize_tMax))},
2081 addToFunctionSummaryMap(
2082 "read", Signature(ArgTypes{IntTy, VoidPtrTy, SizeTy}, RetType{Ssize_tTy}),
2085 addToFunctionSummaryMap(
2087 Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy}, RetType{Ssize_tTy}),
2090 auto GetLineSummary =
2092 .Case({ReturnValueCondition(WithinRange,
2093 Range({-1, -1}, {1, Ssize_tMax}))},
2096 QualType CharPtrPtrRestrictTy = getRestrictTy(getPointerTy(CharPtrTy));
2103 addToFunctionSummaryMap(
2106 ArgTypes{CharPtrPtrRestrictTy, SizePtrRestrictTy, FilePtrRestrictTy},
2107 RetType{Ssize_tTy}),
2111 addToFunctionSummaryMap(
2113 Signature(ArgTypes{CharPtrPtrRestrictTy, SizePtrRestrictTy, IntTy,
2115 RetType{Ssize_tTy}),
2119 Summary GetenvSummary =
2121 .ArgConstraint(NotNull(ArgNo(0)))
2122 .Case({NotNull(Ret)}, ErrnoIrrelevant,
2123 "Assuming the environment variable exists");
2125 if (!ShouldAssumeControlledEnvironment)
2126 GetenvSummary.Case({NotNull(Ret)->negate()}, ErrnoIrrelevant,
2127 "Assuming the environment variable does not exist");
2130 addToFunctionSummaryMap(
2131 "getenv", Signature(ArgTypes{ConstCharPtrTy}, RetType{CharPtrTy}),
2132 std::move(GetenvSummary));
2138 addToFunctionSummaryMap(
2139 {
"getc",
"fgetc"}, Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2141 .Case({ReturnValueCondition(WithinRange,
2142 {{EOFv, EOFv}, {0, UCharRangeMax}})},
2144 .ArgConstraint(NotNull(ArgNo(0))));
2146 const auto ReturnsZeroOrMinusOne =
2147 ConstraintSet{ReturnValueCondition(WithinRange,
Range(-1, 0))};
2148 const auto ReturnsZero =
2149 ConstraintSet{ReturnValueCondition(WithinRange, SingleValue(0))};
2150 const auto ReturnsMinusOne =
2151 ConstraintSet{ReturnValueCondition(WithinRange, SingleValue(-1))};
2152 const auto ReturnsEOF =
2153 ConstraintSet{ReturnValueCondition(WithinRange, SingleValue(EOFv))};
2154 const auto ReturnsNonnegative =
2155 ConstraintSet{ReturnValueCondition(WithinRange,
Range(0, IntMax))};
2156 const auto ReturnsNonZero =
2157 ConstraintSet{ReturnValueCondition(OutOfRange, SingleValue(0))};
2158 const auto ReturnsFileDescriptor =
2159 ConstraintSet{ReturnValueCondition(WithinRange,
Range(-1, IntMax))};
2160 const auto &ReturnsValidFileDescriptor = ReturnsNonnegative;
2162 auto ValidFileDescriptorOrAtFdcwd = [&](ArgNo ArgN) {
2163 return std::make_shared<RangeConstraint>(
2164 ArgN, WithinRange,
Range({AT_FDCWDv, AT_FDCWDv}, {0, IntMax}),
2165 "a valid file descriptor or AT_FDCWD");
2169 addToFunctionSummaryMap(
2171 Signature(ArgTypes{ConstCharPtrRestrictTy, ConstCharPtrRestrictTy},
2172 RetType{FilePtrTy}),
2174 .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
2175 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2176 .ArgConstraint(NotNull(ArgNo(0)))
2177 .ArgConstraint(NotNull(ArgNo(1))));
2180 addToFunctionSummaryMap(
2182 Signature(ArgTypes{IntTy, ConstCharPtrTy}, RetType{FilePtrTy}),
2184 .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
2185 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2186 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
2187 .ArgConstraint(NotNull(ArgNo(1))));
2190 addToFunctionSummaryMap(
2191 "tmpfile", Signature(ArgTypes{}, RetType{FilePtrTy}),
2193 .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
2194 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg));
2198 addToFunctionSummaryMap(
2200 Signature(ArgTypes{ConstCharPtrRestrictTy, ConstCharPtrRestrictTy,
2202 RetType{FilePtrTy}),
2204 .Case({ReturnValueCondition(BO_EQ, ArgNo(2))},
2205 ErrnoMustNotBeChecked, GenericSuccessMsg)
2206 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2207 .ArgConstraint(NotNull(ArgNo(1)))
2208 .ArgConstraint(NotNull(ArgNo(2))));
2211 addToFunctionSummaryMap(
2213 Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}),
2215 .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
2216 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2217 .ArgConstraint(NotNull(ArgNo(0)))
2218 .ArgConstraint(NotNull(ArgNo(1))));
2221 addToFunctionSummaryMap(
2222 "fclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2224 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2225 .Case(ReturnsEOF, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2226 .ArgConstraint(NotNull(ArgNo(0))));
2229 addToFunctionSummaryMap(
2230 "pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2232 .Case({ReturnValueCondition(WithinRange, {{0, IntMax}})},
2233 ErrnoMustNotBeChecked, GenericSuccessMsg)
2234 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2235 .ArgConstraint(NotNull(ArgNo(0))));
2237 std::optional<QualType> Off_tTy = lookupTy(
"off_t");
2238 std::optional<RangeInt> Off_tMax = getMaxValue(Off_tTy);
2242 addToFunctionSummaryMap(
2243 {
"getc",
"fgetc"}, Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2245 .Case({ReturnValueCondition(WithinRange, {{0, UCharRangeMax}})},
2246 ErrnoMustNotBeChecked, GenericSuccessMsg)
2247 .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
2248 ErrnoIrrelevant, GenericFailureMsg)
2249 .ArgConstraint(NotNull(ArgNo(0))));
2253 addToFunctionSummaryMap(
2255 Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}),
2257 .Case({ArgumentCondition(0, WithinRange,
Range(0, UCharRangeMax)),
2258 ReturnValueCondition(BO_EQ, ArgNo(0))},
2259 ErrnoMustNotBeChecked, GenericSuccessMsg)
2260 .Case({ArgumentCondition(0, OutOfRange,
Range(0, UCharRangeMax)),
2261 ReturnValueCondition(WithinRange,
Range(0, UCharRangeMax))},
2262 ErrnoMustNotBeChecked, GenericSuccessMsg)
2263 .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
2264 ErrnoNEZeroIrrelevant, GenericFailureMsg)
2265 .ArgConstraint(NotNull(ArgNo(1))));
2268 addToFunctionSummaryMap(
2270 Signature(ArgTypes{CharPtrRestrictTy, IntTy, FilePtrRestrictTy},
2271 RetType{CharPtrTy}),
2273 .Case({ReturnValueCondition(BO_EQ, ArgNo(0))},
2274 ErrnoMustNotBeChecked, GenericSuccessMsg)
2275 .Case({
IsNull(Ret)}, ErrnoIrrelevant, GenericFailureMsg)
2276 .ArgConstraint(NotNull(ArgNo(0)))
2277 .ArgConstraint(ArgumentCondition(1, WithinRange,
Range(0, IntMax)))
2279 BufferSize(ArgNo(0), ArgNo(1)))
2280 .ArgConstraint(NotNull(ArgNo(2))));
2283 addToFunctionSummaryMap(
2285 Signature(ArgTypes{ConstCharPtrRestrictTy, FilePtrRestrictTy},
2288 .Case(ReturnsNonnegative, ErrnoMustNotBeChecked, GenericSuccessMsg)
2289 .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
2290 ErrnoNEZeroIrrelevant, GenericFailureMsg)
2291 .ArgConstraint(NotNull(ArgNo(0)))
2292 .ArgConstraint(NotNull(ArgNo(1))));
2295 addToFunctionSummaryMap(
2296 "ungetc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}),
2298 .Case({ReturnValueCondition(BO_EQ, ArgNo(0)),
2299 ArgumentCondition(0, WithinRange, {{0, UCharRangeMax}})},
2300 ErrnoMustNotBeChecked, GenericSuccessMsg)
2301 .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv)),
2302 ArgumentCondition(0, WithinRange, SingleValue(EOFv))},
2303 ErrnoNEZeroIrrelevant,
2304 "Assuming that 'ungetc' fails because EOF was passed as "
2306 .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv)),
2307 ArgumentCondition(0, WithinRange, {{0, UCharRangeMax}})},
2308 ErrnoNEZeroIrrelevant, GenericFailureMsg)
2309 .ArgConstraint(ArgumentCondition(
2310 0, WithinRange, {{EOFv, EOFv}, {0, UCharRangeMax}}))
2311 .ArgConstraint(NotNull(ArgNo(1))));
2317 addToFunctionSummaryMap(
2318 "fseek", Signature(ArgTypes{FilePtrTy, LongTy, IntTy}, RetType{IntTy}),
2320 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2321 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2322 .ArgConstraint(NotNull(ArgNo(0)))
2323 .ArgConstraint(ArgumentCondition(2, WithinRange, {{0, 2}})));
2326 addToFunctionSummaryMap(
2328 Signature(ArgTypes{FilePtrTy, Off_tTy, IntTy}, RetType{IntTy}),
2330 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2331 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2332 .ArgConstraint(NotNull(ArgNo(0)))
2333 .ArgConstraint(ArgumentCondition(2, WithinRange, {{0, 2}})));
2339 addToFunctionSummaryMap(
2341 Signature(ArgTypes{FilePtrRestrictTy, FPosTPtrRestrictTy},
2344 .Case(ReturnsZero, ErrnoUnchanged, GenericSuccessMsg)
2345 .Case(ReturnsNonZero, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2346 .ArgConstraint(NotNull(ArgNo(0)))
2347 .ArgConstraint(NotNull(ArgNo(1))));
2353 addToFunctionSummaryMap(
2355 Signature(ArgTypes{FilePtrTy, ConstFPosTPtrTy}, RetType{IntTy}),
2357 .Case(ReturnsZero, ErrnoUnchanged, GenericSuccessMsg)
2358 .Case(ReturnsNonZero, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2359 .ArgConstraint(NotNull(ArgNo(0)))
2360 .ArgConstraint(NotNull(ArgNo(1))));
2363 addToFunctionSummaryMap(
2364 "fflush", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2366 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2367 .Case(ReturnsEOF, ErrnoNEZeroIrrelevant, GenericFailureMsg));
2373 addToFunctionSummaryMap(
2374 "ftell", Signature(ArgTypes{FilePtrTy}, RetType{LongTy}),
2376 .Case({ReturnValueCondition(WithinRange,
Range(0, LongMax))},
2377 ErrnoUnchanged, GenericSuccessMsg)
2378 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2379 .ArgConstraint(NotNull(ArgNo(0))));
2382 addToFunctionSummaryMap(
2383 "ftello", Signature(ArgTypes{FilePtrTy}, RetType{Off_tTy}),
2385 .Case({ReturnValueCondition(WithinRange,
Range(0, Off_tMax))},
2386 ErrnoMustNotBeChecked, GenericSuccessMsg)
2387 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2388 .ArgConstraint(NotNull(ArgNo(0))));
2396 addToFunctionSummaryMap(
2397 "fileno", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2399 .Case(ReturnsValidFileDescriptor, ErrnoUnchanged, GenericSuccessMsg)
2400 .ArgConstraint(NotNull(ArgNo(0))));
2404 addToFunctionSummaryMap(
"rewind",
2405 Signature(ArgTypes{FilePtrTy}, RetType{VoidTy}),
2407 .Case({}, ErrnoMustBeChecked)
2408 .ArgConstraint(NotNull(ArgNo(0))));
2411 addToFunctionSummaryMap(
2412 "clearerr", Signature(ArgTypes{FilePtrTy}, RetType{VoidTy}),
2413 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2416 addToFunctionSummaryMap(
2417 "feof", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2418 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2421 addToFunctionSummaryMap(
2422 "ferror", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
2423 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2426 addToFunctionSummaryMap(
2427 "a64l", Signature(ArgTypes{ConstCharPtrTy}, RetType{LongTy}),
2428 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2431 addToFunctionSummaryMap(
"l64a",
2432 Signature(ArgTypes{LongTy}, RetType{CharPtrTy}),
2434 .ArgConstraint(ArgumentCondition(
2435 0, WithinRange,
Range(0, LongMax))));
2438 addToFunctionSummaryMap(
2439 "open", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{IntTy}),
2441 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2443 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2444 .ArgConstraint(NotNull(ArgNo(0))));
2447 addToFunctionSummaryMap(
2449 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy}, RetType{IntTy}),
2451 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2453 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2454 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2455 .ArgConstraint(NotNull(ArgNo(1))));
2458 addToFunctionSummaryMap(
2459 "access", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{IntTy}),
2461 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2462 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2463 .ArgConstraint(NotNull(ArgNo(0))));
2466 addToFunctionSummaryMap(
2468 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy, IntTy},
2471 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2472 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2473 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2474 .ArgConstraint(NotNull(ArgNo(1))));
2477 addToFunctionSummaryMap(
2478 "dup", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2480 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2482 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2484 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2487 addToFunctionSummaryMap(
2488 "dup2", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
2490 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2492 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2493 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
2495 ArgumentCondition(1, WithinRange,
Range(0, IntMax))));
2498 addToFunctionSummaryMap(
2499 "fdatasync", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2501 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2502 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2504 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2507 addToFunctionSummaryMap(
2509 Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy, IntTy},
2512 .ArgConstraint(NotNull(ArgNo(0)))
2513 .ArgConstraint(NotNull(ArgNo(1))));
2516 addToFunctionSummaryMap(
2517 "fsync", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2519 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2520 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2522 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2525 addToFunctionSummaryMap(
2527 Signature(ArgTypes{ConstCharPtrTy, Off_tTy}, RetType{IntTy}),
2529 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2530 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2531 .ArgConstraint(NotNull(ArgNo(0))));
2534 addToFunctionSummaryMap(
2536 Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{IntTy}),
2538 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2539 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2540 .ArgConstraint(NotNull(ArgNo(0)))
2541 .ArgConstraint(NotNull(ArgNo(1))));
2544 addToFunctionSummaryMap(
2546 Signature(ArgTypes{ConstCharPtrTy, IntTy, ConstCharPtrTy},
2549 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2550 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2551 .ArgConstraint(NotNull(ArgNo(0)))
2552 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(1)))
2553 .ArgConstraint(NotNull(ArgNo(2))));
2556 addToFunctionSummaryMap(
2557 "lockf", Signature(ArgTypes{IntTy, IntTy, Off_tTy}, RetType{IntTy}),
2559 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2560 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2562 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2564 std::optional<QualType> Mode_tTy = lookupTy(
"mode_t");
2567 addToFunctionSummaryMap(
2568 "creat", Signature(ArgTypes{ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
2570 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2572 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2573 .ArgConstraint(NotNull(ArgNo(0))));
2576 addToFunctionSummaryMap(
2577 "sleep", Signature(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}),
2580 ArgumentCondition(0, WithinRange,
Range(0, UnsignedIntMax))));
2582 std::optional<QualType> DirTy = lookupTy(
"DIR");
2583 std::optional<QualType> DirPtrTy = getPointerTy(DirTy);
2586 addToFunctionSummaryMap(
2587 "dirfd", Signature(ArgTypes{DirPtrTy}, RetType{IntTy}),
2589 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2591 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2592 .ArgConstraint(NotNull(ArgNo(0))));
2595 addToFunctionSummaryMap(
2596 "alarm", Signature(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}),
2599 ArgumentCondition(0, WithinRange,
Range(0, UnsignedIntMax))));
2602 addToFunctionSummaryMap(
2603 "closedir", Signature(ArgTypes{DirPtrTy}, RetType{IntTy}),
2605 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2606 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2607 .ArgConstraint(NotNull(ArgNo(0))));
2610 addToFunctionSummaryMap(
2611 "strdup", Signature(ArgTypes{ConstCharPtrTy}, RetType{CharPtrTy}),
2612 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2615 addToFunctionSummaryMap(
2617 Signature(ArgTypes{ConstCharPtrTy, SizeTy}, RetType{CharPtrTy}),
2619 .ArgConstraint(NotNull(ArgNo(0)))
2621 ArgumentCondition(1, WithinRange,
Range(0, SizeMax))));
2624 addToFunctionSummaryMap(
2625 "wcsdup", Signature(ArgTypes{ConstWchar_tPtrTy}, RetType{Wchar_tPtrTy}),
2626 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2629 addToFunctionSummaryMap(
2630 "mkstemp", Signature(ArgTypes{CharPtrTy}, RetType{IntTy}),
2632 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
2634 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2635 .ArgConstraint(NotNull(ArgNo(0))));
2638 addToFunctionSummaryMap(
2639 "mkdtemp", Signature(ArgTypes{CharPtrTy}, RetType{CharPtrTy}),
2641 .Case({ReturnValueCondition(BO_EQ, ArgNo(0))},
2642 ErrnoMustNotBeChecked, GenericSuccessMsg)
2643 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2644 .ArgConstraint(NotNull(ArgNo(0))));
2647 addToFunctionSummaryMap(
2648 "getcwd", Signature(ArgTypes{CharPtrTy, SizeTy}, RetType{CharPtrTy}),
2650 .Case({ArgumentCondition(1, WithinRange,
Range(1, SizeMax)),
2651 ReturnValueCondition(BO_EQ, ArgNo(0))},
2652 ErrnoMustNotBeChecked, GenericSuccessMsg)
2653 .Case({ArgumentCondition(1, WithinRange, SingleValue(0)),
2655 ErrnoNEZeroIrrelevant,
"Assuming that argument 'size' is 0")
2656 .Case({ArgumentCondition(1, WithinRange,
Range(1, SizeMax)),
2658 ErrnoNEZeroIrrelevant, GenericFailureMsg)
2659 .ArgConstraint(NotNull(ArgNo(0)))
2661 BufferSize( ArgNo(0), ArgNo(1)))
2663 ArgumentCondition(1, WithinRange,
Range(0, SizeMax))));
2666 addToFunctionSummaryMap(
2667 "mkdir", Signature(ArgTypes{ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
2669 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2670 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2671 .ArgConstraint(NotNull(ArgNo(0))));
2674 addToFunctionSummaryMap(
2676 Signature(ArgTypes{IntTy, ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
2678 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2679 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2680 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2681 .ArgConstraint(NotNull(ArgNo(1))));
2683 std::optional<QualType> Dev_tTy = lookupTy(
"dev_t");
2686 addToFunctionSummaryMap(
2688 Signature(ArgTypes{ConstCharPtrTy, Mode_tTy, Dev_tTy}, RetType{IntTy}),
2690 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2691 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2692 .ArgConstraint(NotNull(ArgNo(0))));
2695 addToFunctionSummaryMap(
2697 Signature(ArgTypes{IntTy, ConstCharPtrTy, Mode_tTy, Dev_tTy},
2700 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2701 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2702 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2703 .ArgConstraint(NotNull(ArgNo(1))));
2706 addToFunctionSummaryMap(
2707 "chmod", Signature(ArgTypes{ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
2709 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2710 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2711 .ArgConstraint(NotNull(ArgNo(0))));
2714 addToFunctionSummaryMap(
2716 Signature(ArgTypes{IntTy, ConstCharPtrTy, Mode_tTy, IntTy},
2719 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2720 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2721 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2722 .ArgConstraint(NotNull(ArgNo(1))));
2725 addToFunctionSummaryMap(
2726 "fchmod", Signature(ArgTypes{IntTy, Mode_tTy}, RetType{IntTy}),
2728 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2729 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2731 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2733 std::optional<QualType> Uid_tTy = lookupTy(
"uid_t");
2734 std::optional<QualType> Gid_tTy = lookupTy(
"gid_t");
2738 addToFunctionSummaryMap(
2740 Signature(ArgTypes{IntTy, ConstCharPtrTy, Uid_tTy, Gid_tTy, IntTy},
2743 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2744 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2745 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2746 .ArgConstraint(NotNull(ArgNo(1))));
2749 addToFunctionSummaryMap(
2751 Signature(ArgTypes{ConstCharPtrTy, Uid_tTy, Gid_tTy}, RetType{IntTy}),
2753 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2754 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2755 .ArgConstraint(NotNull(ArgNo(0))));
2758 addToFunctionSummaryMap(
2760 Signature(ArgTypes{ConstCharPtrTy, Uid_tTy, Gid_tTy}, RetType{IntTy}),
2762 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2763 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2764 .ArgConstraint(NotNull(ArgNo(0))));
2767 addToFunctionSummaryMap(
2768 "fchown", Signature(ArgTypes{IntTy, Uid_tTy, Gid_tTy}, RetType{IntTy}),
2770 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2771 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2773 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2776 addToFunctionSummaryMap(
2777 "rmdir", Signature(ArgTypes{ConstCharPtrTy}, RetType{IntTy}),
2779 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2780 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2781 .ArgConstraint(NotNull(ArgNo(0))));
2784 addToFunctionSummaryMap(
2785 "chdir", Signature(ArgTypes{ConstCharPtrTy}, RetType{IntTy}),
2787 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2788 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2789 .ArgConstraint(NotNull(ArgNo(0))));
2792 addToFunctionSummaryMap(
2794 Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{IntTy}),
2796 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2797 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2798 .ArgConstraint(NotNull(ArgNo(0)))
2799 .ArgConstraint(NotNull(ArgNo(1))));
2803 addToFunctionSummaryMap(
2805 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy, ConstCharPtrTy, IntTy},
2808 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2809 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2810 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2811 .ArgConstraint(NotNull(ArgNo(1)))
2812 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(2)))
2813 .ArgConstraint(NotNull(ArgNo(3))));
2816 addToFunctionSummaryMap(
2817 "unlink", Signature(ArgTypes{ConstCharPtrTy}, RetType{IntTy}),
2819 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2820 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2821 .ArgConstraint(NotNull(ArgNo(0))));
2824 addToFunctionSummaryMap(
2826 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy}, RetType{IntTy}),
2828 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2829 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2830 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2831 .ArgConstraint(NotNull(ArgNo(1))));
2833 std::optional<QualType> StructStatTy = lookupTy(
"stat");
2834 std::optional<QualType> StructStatPtrTy = getPointerTy(StructStatTy);
2835 std::optional<QualType> StructStatPtrRestrictTy =
2836 getRestrictTy(StructStatPtrTy);
2839 addToFunctionSummaryMap(
2840 "fstat", Signature(ArgTypes{IntTy, StructStatPtrTy}, RetType{IntTy}),
2842 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2843 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2844 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
2845 .ArgConstraint(NotNull(ArgNo(1))));
2848 addToFunctionSummaryMap(
2850 Signature(ArgTypes{ConstCharPtrRestrictTy, StructStatPtrRestrictTy},
2853 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2854 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2855 .ArgConstraint(NotNull(ArgNo(0)))
2856 .ArgConstraint(NotNull(ArgNo(1))));
2859 addToFunctionSummaryMap(
2861 Signature(ArgTypes{ConstCharPtrRestrictTy, StructStatPtrRestrictTy},
2864 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2865 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2866 .ArgConstraint(NotNull(ArgNo(0)))
2867 .ArgConstraint(NotNull(ArgNo(1))));
2871 addToFunctionSummaryMap(
2873 Signature(ArgTypes{IntTy, ConstCharPtrRestrictTy,
2874 StructStatPtrRestrictTy, IntTy},
2877 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2878 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2879 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
2880 .ArgConstraint(NotNull(ArgNo(1)))
2881 .ArgConstraint(NotNull(ArgNo(2))));
2884 addToFunctionSummaryMap(
2885 "opendir", Signature(ArgTypes{ConstCharPtrTy}, RetType{DirPtrTy}),
2887 .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
2888 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2889 .ArgConstraint(NotNull(ArgNo(0))));
2892 addToFunctionSummaryMap(
2893 "fdopendir", Signature(ArgTypes{IntTy}, RetType{DirPtrTy}),
2895 .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
2896 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2898 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2901 addToFunctionSummaryMap(
2902 "isatty", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2904 .Case({ReturnValueCondition(WithinRange,
Range(0, 1))},
2907 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2910 addToFunctionSummaryMap(
2911 "close", Signature(ArgTypes{IntTy}, RetType{IntTy}),
2913 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2914 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2916 ArgumentCondition(0, WithinRange,
Range(-1, IntMax))));
2919 addToFunctionSummaryMap(
"fpathconf",
2920 Signature(ArgTypes{IntTy, IntTy}, RetType{LongTy}),
2922 .ArgConstraint(ArgumentCondition(
2923 0, WithinRange,
Range(0, IntMax))));
2926 addToFunctionSummaryMap(
2927 "pathconf", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{LongTy}),
2928 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2931 addToFunctionSummaryMap(
2932 "rewinddir", Signature(ArgTypes{DirPtrTy}, RetType{VoidTy}),
2933 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2936 addToFunctionSummaryMap(
2937 "seekdir", Signature(ArgTypes{DirPtrTy, LongTy}, RetType{VoidTy}),
2938 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2941 addToFunctionSummaryMap(
2942 "rand_r", Signature(ArgTypes{UnsignedIntPtrTy}, RetType{IntTy}),
2943 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2948 addToFunctionSummaryMap(
2950 Signature(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, Off_tTy},
2951 RetType{VoidPtrTy}),
2953 .ArgConstraint(ArgumentCondition(1, WithinRange,
Range(1, SizeMax)))
2955 ArgumentCondition(4, WithinRange,
Range(-1, IntMax))));
2957 std::optional<QualType> Off64_tTy = lookupTy(
"off64_t");
2961 addToFunctionSummaryMap(
2963 Signature(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, Off64_tTy},
2964 RetType{VoidPtrTy}),
2966 .ArgConstraint(ArgumentCondition(1, WithinRange,
Range(1, SizeMax)))
2968 ArgumentCondition(4, WithinRange,
Range(-1, IntMax))));
2971 addToFunctionSummaryMap(
2972 "pipe", Signature(ArgTypes{IntPtrTy}, RetType{IntTy}),
2974 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
2975 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2976 .ArgConstraint(NotNull(ArgNo(0))));
2983 addToFunctionSummaryMap(
2984 "lseek", Signature(ArgTypes{IntTy, Off_tTy, IntTy}, RetType{Off_tTy}),
2986 .Case(ReturnsNonnegative, ErrnoIrrelevant)
2987 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2989 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
2993 addToFunctionSummaryMap(
2995 Signature(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy},
2996 RetType{Ssize_tTy}),
2998 .Case({ArgumentCondition(2, WithinRange,
Range(1, IntMax)),
2999 ReturnValueCondition(LessThanOrEq, ArgNo(2)),
3000 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3001 ErrnoMustNotBeChecked, GenericSuccessMsg)
3002 .Case({ArgumentCondition(2, WithinRange, SingleValue(0)),
3003 ReturnValueCondition(WithinRange, SingleValue(0))},
3004 ErrnoMustNotBeChecked,
3005 "Assuming that argument 'bufsize' is 0")
3006 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3007 .ArgConstraint(NotNull(ArgNo(0)))
3008 .ArgConstraint(NotNull(ArgNo(1)))
3009 .ArgConstraint(BufferSize(ArgNo(1),
3012 ArgumentCondition(2, WithinRange,
Range(0, SizeMax))));
3016 addToFunctionSummaryMap(
3019 ArgTypes{IntTy, ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy},
3020 RetType{Ssize_tTy}),
3022 .Case({ArgumentCondition(3, WithinRange,
Range(1, IntMax)),
3023 ReturnValueCondition(LessThanOrEq, ArgNo(3)),
3024 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3025 ErrnoMustNotBeChecked, GenericSuccessMsg)
3026 .Case({ArgumentCondition(3, WithinRange, SingleValue(0)),
3027 ReturnValueCondition(WithinRange, SingleValue(0))},
3028 ErrnoMustNotBeChecked,
3029 "Assuming that argument 'bufsize' is 0")
3030 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3031 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
3032 .ArgConstraint(NotNull(ArgNo(1)))
3033 .ArgConstraint(NotNull(ArgNo(2)))
3034 .ArgConstraint(BufferSize(ArgNo(2),
3037 ArgumentCondition(3, WithinRange,
Range(0, SizeMax))));
3041 addToFunctionSummaryMap(
3043 Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy, ConstCharPtrTy},
3046 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3047 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3048 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
3049 .ArgConstraint(NotNull(ArgNo(1)))
3050 .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(2)))
3051 .ArgConstraint(NotNull(ArgNo(3))));
3057 addToFunctionSummaryMap(
3059 Signature(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy},
3060 RetType{CharPtrTy}),
3062 .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
3063 .Case({
IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3064 .ArgConstraint(NotNull(ArgNo(0))));
3066 QualType CharPtrConstPtr = getPointerTy(getConstTy(CharPtrTy));
3069 addToFunctionSummaryMap(
3071 Signature(ArgTypes{ConstCharPtrTy, CharPtrConstPtr}, RetType{IntTy}),
3073 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant)
3074 .ArgConstraint(NotNull(ArgNo(0))));
3077 addToFunctionSummaryMap(
3079 Signature(ArgTypes{ConstCharPtrTy, CharPtrConstPtr}, RetType{IntTy}),
3081 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant)
3082 .ArgConstraint(NotNull(ArgNo(0))));
3085 addToFunctionSummaryMap(
3087 Signature(ArgTypes{IntTy, CharPtrConstPtr, ConstCharPtrTy},
3090 .Case({ReturnValueCondition(WithinRange,
Range(-1, UCharRangeMax))},
3092 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3093 .ArgConstraint(NotNull(ArgNo(1)))
3094 .ArgConstraint(NotNull(ArgNo(2))));
3096 std::optional<QualType> StructSockaddrTy = lookupTy(
"sockaddr");
3097 std::optional<QualType> StructSockaddrPtrTy =
3098 getPointerTy(StructSockaddrTy);
3099 std::optional<QualType> ConstStructSockaddrPtrTy =
3100 getPointerTy(getConstTy(StructSockaddrTy));
3101 std::optional<QualType> StructSockaddrPtrRestrictTy =
3102 getRestrictTy(StructSockaddrPtrTy);
3103 std::optional<QualType> ConstStructSockaddrPtrRestrictTy =
3104 getRestrictTy(ConstStructSockaddrPtrTy);
3105 std::optional<QualType> Socklen_tTy = lookupTy(
"socklen_t");
3106 std::optional<QualType> Socklen_tPtrTy = getPointerTy(Socklen_tTy);
3107 std::optional<QualType> Socklen_tPtrRestrictTy =
3108 getRestrictTy(Socklen_tPtrTy);
3109 std::optional<RangeInt> Socklen_tMax = getMaxValue(Socklen_tTy);
3119 addToFunctionSummaryMap(
3120 "socket", Signature(ArgTypes{IntTy, IntTy, IntTy}, RetType{IntTy}),
3122 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
3124 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg));
3128 .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
3130 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3131 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)));
3132 if (!addToFunctionSummaryMap(
3136 Signature(ArgTypes{IntTy, StructSockaddrPtrRestrictTy,
3137 Socklen_tPtrRestrictTy},
3140 addToFunctionSummaryMap(
3142 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tPtrRestrictTy},
3148 if (!addToFunctionSummaryMap(
3150 Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy},
3153 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3154 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3156 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3157 .ArgConstraint(NotNull(ArgNo(1)))
3159 BufferSize(ArgNo(1), ArgNo(2)))
3161 ArgumentCondition(2, WithinRange,
Range(0, Socklen_tMax)))))
3163 addToFunctionSummaryMap(
3165 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tTy}, RetType{IntTy}),
3167 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3168 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3170 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3172 ArgumentCondition(2, WithinRange,
Range(0, Socklen_tMax))));
3176 if (!addToFunctionSummaryMap(
3178 Signature(ArgTypes{IntTy, StructSockaddrPtrRestrictTy,
3179 Socklen_tPtrRestrictTy},
3182 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3183 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3185 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3186 .ArgConstraint(NotNull(ArgNo(1)))
3187 .ArgConstraint(NotNull(ArgNo(2)))))
3188 addToFunctionSummaryMap(
3190 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tPtrRestrictTy},
3193 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3194 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3196 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3200 if (!addToFunctionSummaryMap(
3202 Signature(ArgTypes{IntTy, StructSockaddrPtrRestrictTy,
3203 Socklen_tPtrRestrictTy},
3206 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3207 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3209 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3210 .ArgConstraint(NotNull(ArgNo(1)))
3211 .ArgConstraint(NotNull(ArgNo(2)))))
3212 addToFunctionSummaryMap(
3214 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tPtrRestrictTy},
3217 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3218 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3220 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3224 if (!addToFunctionSummaryMap(
3226 Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy},
3229 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3230 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3232 ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3233 .ArgConstraint(NotNull(ArgNo(1)))))
3234 addToFunctionSummaryMap(
3236 Signature(ArgTypes{IntTy,
Irrelevant, Socklen_tTy}, RetType{IntTy}),
3238 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3239 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3241 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3245 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
3246 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3247 ErrnoMustNotBeChecked, GenericSuccessMsg)
3248 .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
3249 ArgumentCondition(2, WithinRange, SingleValue(0))},
3250 ErrnoMustNotBeChecked, GenericSuccessMsg)
3251 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3252 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3253 .ArgConstraint(BufferSize(ArgNo(1),
3255 if (!addToFunctionSummaryMap(
3261 Signature(ArgTypes{IntTy, VoidPtrRestrictTy, SizeTy, IntTy,
3262 StructSockaddrPtrRestrictTy,
3263 Socklen_tPtrRestrictTy},
3264 RetType{Ssize_tTy}),
3266 addToFunctionSummaryMap(
3268 Signature(ArgTypes{IntTy, VoidPtrRestrictTy, SizeTy, IntTy,
3270 RetType{Ssize_tTy}),
3275 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
3276 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3277 ErrnoMustNotBeChecked, GenericSuccessMsg)
3278 .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
3279 ArgumentCondition(2, WithinRange, SingleValue(0))},
3280 ErrnoMustNotBeChecked, GenericSuccessMsg)
3281 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3282 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3283 .ArgConstraint(BufferSize(ArgNo(1),
3285 if (!addToFunctionSummaryMap(
3290 Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy,
3291 ConstStructSockaddrPtrTy, Socklen_tTy},
3292 RetType{Ssize_tTy}),
3294 addToFunctionSummaryMap(
3296 Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy,
Irrelevant,
3298 RetType{Ssize_tTy}),
3302 addToFunctionSummaryMap(
3303 "listen", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
3305 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3306 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3308 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3311 addToFunctionSummaryMap(
3313 Signature(ArgTypes{IntTy, VoidPtrTy, SizeTy, IntTy},
3314 RetType{Ssize_tTy}),
3316 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
3317 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3318 ErrnoMustNotBeChecked, GenericSuccessMsg)
3319 .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
3320 ArgumentCondition(2, WithinRange, SingleValue(0))},
3321 ErrnoMustNotBeChecked, GenericSuccessMsg)
3322 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3323 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3324 .ArgConstraint(BufferSize(ArgNo(1),
3327 std::optional<QualType> StructMsghdrTy = lookupTy(
"msghdr");
3328 std::optional<QualType> StructMsghdrPtrTy = getPointerTy(StructMsghdrTy);
3329 std::optional<QualType> ConstStructMsghdrPtrTy =
3330 getPointerTy(getConstTy(StructMsghdrTy));
3333 addToFunctionSummaryMap(
3335 Signature(ArgTypes{IntTy, StructMsghdrPtrTy, IntTy},
3336 RetType{Ssize_tTy}),
3338 .Case({ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3339 ErrnoMustNotBeChecked, GenericSuccessMsg)
3340 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3342 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3345 addToFunctionSummaryMap(
3347 Signature(ArgTypes{IntTy, ConstStructMsghdrPtrTy, IntTy},
3348 RetType{Ssize_tTy}),
3350 .Case({ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3351 ErrnoMustNotBeChecked, GenericSuccessMsg)
3352 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3354 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3358 addToFunctionSummaryMap(
3360 Signature(ArgTypes{IntTy, IntTy, IntTy, ConstVoidPtrTy, Socklen_tTy},
3363 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3364 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3365 .ArgConstraint(NotNull(ArgNo(3)))
3367 BufferSize(ArgNo(3), ArgNo(4)))
3369 ArgumentCondition(4, WithinRange,
Range(0, Socklen_tMax))));
3374 addToFunctionSummaryMap(
3376 Signature(ArgTypes{IntTy, IntTy, IntTy, VoidPtrRestrictTy,
3377 Socklen_tPtrRestrictTy},
3380 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3381 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3382 .ArgConstraint(NotNull(ArgNo(3)))
3383 .ArgConstraint(NotNull(ArgNo(4))));
3386 addToFunctionSummaryMap(
3388 Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy},
3389 RetType{Ssize_tTy}),
3391 .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
3392 ReturnValueCondition(WithinRange,
Range(1, Ssize_tMax))},
3393 ErrnoMustNotBeChecked, GenericSuccessMsg)
3394 .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
3395 ArgumentCondition(2, WithinRange, SingleValue(0))},
3396 ErrnoMustNotBeChecked, GenericSuccessMsg)
3397 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3398 .ArgConstraint(ArgumentCondition(0, WithinRange,
Range(0, IntMax)))
3399 .ArgConstraint(BufferSize(ArgNo(1),
3403 addToFunctionSummaryMap(
3405 Signature(ArgTypes{IntTy, IntTy, IntTy, IntPtrTy}, RetType{IntTy}),
3407 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3408 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3409 .ArgConstraint(NotNull(ArgNo(3))));
3412 addToFunctionSummaryMap(
3413 "shutdown", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
3415 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3416 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3418 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3427 addToFunctionSummaryMap(
3429 Signature(ArgTypes{ConstStructSockaddrPtrRestrictTy, Socklen_tTy,
3430 CharPtrRestrictTy, Socklen_tTy, CharPtrRestrictTy,
3431 Socklen_tTy, IntTy},
3435 BufferSize(ArgNo(0), ArgNo(1)))
3437 ArgumentCondition(1, WithinRange,
Range(0, Socklen_tMax)))
3439 BufferSize(ArgNo(2), ArgNo(3)))
3441 ArgumentCondition(3, WithinRange,
Range(0, Socklen_tMax)))
3443 BufferSize(ArgNo(4), ArgNo(5)))
3445 ArgumentCondition(5, WithinRange,
Range(0, Socklen_tMax))));
3447 std::optional<QualType> StructUtimbufTy = lookupTy(
"utimbuf");
3448 std::optional<QualType> StructUtimbufPtrTy = getPointerTy(StructUtimbufTy);
3451 addToFunctionSummaryMap(
3453 Signature(ArgTypes{ConstCharPtrTy, StructUtimbufPtrTy}, RetType{IntTy}),
3455 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3456 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3457 .ArgConstraint(NotNull(ArgNo(0))));
3459 std::optional<QualType> StructTimespecTy = lookupTy(
"timespec");
3460 std::optional<QualType> StructTimespecPtrTy =
3461 getPointerTy(StructTimespecTy);
3462 std::optional<QualType> ConstStructTimespecPtrTy =
3463 getPointerTy(getConstTy(StructTimespecTy));
3466 addToFunctionSummaryMap(
3468 Signature(ArgTypes{IntTy, ConstStructTimespecPtrTy}, RetType{IntTy}),
3470 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3471 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3473 ArgumentCondition(0, WithinRange,
Range(0, IntMax))));
3477 addToFunctionSummaryMap(
3480 ArgTypes{IntTy, ConstCharPtrTy, ConstStructTimespecPtrTy, IntTy},
3483 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3484 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3485 .ArgConstraint(NotNull(ArgNo(1))));
3487 std::optional<QualType> StructTimevalTy = lookupTy(
"timeval");
3488 std::optional<QualType> ConstStructTimevalPtrTy =
3489 getPointerTy(getConstTy(StructTimevalTy));
3492 addToFunctionSummaryMap(
3494 Signature(ArgTypes{ConstCharPtrTy, ConstStructTimevalPtrTy},
3497 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3498 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3499 .ArgConstraint(NotNull(ArgNo(0))));
3502 addToFunctionSummaryMap(
3504 Signature(ArgTypes{ConstStructTimespecPtrTy, StructTimespecPtrTy},
3507 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3508 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3509 .ArgConstraint(NotNull(ArgNo(0))));
3511 std::optional<QualType> Time_tTy = lookupTy(
"time_t");
3512 std::optional<QualType> ConstTime_tPtrTy =
3513 getPointerTy(getConstTy(Time_tTy));
3514 std::optional<QualType> ConstTime_tPtrRestrictTy =
3515 getRestrictTy(ConstTime_tPtrTy);
3517 std::optional<QualType> StructTmTy = lookupTy(
"tm");
3518 std::optional<QualType> StructTmPtrTy = getPointerTy(StructTmTy);
3519 std::optional<QualType> StructTmPtrRestrictTy =
3520 getRestrictTy(StructTmPtrTy);
3521 std::optional<QualType> ConstStructTmPtrTy =
3522 getPointerTy(getConstTy(StructTmTy));
3523 std::optional<QualType> ConstStructTmPtrRestrictTy =
3524 getRestrictTy(ConstStructTmPtrTy);
3527 addToFunctionSummaryMap(
3529 Signature(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}),
3530 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3534 addToFunctionSummaryMap(
3536 Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
3537 RetType{StructTmPtrTy}),
3539 .ArgConstraint(NotNull(ArgNo(0)))
3540 .ArgConstraint(NotNull(ArgNo(1))));
3543 addToFunctionSummaryMap(
3545 Signature(ArgTypes{ConstStructTmPtrRestrictTy, CharPtrRestrictTy},
3546 RetType{CharPtrTy}),
3548 .ArgConstraint(NotNull(ArgNo(0)))
3549 .ArgConstraint(NotNull(ArgNo(1)))
3550 .ArgConstraint(BufferSize(ArgNo(1),
3551 BVF.getValue(26, IntTy))));
3554 addToFunctionSummaryMap(
3556 Signature(ArgTypes{ConstTime_tPtrTy, CharPtrTy}, RetType{CharPtrTy}),
3558 .ArgConstraint(NotNull(ArgNo(0)))
3559 .ArgConstraint(NotNull(ArgNo(1)))
3560 .ArgConstraint(BufferSize(
3562 BVF.getValue(26, IntTy))));
3566 addToFunctionSummaryMap(
3568 Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
3569 RetType{StructTmPtrTy}),
3571 .ArgConstraint(NotNull(ArgNo(0)))
3572 .ArgConstraint(NotNull(ArgNo(1))));
3575 addToFunctionSummaryMap(
3576 "gmtime", Signature(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}),
3577 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3579 std::optional<QualType> Clockid_tTy = lookupTy(
"clockid_t");
3582 addToFunctionSummaryMap(
3584 Signature(ArgTypes{Clockid_tTy, StructTimespecPtrTy}, RetType{IntTy}),
3586 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3587 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3588 .ArgConstraint(NotNull(ArgNo(1))));
3590 std::optional<QualType> StructItimervalTy = lookupTy(
"itimerval");
3591 std::optional<QualType> StructItimervalPtrTy =
3592 getPointerTy(StructItimervalTy);
3595 addToFunctionSummaryMap(
3597 Signature(ArgTypes{IntTy, StructItimervalPtrTy}, RetType{IntTy}),
3599 .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
3600 .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3601 .ArgConstraint(NotNull(ArgNo(1))));
3603 std::optional<QualType> Pthread_cond_tTy = lookupTy(
"pthread_cond_t");
3604 std::optional<QualType> Pthread_cond_tPtrTy =
3605 getPointerTy(Pthread_cond_tTy);
3606 std::optional<QualType> Pthread_tTy = lookupTy(
"pthread_t");
3607 std::optional<QualType> Pthread_tPtrTy = getPointerTy(Pthread_tTy);
3608 std::optional<QualType> Pthread_tPtrRestrictTy =
3609 getRestrictTy(Pthread_tPtrTy);
3610 std::optional<QualType> Pthread_mutex_tTy = lookupTy(
"pthread_mutex_t");
3611 std::optional<QualType> Pthread_mutex_tPtrTy =
3612 getPointerTy(Pthread_mutex_tTy);
3613 std::optional<QualType> Pthread_mutex_tPtrRestrictTy =
3614 getRestrictTy(Pthread_mutex_tPtrTy);
3615 std::optional<QualType> Pthread_attr_tTy = lookupTy(
"pthread_attr_t");
3616 std::optional<QualType> Pthread_attr_tPtrTy =
3617 getPointerTy(Pthread_attr_tTy);
3618 std::optional<QualType> ConstPthread_attr_tPtrTy =
3619 getPointerTy(getConstTy(Pthread_attr_tTy));
3620 std::optional<QualType> ConstPthread_attr_tPtrRestrictTy =
3621 getRestrictTy(ConstPthread_attr_tPtrTy);
3622 std::optional<QualType> Pthread_mutexattr_tTy =
3623 lookupTy(
"pthread_mutexattr_t");
3624 std::optional<QualType> ConstPthread_mutexattr_tPtrTy =
3625 getPointerTy(getConstTy(Pthread_mutexattr_tTy));
3626 std::optional<QualType> ConstPthread_mutexattr_tPtrRestrictTy =
3627 getRestrictTy(ConstPthread_mutexattr_tPtrTy);
3629 QualType PthreadStartRoutineTy = getPointerTy(
3635 addToFunctionSummaryMap(
3636 {
"pthread_cond_signal",
"pthread_cond_broadcast"},
3637 Signature(ArgTypes{Pthread_cond_tPtrTy}, RetType{IntTy}),
3638 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3643 addToFunctionSummaryMap(
3645 Signature(ArgTypes{Pthread_tPtrRestrictTy,
3646 ConstPthread_attr_tPtrRestrictTy,
3647 PthreadStartRoutineTy, VoidPtrRestrictTy},
3650 .ArgConstraint(NotNull(ArgNo(0)))
3651 .ArgConstraint(NotNull(ArgNo(2))));
3655 addToFunctionSummaryMap(
3656 {
"pthread_attr_destroy",
"pthread_attr_init"},
3657 Signature(ArgTypes{Pthread_attr_tPtrTy}, RetType{IntTy}),
3658 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3664 addToFunctionSummaryMap(
3665 {
"pthread_attr_getstacksize",
"pthread_attr_getguardsize"},
3666 Signature(ArgTypes{ConstPthread_attr_tPtrRestrictTy, SizePtrRestrictTy},
3669 .ArgConstraint(NotNull(ArgNo(0)))
3670 .ArgConstraint(NotNull(ArgNo(1))));
3674 addToFunctionSummaryMap(
3675 {
"pthread_attr_setstacksize",
"pthread_attr_setguardsize"},
3676 Signature(ArgTypes{Pthread_attr_tPtrTy, SizeTy}, RetType{IntTy}),
3678 .ArgConstraint(NotNull(ArgNo(0)))
3680 ArgumentCondition(1, WithinRange,
Range(0, SizeMax))));
3684 addToFunctionSummaryMap(
3685 "pthread_mutex_init",
3686 Signature(ArgTypes{Pthread_mutex_tPtrRestrictTy,
3687 ConstPthread_mutexattr_tPtrRestrictTy},
3689 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3695 addToFunctionSummaryMap(
3696 {
"pthread_mutex_destroy",
"pthread_mutex_lock",
"pthread_mutex_trylock",
3697 "pthread_mutex_unlock"},
3698 Signature(ArgTypes{Pthread_mutex_tPtrTy}, RetType{IntTy}),
3699 Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
3703 if (AddTestFunctions) {
3704 const RangeInt IntMin = BVF.
getMinValue(IntTy).getLimitedValue();
3706 addToFunctionSummaryMap(
3707 "__not_null", Signature(ArgTypes{IntPtrTy}, RetType{IntTy}),
3708 Summary(EvalCallAsPure).ArgConstraint(NotNull(ArgNo(0))));
3710 addToFunctionSummaryMap(
3711 "__not_null_buffer",
3712 Signature(ArgTypes{VoidPtrTy, IntTy, IntTy}, RetType{IntTy}),
3713 Summary(EvalCallAsPure)
3714 .ArgConstraint(NotNullBuffer(ArgNo(0), ArgNo(1), ArgNo(2))));
3717 addToFunctionSummaryMap(
3718 "__single_val_0", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3719 Summary(EvalCallAsPure)
3720 .ArgConstraint(ArgumentCondition(0
U, WithinRange, SingleValue(0))));
3721 addToFunctionSummaryMap(
3722 "__single_val_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3723 Summary(EvalCallAsPure)
3724 .ArgConstraint(ArgumentCondition(0
U, WithinRange, SingleValue(1))));
3725 addToFunctionSummaryMap(
3726 "__range_1_2", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3727 Summary(EvalCallAsPure)
3728 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
Range(1, 2))));
3729 addToFunctionSummaryMap(
3730 "__range_m1_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3731 Summary(EvalCallAsPure)
3732 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
Range(-1, 1))));
3733 addToFunctionSummaryMap(
3734 "__range_m2_m1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3735 Summary(EvalCallAsPure)
3736 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
Range(-2, -1))));
3737 addToFunctionSummaryMap(
3738 "__range_m10_10", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3739 Summary(EvalCallAsPure)
3740 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
Range(-10, 10))));
3741 addToFunctionSummaryMap(
"__range_m1_inf",
3742 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3743 Summary(EvalCallAsPure)
3744 .ArgConstraint(ArgumentCondition(
3745 0
U, WithinRange,
Range(-1, IntMax))));
3746 addToFunctionSummaryMap(
"__range_0_inf",
3747 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3748 Summary(EvalCallAsPure)
3749 .ArgConstraint(ArgumentCondition(
3750 0
U, WithinRange,
Range(0, IntMax))));
3751 addToFunctionSummaryMap(
"__range_1_inf",
3752 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3753 Summary(EvalCallAsPure)
3754 .ArgConstraint(ArgumentCondition(
3755 0
U, WithinRange,
Range(1, IntMax))));
3756 addToFunctionSummaryMap(
"__range_minf_m1",
3757 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3758 Summary(EvalCallAsPure)
3759 .ArgConstraint(ArgumentCondition(
3760 0
U, WithinRange,
Range(IntMin, -1))));
3761 addToFunctionSummaryMap(
"__range_minf_0",
3762 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3763 Summary(EvalCallAsPure)
3764 .ArgConstraint(ArgumentCondition(
3765 0
U, WithinRange,
Range(IntMin, 0))));
3766 addToFunctionSummaryMap(
"__range_minf_1",
3767 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3768 Summary(EvalCallAsPure)
3769 .ArgConstraint(ArgumentCondition(
3770 0
U, WithinRange,
Range(IntMin, 1))));
3771 addToFunctionSummaryMap(
"__range_1_2__4_6",
3772 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3773 Summary(EvalCallAsPure)
3774 .ArgConstraint(ArgumentCondition(
3775 0
U, WithinRange,
Range({1, 2}, {4, 6}))));
3776 addToFunctionSummaryMap(
3777 "__range_1_2__4_inf", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3778 Summary(EvalCallAsPure)
3779 .ArgConstraint(ArgumentCondition(0
U, WithinRange,
3780 Range({1, 2}, {4, IntMax}))));
3783 addToFunctionSummaryMap(
3784 "__single_val_out_0", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3785 Summary(EvalCallAsPure)
3786 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(0))));
3787 addToFunctionSummaryMap(
3788 "__single_val_out_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3789 Summary(EvalCallAsPure)
3790 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(1))));
3791 addToFunctionSummaryMap(
3792 "__range_out_1_2", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3793 Summary(EvalCallAsPure)
3794 .ArgConstraint(ArgumentCondition(0
U, OutOfRange,
Range(1, 2))));
3795 addToFunctionSummaryMap(
3796 "__range_out_m1_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3797 Summary(EvalCallAsPure)
3798 .ArgConstraint(ArgumentCondition(0
U, OutOfRange,
Range(-1, 1))));
3799 addToFunctionSummaryMap(
3800 "__range_out_m2_m1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3801 Summary(EvalCallAsPure)
3802 .ArgConstraint(ArgumentCondition(0
U, OutOfRange,
Range(-2, -1))));
3803 addToFunctionSummaryMap(
3804 "__range_out_m10_10", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3805 Summary(EvalCallAsPure)
3806 .ArgConstraint(ArgumentCondition(0
U, OutOfRange,
Range(-10, 10))));
3807 addToFunctionSummaryMap(
"__range_out_m1_inf",
3808 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3809 Summary(EvalCallAsPure)
3810 .ArgConstraint(ArgumentCondition(
3811 0
U, OutOfRange,
Range(-1, IntMax))));
3812 addToFunctionSummaryMap(
"__range_out_0_inf",
3813 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3814 Summary(EvalCallAsPure)
3815 .ArgConstraint(ArgumentCondition(
3816 0
U, OutOfRange,
Range(0, IntMax))));
3817 addToFunctionSummaryMap(
"__range_out_1_inf",
3818 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3819 Summary(EvalCallAsPure)
3820 .ArgConstraint(ArgumentCondition(
3821 0
U, OutOfRange,
Range(1, IntMax))));
3822 addToFunctionSummaryMap(
"__range_out_minf_m1",
3823 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3824 Summary(EvalCallAsPure)
3825 .ArgConstraint(ArgumentCondition(
3826 0
U, OutOfRange,
Range(IntMin, -1))));
3827 addToFunctionSummaryMap(
"__range_out_minf_0",
3828 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3829 Summary(EvalCallAsPure)
3830 .ArgConstraint(ArgumentCondition(
3831 0
U, OutOfRange,
Range(IntMin, 0))));
3832 addToFunctionSummaryMap(
"__range_out_minf_1",
3833 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3834 Summary(EvalCallAsPure)
3835 .ArgConstraint(ArgumentCondition(
3836 0
U, OutOfRange,
Range(IntMin, 1))));
3837 addToFunctionSummaryMap(
"__range_out_1_2__4_6",
3838 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3839 Summary(EvalCallAsPure)
3840 .ArgConstraint(ArgumentCondition(
3841 0
U, OutOfRange,
Range({1, 2}, {4, 6}))));
3842 addToFunctionSummaryMap(
3843 "__range_out_1_2__4_inf", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3844 Summary(EvalCallAsPure)
3846 ArgumentCondition(0
U, OutOfRange,
Range({1, 2}, {4, IntMax}))));
3849 addToFunctionSummaryMap(
3850 "__within", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3851 Summary(EvalCallAsPure)
3852 .ArgConstraint(ArgumentCondition(0
U, WithinRange, SingleValue(1))));
3853 addToFunctionSummaryMap(
3854 "__out_of", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3855 Summary(EvalCallAsPure)
3856 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(1))));
3858 addToFunctionSummaryMap(
3859 "__two_constrained_args",
3860 Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
3861 Summary(EvalCallAsPure)
3862 .ArgConstraint(ArgumentCondition(0
U, WithinRange, SingleValue(1)))
3863 .ArgConstraint(ArgumentCondition(1U, WithinRange, SingleValue(1))));
3864 addToFunctionSummaryMap(
3865 "__arg_constrained_twice", Signature(ArgTypes{IntTy}, RetType{IntTy}),
3866 Summary(EvalCallAsPure)
3867 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(1)))
3868 .ArgConstraint(ArgumentCondition(0
U, OutOfRange, SingleValue(2))));
3869 addToFunctionSummaryMap(
3871 Signature(ArgTypes{
Irrelevant, IntTy}, RetType{IntTy}),
3872 Summary(EvalCallAsPure).ArgConstraint(NotNull(ArgNo(0))));
3873 addToFunctionSummaryMap(
3875 Signature(ArgTypes{VoidPtrTy, ConstCharPtrTy}, RetType{IntTy}),
3876 Summary(EvalCallAsPure)
3877 .ArgConstraint(NotNull(ArgNo(0)))
3878 .ArgConstraint(NotNull(ArgNo(1))));
3879 addToFunctionSummaryMap(
3880 "__buf_size_arg_constraint",
3881 Signature(ArgTypes{ConstVoidPtrTy, SizeTy}, RetType{IntTy}),
3882 Summary(EvalCallAsPure)
3884 BufferSize(ArgNo(0), ArgNo(1))));
3885 addToFunctionSummaryMap(
3886 "__buf_size_arg_constraint_mul",
3887 Signature(ArgTypes{ConstVoidPtrTy, SizeTy, SizeTy}, RetType{IntTy}),
3888 Summary(EvalCallAsPure)
3889 .ArgConstraint(BufferSize(ArgNo(0), ArgNo(1),
3891 addToFunctionSummaryMap(
3892 "__buf_size_arg_constraint_concrete",
3893 Signature(ArgTypes{ConstVoidPtrTy}, RetType{IntTy}),
3894 Summary(EvalCallAsPure)
3895 .ArgConstraint(BufferSize(ArgNo(0),
3896 BVF.getValue(10, IntTy))));
3897 addToFunctionSummaryMap(
3898 {
"__test_restrict_param_0",
"__test_restrict_param_1",
3899 "__test_restrict_param_2"},
3900 Signature(ArgTypes{VoidPtrRestrictTy}, RetType{VoidTy}),
3901 Summary(EvalCallAsPure));
3904 addToFunctionSummaryMap(
3905 "__test_case_note", Signature(ArgTypes{}, RetType{IntTy}),
3906 Summary(EvalCallAsPure)
3907 .Case({ReturnValueCondition(WithinRange, SingleValue(0))},
3908 ErrnoIrrelevant,
"Function returns 0")
3909 .Case({ReturnValueCondition(WithinRange, SingleValue(1))},
3910 ErrnoIrrelevant,
"Function returns 1"));
3911 addToFunctionSummaryMap(
3912 "__test_case_range_1_2__4_6",
3913 Signature(ArgTypes{IntTy}, RetType{IntTy}),
3914 Summary(EvalCallAsPure)
3915 .Case({ArgumentCondition(0
U, WithinRange,
3916 IntRangeVector{{IntMin, 0}, {3, 3}}),
3917 ReturnValueCondition(WithinRange, SingleValue(1))},
3919 .Case({ArgumentCondition(0
U, WithinRange,
3920 IntRangeVector{{3, 3}, {7, IntMax}}),
3921 ReturnValueCondition(WithinRange, SingleValue(2))},
3923 .Case({ArgumentCondition(0
U, WithinRange,
3924 IntRangeVector{{IntMin, 0}, {7, IntMax}}),
3925 ReturnValueCondition(WithinRange, SingleValue(3))},
3927 .Case({ArgumentCondition(
3929 IntRangeVector{{IntMin, 0}, {3, 3}, {7, IntMax}}),
3930 ReturnValueCondition(WithinRange, SingleValue(4))},
3935void ento::registerStdCLibraryFunctionsChecker(
CheckerManager &mgr) {
3939 Checker->DisplayLoadedSummaries =
3942 Checker->ShouldAssumeControlledEnvironment =
3943 Opts.ShouldAssumeControlledEnvironment;
3946bool ento::shouldRegisterStdCLibraryFunctionsChecker(
3951void ento::registerStdCLibraryFunctionsTesterChecker(
CheckerManager &mgr) {
3953 Checker->AddTestFunctions =
true;
3956bool 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
QualType getCanonicalType() const
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.
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)
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
Extra information about a function prototype.