//=== StdLibraryFunctionsChecker.cpp - Model standard functions -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This checker improves modeling of a few simple library functions.
//
// This checker provides a specification format - `Summary' - and
// contains descriptions of some library functions in this format. Each
// specification contains a list of branches for splitting the program state
// upon call, and range constraints on argument and return-value symbols that
// are satisfied on each branch. This spec can be expanded to include more
// items, like external effects of the function.
//
// The main difference between this approach and the body farms technique is
// in more explicit control over how many branches are produced. For example,
// consider standard C function `ispunct(int x)', which returns a non-zero value
// iff `x' is a punctuation character, that is, when `x' is in range
//   ['!', '/']   [':', '@']  U  ['[', '\`']  U  ['{', '~'].
// `Summary' provides only two branches for this function. However,
// any attempt to describe this range with if-statements in the body farm
// would result in many more branches. Because each branch needs to be analyzed
// independently, this significantly reduces performance. Additionally,
// once we consider a branch on which `x' is in range, say, ['!', '/'],
// we assume that such branch is an important separate path through the program,
// which may lead to false positives because considering this particular path
// was not consciously intended, and therefore it might have been unreachable.
//
// This checker uses eval::Call for modeling pure functions (functions without
// side effects), for which their `Summary' is a precise model. This avoids
// unnecessary invalidation passes. Conflicts with other checkers are unlikely
// because if the function has no other effects, other checkers would probably
// never want to improve upon the modeling done by this checker.
//
// Non-pure functions, for which only partial improvement over the default
// behavior is expected, are modeled via check::PostCall, non-intrusively.
//
//===----------------------------------------------------------------------===//

#include "ErrnoModeling.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatVariadic.h"

#include <optional>
#include <string>

using namespace clang;
using namespace clang::ento;

namespace {
class StdLibraryFunctionsChecker
    : public Checker<check::PreCall, check::PostCall, eval::Call> {

  class Summary;

  /// Specify how much the analyzer engine should entrust modeling this function
  /// to us.
  enum InvalidationKind {
    /// No \c eval::Call for the function, it can be modeled elsewhere.
    /// This checker checks only pre and post conditions.
    NoEvalCall,
    /// The function is modeled completely in this checker.
    EvalCallAsPure
  };

  /// Given a range, should the argument stay inside or outside this range?
  enum RangeKind { OutOfRange, WithinRange };

  static RangeKind negateKind(RangeKind K) {
    switch (K) {
    case OutOfRange:
      return WithinRange;
    case WithinRange:
      return OutOfRange;
    }
    llvm_unreachable("Unknown range kind");
  }

  /// The universal integral type to use in value range descriptions.
  /// Unsigned to make sure overflows are well-defined.
  typedef uint64_t RangeInt;

  /// Describes a single range constraint. Eg. {{0, 1}, {3, 4}} is
  /// a non-negative integer, which less than 5 and not equal to 2.
  typedef std::vector<std::pair<RangeInt, RangeInt>> IntRangeVector;

  /// A reference to an argument or return value by its number.
  /// ArgNo in CallExpr and CallEvent is defined as Unsigned, but
  /// obviously uint32_t should be enough for all practical purposes.
  typedef uint32_t ArgNo;
  /// Special argument number for specifying the return value.
  static const ArgNo Ret;

  /// Get a string representation of an argument index.
  /// E.g.: (1) -> '1st arg', (2) - > '2nd arg'
  static void printArgDesc(ArgNo, llvm::raw_ostream &Out);
  /// Print value X of the argument in form " (which is X)",
  /// if the value is a fixed known value, otherwise print nothing.
  /// This is used as simple explanation of values if possible.
  static void printArgValueInfo(ArgNo ArgN, ProgramStateRef State,
                                const CallEvent &Call, llvm::raw_ostream &Out);
  /// Append textual description of a numeric range [RMin,RMax] to
  /// \p Out.
  static void appendInsideRangeDesc(llvm::APSInt RMin, llvm::APSInt RMax,
                                    QualType ArgT, BasicValueFactory &BVF,
                                    llvm::raw_ostream &Out);
  /// Append textual description of a numeric range out of [RMin,RMax] to
  /// \p Out.
  static void appendOutOfRangeDesc(llvm::APSInt RMin, llvm::APSInt RMax,
                                   QualType ArgT, BasicValueFactory &BVF,
                                   llvm::raw_ostream &Out);

  class ValueConstraint;

  /// Pointer to the ValueConstraint. We need a copyable, polymorphic and
  /// default initializable type (vector needs that). A raw pointer was good,
  /// however, we cannot default initialize that. unique_ptr makes the Summary
  /// class non-copyable, therefore not an option. Releasing the copyability
  /// requirement would render the initialization of the Summary map infeasible.
  /// Mind that a pointer to a new value constraint is created when the negate
  /// function is used.
  using ValueConstraintPtr = std::shared_ptr<ValueConstraint>;

  /// Polymorphic base class that represents a constraint on a given argument
  /// (or return value) of a function. Derived classes implement different kind
  /// of constraints, e.g range constraints or correlation between two
  /// arguments.
  /// These are used as argument constraints (preconditions) of functions, in
  /// which case a bug report may be emitted if the constraint is not satisfied.
  /// Another use is as conditions for summary cases, to create different
  /// classes of behavior for a function. In this case no description of the
  /// constraint is needed because the summary cases have an own (not generated)
  /// description string.
  class ValueConstraint {
  public:
    ValueConstraint(ArgNo ArgN) : ArgN(ArgN) {}
    virtual ~ValueConstraint() {}

    /// Apply the effects of the constraint on the given program state. If null
    /// is returned then the constraint is not feasible.
    virtual ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                                  const Summary &Summary,
                                  CheckerContext &C) const = 0;

    /// Represents that in which context do we require a description of the
    /// constraint.
    enum DescriptionKind {
      /// Describe a constraint that was violated.
      /// Description should start with something like "should be".
      Violation,
      /// Describe a constraint that was assumed to be true.
      /// This can be used when a precondition is satisfied, or when a summary
      /// case is applied.
      /// Description should start with something like "is".
      Assumption
    };

    /// Give a description that explains the constraint to the user. Used when
    /// a bug is reported or when the constraint is applied and displayed as a
    /// note. The description should not mention the argument (getArgNo).
    /// See StdLibraryFunctionsChecker::reportBug about how this function is
    /// used (this function is used not only there).
    virtual void describe(DescriptionKind DK, const CallEvent &Call,
                          ProgramStateRef State, const Summary &Summary,
                          llvm::raw_ostream &Out) const {
      // There are some descendant classes that are not used as argument
      // constraints, e.g. ComparisonConstraint. In that case we can safely
      // ignore the implementation of this function.
      llvm_unreachable(
          "Description not implemented for summary case constraints");
    }

    /// Give a description that explains the actual argument value (where the
    /// current ValueConstraint applies to) to the user. This function should be
    /// called only when the current constraint is satisfied by the argument.
    /// It should produce a more precise description than the constraint itself.
    /// The actual value of the argument and the program state can be used to
    /// make the description more precise. In the most simple case, if the
    /// argument has a fixed known value this value can be printed into \p Out,
    /// this is done by default.
    /// The function should return true if a description was printed to \p Out,
    /// otherwise false.
    /// See StdLibraryFunctionsChecker::reportBug about how this function is
    /// used.
    virtual bool describeArgumentValue(const CallEvent &Call,
                                       ProgramStateRef State,
                                       const Summary &Summary,
                                       llvm::raw_ostream &Out) const {
      if (auto N = getArgSVal(Call, getArgNo()).getAs<NonLoc>()) {
        if (const llvm::APSInt *Int = N->getAsInteger()) {
          Out << *Int;
          return true;
        }
      }
      return false;
    }

    /// Return those arguments that should be tracked when we report a bug about
    /// argument constraint violation. By default it is the argument that is
    /// constrained, however, in some special cases we need to track other
    /// arguments as well. E.g. a buffer size might be encoded in another
    /// argument.
    /// The "return value" argument number can not occur as returned value.
    virtual std::vector<ArgNo> getArgsToTrack() const { return {ArgN}; }

    /// Get a constraint that represents exactly the opposite of the current.
    virtual ValueConstraintPtr negate() const {
      llvm_unreachable("Not implemented");
    };

    /// Check whether the constraint is malformed or not. It is malformed if the
    /// specified argument has a mismatch with the given FunctionDecl (e.g. the
    /// arg number is out-of-range of the function's argument list).
    /// This condition can indicate if a probably wrong or unexpected function
    /// was found where the constraint is to be applied.
    bool checkValidity(const FunctionDecl *FD) const {
      const bool ValidArg = ArgN == Ret || ArgN < FD->getNumParams();
      assert(ValidArg && "Arg out of range!");
      if (!ValidArg)
        return false;
      // Subclasses may further refine the validation.
      return checkSpecificValidity(FD);
    }

    /// Return the argument number (may be placeholder for "return value").
    ArgNo getArgNo() const { return ArgN; }

  protected:
    /// Argument to which to apply the constraint. It can be a real argument of
    /// the function to check, or a special value to indicate the return value
    /// of the function.
    /// Every constraint is assigned to one main argument, even if other
    /// arguments are involved.
    ArgNo ArgN;

    /// Do constraint-specific validation check.
    virtual bool checkSpecificValidity(const FunctionDecl *FD) const {
      return true;
    }
  };

  /// Check if a single argument falls into a specific "range".
  /// A range is formed as a set of intervals.
  /// E.g. \code {['A', 'Z'], ['a', 'z'], ['_', '_']} \endcode
  /// The intervals are closed intervals that contain one or more values.
  ///
  /// The default constructed RangeConstraint has an empty range, applying
  /// such constraint does not involve any assumptions, thus the State remains
  /// unchanged. This is meaningful, if the range is dependent on a looked up
  /// type (e.g. [0, Socklen_tMax]). If the type is not found, then the range
  /// is default initialized to be empty.
  class RangeConstraint : public ValueConstraint {
    /// The constraint can be specified by allowing or disallowing the range.
    /// WithinRange indicates allowing the range, OutOfRange indicates
    /// disallowing it (allowing the complementary range).
    RangeKind Kind;

    /// A set of intervals.
    IntRangeVector Ranges;

    /// A textual description of this constraint for the specific case where the
    /// constraint is used. If empty a generated description will be used that
    /// is built from the range of the constraint.
    StringRef Description;

  public:
    RangeConstraint(ArgNo ArgN, RangeKind Kind, const IntRangeVector &Ranges,
                    StringRef Desc = "")
        : ValueConstraint(ArgN), Kind(Kind), Ranges(Ranges), Description(Desc) {
    }

    const IntRangeVector &getRanges() const { return Ranges; }

    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override;

    void describe(DescriptionKind DK, const CallEvent &Call,
                  ProgramStateRef State, const Summary &Summary,
                  llvm::raw_ostream &Out) const override;

    bool describeArgumentValue(const CallEvent &Call, ProgramStateRef State,
                               const Summary &Summary,
                               llvm::raw_ostream &Out) const override;

    ValueConstraintPtr negate() const override {
      RangeConstraint Tmp(*this);
      Tmp.Kind = negateKind(Kind);
      return std::make_shared<RangeConstraint>(Tmp);
    }

  protected:
    bool checkSpecificValidity(const FunctionDecl *FD) const override {
      const bool ValidArg =
          getArgType(FD, ArgN)->isIntegralType(FD->getASTContext());
      assert(ValidArg &&
             "This constraint should be applied on an integral type");
      return ValidArg;
    }

  private:
    /// A callback function that is used when iterating over the range
    /// intervals. It gets the begin and end (inclusive) of one interval.
    /// This is used to make any kind of task possible that needs an iteration
    /// over the intervals.
    using RangeApplyFunction =
        std::function<bool(const llvm::APSInt &Min, const llvm::APSInt &Max)>;

    /// Call a function on the intervals of the range.
    /// The function is called with all intervals in the range.
    void applyOnWithinRange(BasicValueFactory &BVF, QualType ArgT,
                            const RangeApplyFunction &F) const;
    /// Call a function on all intervals in the complementary range.
    /// The function is called with all intervals that fall out of the range.
    /// E.g. consider an interval list [A, B] and [C, D]
    /// \code
    /// -------+--------+------------------+------------+----------->
    ///        A        B                  C            D
    /// \endcode
    /// We get the ranges [-inf, A - 1], [D + 1, +inf], [B + 1, C - 1].
    /// The \p ArgT is used to determine the min and max of the type that is
    /// used as "-inf" and "+inf".
    void applyOnOutOfRange(BasicValueFactory &BVF, QualType ArgT,
                           const RangeApplyFunction &F) const;
    /// Call a function on the intervals of the range or the complementary
    /// range.
    void applyOnRange(RangeKind Kind, BasicValueFactory &BVF, QualType ArgT,
                      const RangeApplyFunction &F) const {
      switch (Kind) {
      case OutOfRange:
        applyOnOutOfRange(BVF, ArgT, F);
        break;
      case WithinRange:
        applyOnWithinRange(BVF, ArgT, F);
        break;
      };
    }
  };

  /// Check relation of an argument to another.
  class ComparisonConstraint : public ValueConstraint {
    BinaryOperator::Opcode Opcode;
    ArgNo OtherArgN;

  public:
    ComparisonConstraint(ArgNo ArgN, BinaryOperator::Opcode Opcode,
                         ArgNo OtherArgN)
        : ValueConstraint(ArgN), Opcode(Opcode), OtherArgN(OtherArgN) {}
    ArgNo getOtherArgNo() const { return OtherArgN; }
    BinaryOperator::Opcode getOpcode() const { return Opcode; }
    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override;
  };

  /// Check null or non-null-ness of an argument that is of pointer type.
  class NotNullConstraint : public ValueConstraint {
    using ValueConstraint::ValueConstraint;
    // This variable has a role when we negate the constraint.
    bool CannotBeNull = true;

  public:
    NotNullConstraint(ArgNo ArgN, bool CannotBeNull = true)
        : ValueConstraint(ArgN), CannotBeNull(CannotBeNull) {}

    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override;

    void describe(DescriptionKind DK, const CallEvent &Call,
                  ProgramStateRef State, const Summary &Summary,
                  llvm::raw_ostream &Out) const override;

    bool describeArgumentValue(const CallEvent &Call, ProgramStateRef State,
                               const Summary &Summary,
                               llvm::raw_ostream &Out) const override;

    ValueConstraintPtr negate() const override {
      NotNullConstraint Tmp(*this);
      Tmp.CannotBeNull = !this->CannotBeNull;
      return std::make_shared<NotNullConstraint>(Tmp);
    }

  protected:
    bool checkSpecificValidity(const FunctionDecl *FD) const override {
      const bool ValidArg = getArgType(FD, ArgN)->isPointerType();
      assert(ValidArg &&
             "This constraint should be applied only on a pointer type");
      return ValidArg;
    }
  };

  /// Check null or non-null-ness of an argument that is of pointer type.
  /// The argument is meant to be a buffer that has a size constraint, and it
  /// is allowed to have a NULL value if the size is 0. The size can depend on
  /// 1 or 2 additional arguments, if one of these is 0 the buffer is allowed to
  /// be NULL. This is useful for functions like `fread` which have this special
  /// property.
  class NotNullBufferConstraint : public ValueConstraint {
    using ValueConstraint::ValueConstraint;
    ArgNo SizeArg1N;
    std::optional<ArgNo> SizeArg2N;
    // This variable has a role when we negate the constraint.
    bool CannotBeNull = true;

  public:
    NotNullBufferConstraint(ArgNo ArgN, ArgNo SizeArg1N,
                            std::optional<ArgNo> SizeArg2N,
                            bool CannotBeNull = true)
        : ValueConstraint(ArgN), SizeArg1N(SizeArg1N), SizeArg2N(SizeArg2N),
          CannotBeNull(CannotBeNull) {}

    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override;

    void describe(DescriptionKind DK, const CallEvent &Call,
                  ProgramStateRef State, const Summary &Summary,
                  llvm::raw_ostream &Out) const override;

    bool describeArgumentValue(const CallEvent &Call, ProgramStateRef State,
                               const Summary &Summary,
                               llvm::raw_ostream &Out) const override;

    ValueConstraintPtr negate() const override {
      NotNullBufferConstraint Tmp(*this);
      Tmp.CannotBeNull = !this->CannotBeNull;
      return std::make_shared<NotNullBufferConstraint>(Tmp);
    }

  protected:
    bool checkSpecificValidity(const FunctionDecl *FD) const override {
      const bool ValidArg = getArgType(FD, ArgN)->isPointerType();
      assert(ValidArg &&
             "This constraint should be applied only on a pointer type");
      return ValidArg;
    }
  };

  // Represents a buffer argument with an additional size constraint. The
  // constraint may be a concrete value, or a symbolic value in an argument.
  // Example 1. Concrete value as the minimum buffer size.
  //   char *asctime_r(const struct tm *restrict tm, char *restrict buf);
  //   // `buf` size must be at least 26 bytes according the POSIX standard.
  // Example 2. Argument as a buffer size.
  //   ctime_s(char *buffer, rsize_t bufsz, const time_t *time);
  // Example 3. The size is computed as a multiplication of other args.
  //   size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  //   // Here, ptr is the buffer, and its minimum size is `size * nmemb`.
  class BufferSizeConstraint : public ValueConstraint {
    // The concrete value which is the minimum size for the buffer.
    std::optional<llvm::APSInt> ConcreteSize;
    // The argument which holds the size of the buffer.
    std::optional<ArgNo> SizeArgN;
    // The argument which is a multiplier to size. This is set in case of
    // `fread` like functions where the size is computed as a multiplication of
    // two arguments.
    std::optional<ArgNo> SizeMultiplierArgN;
    // The operator we use in apply. This is negated in negate().
    BinaryOperator::Opcode Op = BO_LE;

  public:
    BufferSizeConstraint(ArgNo Buffer, llvm::APSInt BufMinSize)
        : ValueConstraint(Buffer), ConcreteSize(BufMinSize) {}
    BufferSizeConstraint(ArgNo Buffer, ArgNo BufSize)
        : ValueConstraint(Buffer), SizeArgN(BufSize) {}
    BufferSizeConstraint(ArgNo Buffer, ArgNo BufSize, ArgNo BufSizeMultiplier)
        : ValueConstraint(Buffer), SizeArgN(BufSize),
          SizeMultiplierArgN(BufSizeMultiplier) {}

    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override;

    void describe(DescriptionKind DK, const CallEvent &Call,
                  ProgramStateRef State, const Summary &Summary,
                  llvm::raw_ostream &Out) const override;

    bool describeArgumentValue(const CallEvent &Call, ProgramStateRef State,
                               const Summary &Summary,
                               llvm::raw_ostream &Out) const override;

    std::vector<ArgNo> getArgsToTrack() const override {
      std::vector<ArgNo> Result{ArgN};
      if (SizeArgN)
        Result.push_back(*SizeArgN);
      if (SizeMultiplierArgN)
        Result.push_back(*SizeMultiplierArgN);
      return Result;
    }

    ValueConstraintPtr negate() const override {
      BufferSizeConstraint Tmp(*this);
      Tmp.Op = BinaryOperator::negateComparisonOp(Op);
      return std::make_shared<BufferSizeConstraint>(Tmp);
    }

  protected:
    bool checkSpecificValidity(const FunctionDecl *FD) const override {
      const bool ValidArg = getArgType(FD, ArgN)->isPointerType();
      assert(ValidArg &&
             "This constraint should be applied only on a pointer type");
      return ValidArg;
    }
  };

  /// The complete list of constraints that defines a single branch.
  using ConstraintSet = std::vector<ValueConstraintPtr>;

  /// Define how a function affects the system variable 'errno'.
  /// This works together with the \c ErrnoModeling and \c ErrnoChecker classes.
  /// Currently 3 use cases exist: success, failure, irrelevant.
  /// In the future the failure case can be customized to set \c errno to a
  /// more specific constraint (for example > 0), or new case can be added
  /// for functions which require check of \c errno in both success and failure
  /// case.
  class ErrnoConstraintBase {
  public:
    /// Apply specific state changes related to the errno variable.
    virtual ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                                  const Summary &Summary,
                                  CheckerContext &C) const = 0;
    /// Get a description about what happens with 'errno' here and how it causes
    /// a later bug report created by ErrnoChecker.
    /// Empty return value means that 'errno' related bug may not happen from
    /// the current analyzed function.
    virtual const std::string describe(CheckerContext &C) const { return ""; }

    virtual ~ErrnoConstraintBase() {}

  protected:
    ErrnoConstraintBase() = default;

    /// This is used for conjure symbol for errno to differentiate from the
    /// original call expression (same expression is used for the errno symbol).
    static int Tag;
  };

  /// Reset errno constraints to irrelevant.
  /// This is applicable to functions that may change 'errno' and are not
  /// modeled elsewhere.
  class ResetErrnoConstraint : public ErrnoConstraintBase {
  public:
    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override {
      return errno_modeling::setErrnoState(State, errno_modeling::Irrelevant);
    }
  };

  /// Do not change errno constraints.
  /// This is applicable to functions that are modeled in another checker
  /// and the already set errno constraints should not be changed in the
  /// post-call event.
  class NoErrnoConstraint : public ErrnoConstraintBase {
  public:
    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override {
      return State;
    }
  };

  /// Set errno constraint at failure cases of standard functions.
  /// Failure case: 'errno' becomes not equal to 0 and may or may not be checked
  /// by the program. \c ErrnoChecker does not emit a bug report after such a
  /// function call.
  class FailureErrnoConstraint : public ErrnoConstraintBase {
  public:
    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override {
      SValBuilder &SVB = C.getSValBuilder();
      NonLoc ErrnoSVal =
          SVB.conjureSymbolVal(&Tag, Call.getOriginExpr(),
                               C.getLocationContext(), C.getASTContext().IntTy,
                               C.blockCount())
              .castAs<NonLoc>();
      return errno_modeling::setErrnoForStdFailure(State, C, ErrnoSVal);
    }
  };

  /// Set errno constraint at success cases of standard functions.
  /// Success case: 'errno' is not allowed to be used because the value is
  /// undefined after successful call.
  /// \c ErrnoChecker can emit bug report after such a function call if errno
  /// is used.
  class SuccessErrnoConstraint : public ErrnoConstraintBase {
  public:
    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override {
      return errno_modeling::setErrnoForStdSuccess(State, C);
    }

    const std::string describe(CheckerContext &C) const override {
      return "'errno' becomes undefined after the call";
    }
  };

  /// Set errno constraint at functions that indicate failure only with 'errno'.
  /// In this case 'errno' is required to be observed.
  /// \c ErrnoChecker can emit bug report after such a function call if errno
  /// is overwritten without a read before.
  class ErrnoMustBeCheckedConstraint : public ErrnoConstraintBase {
  public:
    ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                          const Summary &Summary,
                          CheckerContext &C) const override {
      return errno_modeling::setErrnoStdMustBeChecked(State, C,
                                                      Call.getOriginExpr());
    }

    const std::string describe(CheckerContext &C) const override {
      return "reading 'errno' is required to find out if the call has failed";
    }
  };

  /// A single branch of a function summary.
  ///
  /// A branch is defined by a series of constraints - "assumptions" -
  /// that together form a single possible outcome of invoking the function.
  /// When static analyzer considers a branch, it tries to introduce
  /// a child node in the Exploded Graph. The child node has to include
  /// constraints that define the branch. If the constraints contradict
  /// existing constraints in the state, the node is not created and the branch
  /// is dropped; otherwise it's queued for future exploration.
  /// The branch is accompanied by a note text that may be displayed
  /// to the user when a bug is found on a path that takes this branch.
  ///
  /// For example, consider the branches in `isalpha(x)`:
  ///   Branch 1)
  ///     x is in range ['A', 'Z'] or in ['a', 'z']
  ///     then the return value is not 0. (I.e. out-of-range [0, 0])
  ///     and the note may say "Assuming the character is alphabetical"
  ///   Branch 2)
  ///     x is out-of-range ['A', 'Z'] and out-of-range ['a', 'z']
  ///     then the return value is 0
  ///     and the note may say "Assuming the character is non-alphabetical".
  class SummaryCase {
    ConstraintSet Constraints;
    const ErrnoConstraintBase &ErrnoConstraint;
    StringRef Note;

  public:
    SummaryCase(ConstraintSet &&Constraints, const ErrnoConstraintBase &ErrnoC,
                StringRef Note)
        : Constraints(std::move(Constraints)), ErrnoConstraint(ErrnoC),
          Note(Note) {}

    SummaryCase(const ConstraintSet &Constraints,
                const ErrnoConstraintBase &ErrnoC, StringRef Note)
        : Constraints(Constraints), ErrnoConstraint(ErrnoC), Note(Note) {}

    const ConstraintSet &getConstraints() const { return Constraints; }
    const ErrnoConstraintBase &getErrnoConstraint() const {
      return ErrnoConstraint;
    }
    StringRef getNote() const { return Note; }
  };

  using ArgTypes = std::vector<std::optional<QualType>>;
  using RetType = std::optional<QualType>;

  // A placeholder type, we use it whenever we do not care about the concrete
  // type in a Signature.
  const QualType Irrelevant{};
  bool static isIrrelevant(QualType T) { return T.isNull(); }

  // The signature of a function we want to describe with a summary. This is a
  // concessive signature, meaning there may be irrelevant types in the
  // signature which we do not check against a function with concrete types.
  // All types in the spec need to be canonical.
  class Signature {
    using ArgQualTypes = std::vector<QualType>;
    ArgQualTypes ArgTys;
    QualType RetTy;
    // True if any component type is not found by lookup.
    bool Invalid = false;

  public:
    // Construct a signature from optional types. If any of the optional types
    // are not set then the signature will be invalid.
    Signature(ArgTypes ArgTys, RetType RetTy) {
      for (std::optional<QualType> Arg : ArgTys) {
        if (!Arg) {
          Invalid = true;
          return;
        } else {
          assertArgTypeSuitableForSignature(*Arg);
          this->ArgTys.push_back(*Arg);
        }
      }
      if (!RetTy) {
        Invalid = true;
        return;
      } else {
        assertRetTypeSuitableForSignature(*RetTy);
        this->RetTy = *RetTy;
      }
    }

    bool isInvalid() const { return Invalid; }
    bool matches(const FunctionDecl *FD) const;

  private:
    static void assertArgTypeSuitableForSignature(QualType T) {
      assert((T.isNull() || !T->isVoidType()) &&
             "We should have no void types in the spec");
      assert((T.isNull() || T.isCanonical()) &&
             "We should only have canonical types in the spec");
    }
    static void assertRetTypeSuitableForSignature(QualType T) {
      assert((T.isNull() || T.isCanonical()) &&
             "We should only have canonical types in the spec");
    }
  };

  static QualType getArgType(const FunctionDecl *FD, ArgNo ArgN) {
    assert(FD && "Function must be set");
    QualType T = (ArgN == Ret)
                     ? FD->getReturnType().getCanonicalType()
                     : FD->getParamDecl(ArgN)->getType().getCanonicalType();
    return T;
  }

  using SummaryCases = std::vector<SummaryCase>;

  /// A summary includes information about
  ///   * function prototype (signature)
  ///   * approach to invalidation,
  ///   * a list of branches - so, a list of list of ranges,
  ///   * a list of argument constraints, that must be true on every branch.
  ///     If these constraints are not satisfied that means a fatal error
  ///     usually resulting in undefined behaviour.
  ///
  /// Application of a summary:
  ///   The signature and argument constraints together contain information
  ///   about which functions are handled by the summary. The signature can use
  ///   "wildcards", i.e. Irrelevant types. Irrelevant type of a parameter in
  ///   a signature means that type is not compared to the type of the parameter
  ///   in the found FunctionDecl. Argument constraints may specify additional
  ///   rules for the given parameter's type, those rules are checked once the
  ///   signature is matched.
  class Summary {
    const InvalidationKind InvalidationKd;
    SummaryCases Cases;
    ConstraintSet ArgConstraints;

    // The function to which the summary applies. This is set after lookup and
    // match to the signature.
    const FunctionDecl *FD = nullptr;

  public:
    Summary(InvalidationKind InvalidationKd) : InvalidationKd(InvalidationKd) {}

    Summary &Case(ConstraintSet &&CS, const ErrnoConstraintBase &ErrnoC,
                  StringRef Note = "") {
      Cases.push_back(SummaryCase(std::move(CS), ErrnoC, Note));
      return *this;
    }
    Summary &Case(const ConstraintSet &CS, const ErrnoConstraintBase &ErrnoC,
                  StringRef Note = "") {
      Cases.push_back(SummaryCase(CS, ErrnoC, Note));
      return *this;
    }
    Summary &ArgConstraint(ValueConstraintPtr VC) {
      assert(VC->getArgNo() != Ret &&
             "Arg constraint should not refer to the return value");
      ArgConstraints.push_back(VC);
      return *this;
    }

    InvalidationKind getInvalidationKd() const { return InvalidationKd; }
    const SummaryCases &getCases() const { return Cases; }
    const ConstraintSet &getArgConstraints() const { return ArgConstraints; }

    QualType getArgType(ArgNo ArgN) const {
      return StdLibraryFunctionsChecker::getArgType(FD, ArgN);
    }

    // Returns true if the summary should be applied to the given function.
    // And if yes then store the function declaration.
    bool matchesAndSet(const Signature &Sign, const FunctionDecl *FD) {
      bool Result = Sign.matches(FD) && validateByConstraints(FD);
      if (Result) {
        assert(!this->FD && "FD must not be set more than once");
        this->FD = FD;
      }
      return Result;
    }

  private:
    // Once we know the exact type of the function then do validation check on
    // all the given constraints.
    bool validateByConstraints(const FunctionDecl *FD) const {
      for (const SummaryCase &Case : Cases)
        for (const ValueConstraintPtr &Constraint : Case.getConstraints())
          if (!Constraint->checkValidity(FD))
            return false;
      for (const ValueConstraintPtr &Constraint : ArgConstraints)
        if (!Constraint->checkValidity(FD))
          return false;
      return true;
    }
  };

  // The map of all functions supported by the checker. It is initialized
  // lazily, and it doesn't change after initialization.
  using FunctionSummaryMapType = llvm::DenseMap<const FunctionDecl *, Summary>;
  mutable FunctionSummaryMapType FunctionSummaryMap;

  const BugType BT_InvalidArg{this, "Function call with invalid argument"};
  mutable bool SummariesInitialized = false;

  static SVal getArgSVal(const CallEvent &Call, ArgNo ArgN) {
    return ArgN == Ret ? Call.getReturnValue() : Call.getArgSVal(ArgN);
  }
  static std::string getFunctionName(const CallEvent &Call) {
    assert(Call.getDecl() &&
           "Call was found by a summary, should have declaration");
    return cast<NamedDecl>(Call.getDecl())->getNameAsString();
  }

public:
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
  bool evalCall(const CallEvent &Call, CheckerContext &C) const;

  CheckerNameRef CheckName;
  bool AddTestFunctions = false;

  bool DisplayLoadedSummaries = false;
  bool ModelPOSIX = false;
  bool ShouldAssumeControlledEnvironment = false;

private:
  std::optional<Summary> findFunctionSummary(const FunctionDecl *FD,
                                             CheckerContext &C) const;
  std::optional<Summary> findFunctionSummary(const CallEvent &Call,
                                             CheckerContext &C) const;

  void initFunctionSummaries(CheckerContext &C) const;

  void reportBug(const CallEvent &Call, ExplodedNode *N,
                 const ValueConstraint *VC, const ValueConstraint *NegatedVC,
                 const Summary &Summary, CheckerContext &C) const {
    assert(Call.getDecl() &&
           "Function found in summary must have a declaration available");
    SmallString<256> Msg;
    llvm::raw_svector_ostream MsgOs(Msg);

    MsgOs << "The ";
    printArgDesc(VC->getArgNo(), MsgOs);
    MsgOs << " to '" << getFunctionName(Call) << "' ";
    bool ValuesPrinted =
        NegatedVC->describeArgumentValue(Call, N->getState(), Summary, MsgOs);
    if (ValuesPrinted)
      MsgOs << " but ";
    else
      MsgOs << "is out of the accepted range; It ";
    VC->describe(ValueConstraint::Violation, Call, C.getState(), Summary,
                 MsgOs);
    Msg[0] = toupper(Msg[0]);
    auto R = std::make_unique<PathSensitiveBugReport>(BT_InvalidArg, Msg, N);

    for (ArgNo ArgN : VC->getArgsToTrack()) {
      bugreporter::trackExpressionValue(N, Call.getArgExpr(ArgN), *R);
      R->markInteresting(Call.getArgSVal(ArgN));
      // All tracked arguments are important, highlight them.
      R->addRange(Call.getArgSourceRange(ArgN));
    }

    C.emitReport(std::move(R));
  }

  /// These are the errno constraints that can be passed to summary cases.
  /// One of these should fit for a single summary case.
  /// Usually if a failure return value exists for function, that function
  /// needs different cases for success and failure with different errno
  /// constraints (and different return value constraints).
  const NoErrnoConstraint ErrnoUnchanged{};
  const ResetErrnoConstraint ErrnoIrrelevant{};
  const ErrnoMustBeCheckedConstraint ErrnoMustBeChecked{};
  const SuccessErrnoConstraint ErrnoMustNotBeChecked{};
  const FailureErrnoConstraint ErrnoNEZeroIrrelevant{};
};

int StdLibraryFunctionsChecker::ErrnoConstraintBase::Tag = 0;

const StdLibraryFunctionsChecker::ArgNo StdLibraryFunctionsChecker::Ret =
    std::numeric_limits<ArgNo>::max();

static BasicValueFactory &getBVF(ProgramStateRef State) {
  ProgramStateManager &Mgr = State->getStateManager();
  SValBuilder &SVB = Mgr.getSValBuilder();
  return SVB.getBasicValueFactory();
}

} // end of anonymous namespace

void StdLibraryFunctionsChecker::printArgDesc(
    StdLibraryFunctionsChecker::ArgNo ArgN, llvm::raw_ostream &Out) {
  Out << std::to_string(ArgN + 1);
  Out << llvm::getOrdinalSuffix(ArgN + 1);
  Out << " argument";
}

void StdLibraryFunctionsChecker::printArgValueInfo(ArgNo ArgN,
                                                   ProgramStateRef State,
                                                   const CallEvent &Call,
                                                   llvm::raw_ostream &Out) {
  if (const llvm::APSInt *Val =
          State->getStateManager().getSValBuilder().getKnownValue(
              State, getArgSVal(Call, ArgN)))
    Out << " (which is " << *Val << ")";
}

void StdLibraryFunctionsChecker::appendInsideRangeDesc(llvm::APSInt RMin,
                                                       llvm::APSInt RMax,
                                                       QualType ArgT,
                                                       BasicValueFactory &BVF,
                                                       llvm::raw_ostream &Out) {
  if (RMin.isZero() && RMax.isZero())
    Out << "zero";
  else if (RMin == RMax)
    Out << RMin;
  else if (RMin == BVF.getMinValue(ArgT)) {
    if (RMax == -1)
      Out << "< 0";
    else
      Out << "<= " << RMax;
  } else if (RMax == BVF.getMaxValue(ArgT)) {
    if (RMin.isOne())
      Out << "> 0";
    else
      Out << ">= " << RMin;
  } else if (RMin.isNegative() == RMax.isNegative() &&
             RMin.getLimitedValue() == RMax.getLimitedValue() - 1) {
    Out << RMin << " or " << RMax;
  } else {
    Out << "between " << RMin << " and " << RMax;
  }
}

void StdLibraryFunctionsChecker::appendOutOfRangeDesc(llvm::APSInt RMin,
                                                      llvm::APSInt RMax,
                                                      QualType ArgT,
                                                      BasicValueFactory &BVF,
                                                      llvm::raw_ostream &Out) {
  if (RMin.isZero() && RMax.isZero())
    Out << "nonzero";
  else if (RMin == RMax) {
    Out << "not equal to " << RMin;
  } else if (RMin == BVF.getMinValue(ArgT)) {
    if (RMax == -1)
      Out << ">= 0";
    else
      Out << "> " << RMax;
  } else if (RMax == BVF.getMaxValue(ArgT)) {
    if (RMin.isOne())
      Out << "<= 0";
    else
      Out << "< " << RMin;
  } else if (RMin.isNegative() == RMax.isNegative() &&
             RMin.getLimitedValue() == RMax.getLimitedValue() - 1) {
    Out << "not " << RMin << " and not " << RMax;
  } else {
    Out << "not between " << RMin << " and " << RMax;
  }
}

void StdLibraryFunctionsChecker::RangeConstraint::applyOnWithinRange(
    BasicValueFactory &BVF, QualType ArgT, const RangeApplyFunction &F) const {
  if (Ranges.empty())
    return;

  for (auto [Start, End] : getRanges()) {
    const llvm::APSInt &Min = BVF.getValue(Start, ArgT);
    const llvm::APSInt &Max = BVF.getValue(End, ArgT);
    assert(Min <= Max);
    if (!F(Min, Max))
      return;
  }
}

void StdLibraryFunctionsChecker::RangeConstraint::applyOnOutOfRange(
    BasicValueFactory &BVF, QualType ArgT, const RangeApplyFunction &F) const {
  if (Ranges.empty())
    return;

  const IntRangeVector &R = getRanges();
  size_t E = R.size();

  const llvm::APSInt &MinusInf = BVF.getMinValue(ArgT);
  const llvm::APSInt &PlusInf = BVF.getMaxValue(ArgT);

  const llvm::APSInt &RangeLeft = BVF.getValue(R[0].first - 1ULL, ArgT);
  const llvm::APSInt &RangeRight = BVF.getValue(R[E - 1].second + 1ULL, ArgT);

  // Iterate over the "holes" between intervals.
  for (size_t I = 1; I != E; ++I) {
    const llvm::APSInt &Min = BVF.getValue(R[I - 1].second + 1ULL, ArgT);
    const llvm::APSInt &Max = BVF.getValue(R[I].first - 1ULL, ArgT);
    if (Min <= Max) {
      if (!F(Min, Max))
        return;
    }
  }
  // Check the interval [T_MIN, min(R) - 1].
  if (RangeLeft != PlusInf) {
    assert(MinusInf <= RangeLeft);
    if (!F(MinusInf, RangeLeft))
      return;
  }
  // Check the interval [max(R) + 1, T_MAX],
  if (RangeRight != MinusInf) {
    assert(RangeRight <= PlusInf);
    if (!F(RangeRight, PlusInf))
      return;
  }
}

ProgramStateRef StdLibraryFunctionsChecker::RangeConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {
  ConstraintManager &CM = C.getConstraintManager();
  SVal V = getArgSVal(Call, getArgNo());
  QualType T = Summary.getArgType(getArgNo());

  if (auto N = V.getAs<NonLoc>()) {
    auto ExcludeRangeFromArg = [&](const llvm::APSInt &Min,
                                   const llvm::APSInt &Max) {
      State = CM.assumeInclusiveRange(State, *N, Min, Max, false);
      return static_cast<bool>(State);
    };
    // "OutOfRange R" is handled by excluding all ranges in R.
    // "WithinRange R" is treated as "OutOfRange [T_MIN, T_MAX] \ R".
    applyOnRange(negateKind(Kind), C.getSValBuilder().getBasicValueFactory(), T,
                 ExcludeRangeFromArg);
  }

  return State;
}

void StdLibraryFunctionsChecker::RangeConstraint::describe(
    DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
    const Summary &Summary, llvm::raw_ostream &Out) const {

  BasicValueFactory &BVF = getBVF(State);
  QualType T = Summary.getArgType(getArgNo());

  Out << ((DK == Violation) ? "should be " : "is ");
  if (!Description.empty()) {
    Out << Description;
  } else {
    unsigned I = Ranges.size();
    if (Kind == WithinRange) {
      for (const std::pair<RangeInt, RangeInt> &R : Ranges) {
        appendInsideRangeDesc(BVF.getValue(R.first, T),
                              BVF.getValue(R.second, T), T, BVF, Out);
        if (--I > 0)
          Out << " or ";
      }
    } else {
      for (const std::pair<RangeInt, RangeInt> &R : Ranges) {
        appendOutOfRangeDesc(BVF.getValue(R.first, T),
                             BVF.getValue(R.second, T), T, BVF, Out);
        if (--I > 0)
          Out << " and ";
      }
    }
  }
}

bool StdLibraryFunctionsChecker::RangeConstraint::describeArgumentValue(
    const CallEvent &Call, ProgramStateRef State, const Summary &Summary,
    llvm::raw_ostream &Out) const {
  unsigned int NRanges = 0;
  bool HaveAllRanges = true;

  ProgramStateManager &Mgr = State->getStateManager();
  BasicValueFactory &BVF = Mgr.getSValBuilder().getBasicValueFactory();
  ConstraintManager &CM = Mgr.getConstraintManager();
  SVal V = getArgSVal(Call, getArgNo());

  if (auto N = V.getAs<NonLoc>()) {
    if (const llvm::APSInt *Int = N->getAsInteger()) {
      Out << "is ";
      Out << *Int;
      return true;
    }
    QualType T = Summary.getArgType(getArgNo());
    SmallString<128> MoreInfo;
    llvm::raw_svector_ostream MoreInfoOs(MoreInfo);
    auto ApplyF = [&](const llvm::APSInt &Min, const llvm::APSInt &Max) {
      if (CM.assumeInclusiveRange(State, *N, Min, Max, true)) {
        if (NRanges > 0)
          MoreInfoOs << " or ";
        appendInsideRangeDesc(Min, Max, T, BVF, MoreInfoOs);
        ++NRanges;
      } else {
        HaveAllRanges = false;
      }
      return true;
    };

    applyOnRange(Kind, BVF, T, ApplyF);
    assert(NRanges > 0);
    if (!HaveAllRanges || NRanges == 1) {
      Out << "is ";
      Out << MoreInfo;
      return true;
    }
  }
  return false;
}

ProgramStateRef StdLibraryFunctionsChecker::ComparisonConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {

  ProgramStateManager &Mgr = State->getStateManager();
  SValBuilder &SVB = Mgr.getSValBuilder();
  QualType CondT = SVB.getConditionType();
  QualType T = Summary.getArgType(getArgNo());
  SVal V = getArgSVal(Call, getArgNo());

  BinaryOperator::Opcode Op = getOpcode();
  ArgNo OtherArg = getOtherArgNo();
  SVal OtherV = getArgSVal(Call, OtherArg);
  QualType OtherT = Summary.getArgType(OtherArg);
  // Note: we avoid integral promotion for comparison.
  OtherV = SVB.evalCast(OtherV, T, OtherT);
  if (auto CompV = SVB.evalBinOp(State, Op, V, OtherV, CondT)
                       .getAs<DefinedOrUnknownSVal>())
    State = State->assume(*CompV, true);
  return State;
}

ProgramStateRef StdLibraryFunctionsChecker::NotNullConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {
  SVal V = getArgSVal(Call, getArgNo());
  if (V.isUndef())
    return State;

  DefinedOrUnknownSVal L = V.castAs<DefinedOrUnknownSVal>();
  if (!isa<Loc>(L))
    return State;

  return State->assume(L, CannotBeNull);
}

void StdLibraryFunctionsChecker::NotNullConstraint::describe(
    DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
    const Summary &Summary, llvm::raw_ostream &Out) const {
  assert(CannotBeNull &&
         "Describe should not be used when the value must be NULL");
  if (DK == Violation)
    Out << "should not be NULL";
  else
    Out << "is not NULL";
}

bool StdLibraryFunctionsChecker::NotNullConstraint::describeArgumentValue(
    const CallEvent &Call, ProgramStateRef State, const Summary &Summary,
    llvm::raw_ostream &Out) const {
  assert(!CannotBeNull && "This function is used when the value is NULL");
  Out << "is NULL";
  return true;
}

ProgramStateRef StdLibraryFunctionsChecker::NotNullBufferConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {
  SVal V = getArgSVal(Call, getArgNo());
  if (V.isUndef())
    return State;
  DefinedOrUnknownSVal L = V.castAs<DefinedOrUnknownSVal>();
  if (!isa<Loc>(L))
    return State;

  std::optional<DefinedOrUnknownSVal> SizeArg1 =
      getArgSVal(Call, SizeArg1N).getAs<DefinedOrUnknownSVal>();
  std::optional<DefinedOrUnknownSVal> SizeArg2;
  if (SizeArg2N)
    SizeArg2 = getArgSVal(Call, *SizeArg2N).getAs<DefinedOrUnknownSVal>();

  auto IsArgZero = [State](std::optional<DefinedOrUnknownSVal> Val) {
    if (!Val)
      return false;
    auto [IsNonNull, IsNull] = State->assume(*Val);
    return IsNull && !IsNonNull;
  };

  if (IsArgZero(SizeArg1) || IsArgZero(SizeArg2))
    return State;

  return State->assume(L, CannotBeNull);
}

void StdLibraryFunctionsChecker::NotNullBufferConstraint::describe(
    DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
    const Summary &Summary, llvm::raw_ostream &Out) const {
  assert(CannotBeNull &&
         "Describe should not be used when the value must be NULL");
  if (DK == Violation)
    Out << "should not be NULL";
  else
    Out << "is not NULL";
}

bool StdLibraryFunctionsChecker::NotNullBufferConstraint::describeArgumentValue(
    const CallEvent &Call, ProgramStateRef State, const Summary &Summary,
    llvm::raw_ostream &Out) const {
  assert(!CannotBeNull && "This function is used when the value is NULL");
  Out << "is NULL";
  return true;
}

ProgramStateRef StdLibraryFunctionsChecker::BufferSizeConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {
  SValBuilder &SvalBuilder = C.getSValBuilder();
  // The buffer argument.
  SVal BufV = getArgSVal(Call, getArgNo());

  // Get the size constraint.
  const SVal SizeV = [this, &State, &Call, &Summary, &SvalBuilder]() {
    if (ConcreteSize) {
      return SVal(SvalBuilder.makeIntVal(*ConcreteSize));
    }
    assert(SizeArgN && "The constraint must be either a concrete value or "
                       "encoded in an argument.");
    // The size argument.
    SVal SizeV = getArgSVal(Call, *SizeArgN);
    // Multiply with another argument if given.
    if (SizeMultiplierArgN) {
      SVal SizeMulV = getArgSVal(Call, *SizeMultiplierArgN);
      SizeV = SvalBuilder.evalBinOp(State, BO_Mul, SizeV, SizeMulV,
                                    Summary.getArgType(*SizeArgN));
    }
    return SizeV;
  }();

  // The dynamic size of the buffer argument, got from the analyzer engine.
  SVal BufDynSize = getDynamicExtentWithOffset(State, BufV);

  SVal Feasible = SvalBuilder.evalBinOp(State, Op, SizeV, BufDynSize,
                                        SvalBuilder.getContext().BoolTy);
  if (auto F = Feasible.getAs<DefinedOrUnknownSVal>())
    return State->assume(*F, true);

  // We can get here only if the size argument or the dynamic size is
  // undefined. But the dynamic size should never be undefined, only
  // unknown. So, here, the size of the argument is undefined, i.e. we
  // cannot apply the constraint. Actually, other checkers like
  // CallAndMessage should catch this situation earlier, because we call a
  // function with an uninitialized argument.
  llvm_unreachable("Size argument or the dynamic size is Undefined");
}

void StdLibraryFunctionsChecker::BufferSizeConstraint::describe(
    DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
    const Summary &Summary, llvm::raw_ostream &Out) const {
  Out << ((DK == Violation) ? "should be " : "is ");
  Out << "a buffer with size equal to or greater than ";
  if (ConcreteSize) {
    Out << *ConcreteSize;
  } else if (SizeArgN) {
    Out << "the value of the ";
    printArgDesc(*SizeArgN, Out);
    printArgValueInfo(*SizeArgN, State, Call, Out);
    if (SizeMultiplierArgN) {
      Out << " times the ";
      printArgDesc(*SizeMultiplierArgN, Out);
      printArgValueInfo(*SizeMultiplierArgN, State, Call, Out);
    }
  }
}

bool StdLibraryFunctionsChecker::BufferSizeConstraint::describeArgumentValue(
    const CallEvent &Call, ProgramStateRef State, const Summary &Summary,
    llvm::raw_ostream &Out) const {
  SVal BufV = getArgSVal(Call, getArgNo());
  SVal BufDynSize = getDynamicExtentWithOffset(State, BufV);
  if (const llvm::APSInt *Val =
          State->getStateManager().getSValBuilder().getKnownValue(State,
                                                                  BufDynSize)) {
    Out << "is a buffer with size " << *Val;
    return true;
  }
  return false;
}

void StdLibraryFunctionsChecker::checkPreCall(const CallEvent &Call,
                                              CheckerContext &C) const {
  std::optional<Summary> FoundSummary = findFunctionSummary(Call, C);
  if (!FoundSummary)
    return;

  const Summary &Summary = *FoundSummary;
  ProgramStateRef State = C.getState();

  ProgramStateRef NewState = State;
  ExplodedNode *NewNode = C.getPredecessor();
  for (const ValueConstraintPtr &Constraint : Summary.getArgConstraints()) {
    ValueConstraintPtr NegatedConstraint = Constraint->negate();
    ProgramStateRef SuccessSt = Constraint->apply(NewState, Call, Summary, C);
    ProgramStateRef FailureSt =
        NegatedConstraint->apply(NewState, Call, Summary, C);
    // The argument constraint is not satisfied.
    if (FailureSt && !SuccessSt) {
      if (ExplodedNode *N = C.generateErrorNode(State, NewNode))
        reportBug(Call, N, Constraint.get(), NegatedConstraint.get(), Summary,
                  C);
      break;
    }
    // We will apply the constraint even if we cannot reason about the
    // argument. This means both SuccessSt and FailureSt can be true. If we
    // weren't applying the constraint that would mean that symbolic
    // execution continues on a code whose behaviour is undefined.
    assert(SuccessSt);
    NewState = SuccessSt;
    if (NewState != State) {
      SmallString<128> Msg;
      llvm::raw_svector_ostream Os(Msg);
      Os << "Assuming that the ";
      printArgDesc(Constraint->getArgNo(), Os);
      Os << " to '";
      Os << getFunctionName(Call);
      Os << "' ";
      Constraint->describe(ValueConstraint::Assumption, Call, NewState, Summary,
                           Os);
      const auto ArgSVal = Call.getArgSVal(Constraint->getArgNo());
      NewNode = C.addTransition(
          NewState, NewNode,
          C.getNoteTag([Msg = std::move(Msg), ArgSVal](
                           PathSensitiveBugReport &BR, llvm::raw_ostream &OS) {
            if (BR.isInteresting(ArgSVal))
              OS << Msg;
          }));
    }
  }
}

void StdLibraryFunctionsChecker::checkPostCall(const CallEvent &Call,
                                               CheckerContext &C) const {
  std::optional<Summary> FoundSummary = findFunctionSummary(Call, C);
  if (!FoundSummary)
    return;

  // Now apply the constraints.
  const Summary &Summary = *FoundSummary;
  ProgramStateRef State = C.getState();
  ExplodedNode *Node = C.getPredecessor();

  // Apply case/branch specifications.
  for (const SummaryCase &Case : Summary.getCases()) {
    ProgramStateRef NewState = State;
    for (const ValueConstraintPtr &Constraint : Case.getConstraints()) {
      NewState = Constraint->apply(NewState, Call, Summary, C);
      if (!NewState)
        break;
    }

    if (NewState)
      NewState = Case.getErrnoConstraint().apply(NewState, Call, Summary, C);

    if (!NewState)
      continue;

    // Here it's possible that NewState == State, e.g. when other checkers
    // already applied the same constraints (or stricter ones).
    // Still add these note tags, the other checker should add only its
    // specialized note tags. These general note tags are handled always by
    // StdLibraryFunctionsChecker.

    ExplodedNode *Pred = Node;
    DeclarationName FunctionName =
        cast<NamedDecl>(Call.getDecl())->getDeclName();

    std::string ErrnoNote = Case.getErrnoConstraint().describe(C);
    std::string CaseNote;
    if (Case.getNote().empty()) {
      if (!ErrnoNote.empty())
        ErrnoNote =
            llvm::formatv("After calling '{0}' {1}", FunctionName, ErrnoNote);
    } else {
      CaseNote = llvm::formatv(Case.getNote().str().c_str(), FunctionName);
    }
    const SVal RV = Call.getReturnValue();

    if (Summary.getInvalidationKd() == EvalCallAsPure) {
      // Do not expect that errno is interesting (the "pure" functions do not
      // affect it).
      if (!CaseNote.empty()) {
        const NoteTag *Tag = C.getNoteTag(
            [Node, CaseNote, RV](PathSensitiveBugReport &BR) -> std::string {
              // Try to omit the note if we know in advance which branch is
              // taken (this means, only one branch exists).
              // This check is performed inside the lambda, after other
              // (or this) checkers had a chance to add other successors.
              // Dereferencing the saved node object is valid because it's part
              // of a bug report call sequence.
              // FIXME: This check is not exact. We may be here after a state
              // split that was performed by another checker (and can not find
              // the successors). This is why this check is only used in the
              // EvalCallAsPure case.
              if (BR.isInteresting(RV) && Node->succ_size() > 1)
                return CaseNote;
              return "";
            });
        Pred = C.addTransition(NewState, Pred, Tag);
      }
    } else {
      if (!CaseNote.empty() || !ErrnoNote.empty()) {
        const NoteTag *Tag =
            C.getNoteTag([CaseNote, ErrnoNote,
                          RV](PathSensitiveBugReport &BR) -> std::string {
              // If 'errno' is interesting, show the user a note about the case
              // (what happened at the function call) and about how 'errno'
              // causes the problem. ErrnoChecker sets the errno (but not RV) to
              // interesting.
              // If only the return value is interesting, show only the case
              // note.
              std::optional<Loc> ErrnoLoc =
                  errno_modeling::getErrnoLoc(BR.getErrorNode()->getState());
              bool ErrnoImportant = !ErrnoNote.empty() && ErrnoLoc &&
                                    BR.isInteresting(ErrnoLoc->getAsRegion());
              if (ErrnoImportant) {
                BR.markNotInteresting(ErrnoLoc->getAsRegion());
                if (CaseNote.empty())
                  return ErrnoNote;
                return llvm::formatv("{0}; {1}", CaseNote, ErrnoNote);
              } else {
                if (BR.isInteresting(RV))
                  return CaseNote;
              }
              return "";
            });
        Pred = C.addTransition(NewState, Pred, Tag);
      }
    }

    // Add the transition if no note tag was added.
    if (Pred == Node && NewState != State)
      C.addTransition(NewState);
  }
}

bool StdLibraryFunctionsChecker::evalCall(const CallEvent &Call,
                                          CheckerContext &C) const {
  std::optional<Summary> FoundSummary = findFunctionSummary(Call, C);
  if (!FoundSummary)
    return false;

  const Summary &Summary = *FoundSummary;
  switch (Summary.getInvalidationKd()) {
  case EvalCallAsPure: {
    ProgramStateRef State = C.getState();
    const LocationContext *LC = C.getLocationContext();
    const auto *CE = cast<CallExpr>(Call.getOriginExpr());
    SVal V = C.getSValBuilder().conjureSymbolVal(
        CE, LC, CE->getType().getCanonicalType(), C.blockCount());
    State = State->BindExpr(CE, LC, V);

    C.addTransition(State);

    return true;
  }
  case NoEvalCall:
    // Summary tells us to avoid performing eval::Call. The function is possibly
    // evaluated by another checker, or evaluated conservatively.
    return false;
  }
  llvm_unreachable("Unknown invalidation kind!");
}

bool StdLibraryFunctionsChecker::Signature::matches(
    const FunctionDecl *FD) const {
  assert(!isInvalid());
  // Check the number of arguments.
  if (FD->param_size() != ArgTys.size())
    return false;

  // The "restrict" keyword is illegal in C++, however, many libc
  // implementations use the "__restrict" compiler intrinsic in functions
  // prototypes. The "__restrict" keyword qualifies a type as a restricted type
  // even in C++.
  // In case of any non-C99 languages, we don't want to match based on the
  // restrict qualifier because we cannot know if the given libc implementation
  // qualifies the paramter type or not.
  auto RemoveRestrict = [&FD](QualType T) {
    if (!FD->getASTContext().getLangOpts().C99)
      T.removeLocalRestrict();
    return T;
  };

  // Check the return type.
  if (!isIrrelevant(RetTy)) {
    QualType FDRetTy = RemoveRestrict(FD->getReturnType().getCanonicalType());
    if (RetTy != FDRetTy)
      return false;
  }

  // Check the argument types.
  for (auto [Idx, ArgTy] : llvm::enumerate(ArgTys)) {
    if (isIrrelevant(ArgTy))
      continue;
    QualType FDArgTy =
        RemoveRestrict(FD->getParamDecl(Idx)->getType().getCanonicalType());
    if (ArgTy != FDArgTy)
      return false;
  }

  return true;
}

std::optional<StdLibraryFunctionsChecker::Summary>
StdLibraryFunctionsChecker::findFunctionSummary(const FunctionDecl *FD,
                                                CheckerContext &C) const {
  if (!FD)
    return std::nullopt;

  initFunctionSummaries(C);

  auto FSMI = FunctionSummaryMap.find(FD->getCanonicalDecl());
  if (FSMI == FunctionSummaryMap.end())
    return std::nullopt;
  return FSMI->second;
}

std::optional<StdLibraryFunctionsChecker::Summary>
StdLibraryFunctionsChecker::findFunctionSummary(const CallEvent &Call,
                                                CheckerContext &C) const {
  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
  if (!FD)
    return std::nullopt;
  return findFunctionSummary(FD, C);
}

void StdLibraryFunctionsChecker::initFunctionSummaries(
    CheckerContext &C) const {
  if (SummariesInitialized)
    return;
  SummariesInitialized = true;

  SValBuilder &SVB = C.getSValBuilder();
  BasicValueFactory &BVF = SVB.getBasicValueFactory();
  const ASTContext &ACtx = BVF.getContext();
  Preprocessor &PP = C.getPreprocessor();

  // Helper class to lookup a type by its name.
  class LookupType {
    const ASTContext &ACtx;

  public:
    LookupType(const ASTContext &ACtx) : ACtx(ACtx) {}

    // Find the type. If not found then the optional is not set.
    std::optional<QualType> operator()(StringRef Name) {
      IdentifierInfo &II = ACtx.Idents.get(Name);
      auto LookupRes = ACtx.getTranslationUnitDecl()->lookup(&II);
      if (LookupRes.empty())
        return std::nullopt;

      // Prioritze typedef declarations.
      // This is needed in case of C struct typedefs. E.g.:
      //   typedef struct FILE FILE;
      // In this case, we have a RecordDecl 'struct FILE' with the name 'FILE'
      // and we have a TypedefDecl with the name 'FILE'.
      for (Decl *D : LookupRes)
        if (auto *TD = dyn_cast<TypedefNameDecl>(D))
          return ACtx.getTypeDeclType(TD).getCanonicalType();

      // Find the first TypeDecl.
      // There maybe cases when a function has the same name as a struct.
      // E.g. in POSIX: `struct stat` and the function `stat()`:
      //   int stat(const char *restrict path, struct stat *restrict buf);
      for (Decl *D : LookupRes)
        if (auto *TD = dyn_cast<TypeDecl>(D))
          return ACtx.getTypeDeclType(TD).getCanonicalType();
      return std::nullopt;
    }
  } lookupTy(ACtx);

  // Below are auxiliary classes to handle optional types that we get as a
  // result of the lookup.
  class GetRestrictTy {
    const ASTContext &ACtx;

  public:
    GetRestrictTy(const ASTContext &ACtx) : ACtx(ACtx) {}
    QualType operator()(QualType Ty) {
      return ACtx.getLangOpts().C99 ? ACtx.getRestrictType(Ty) : Ty;
    }
    std::optional<QualType> operator()(std::optional<QualType> Ty) {
      if (Ty)
        return operator()(*Ty);
      return std::nullopt;
    }
  } getRestrictTy(ACtx);
  class GetPointerTy {
    const ASTContext &ACtx;

  public:
    GetPointerTy(const ASTContext &ACtx) : ACtx(ACtx) {}
    QualType operator()(QualType Ty) { return ACtx.getPointerType(Ty); }
    std::optional<QualType> operator()(std::optional<QualType> Ty) {
      if (Ty)
        return operator()(*Ty);
      return std::nullopt;
    }
  } getPointerTy(ACtx);
  class {
  public:
    std::optional<QualType> operator()(std::optional<QualType> Ty) {
      return Ty ? std::optional<QualType>(Ty->withConst()) : std::nullopt;
    }
    QualType operator()(QualType Ty) { return Ty.withConst(); }
  } getConstTy;
  class GetMaxValue {
    BasicValueFactory &BVF;

  public:
    GetMaxValue(BasicValueFactory &BVF) : BVF(BVF) {}
    std::optional<RangeInt> operator()(QualType Ty) {
      return BVF.getMaxValue(Ty).getLimitedValue();
    }
    std::optional<RangeInt> operator()(std::optional<QualType> Ty) {
      if (Ty) {
        return operator()(*Ty);
      }
      return std::nullopt;
    }
  } getMaxValue(BVF);

  // These types are useful for writing specifications quickly,
  // New specifications should probably introduce more types.
  // Some types are hard to obtain from the AST, eg. "ssize_t".
  // In such cases it should be possible to provide multiple variants
  // of function summary for common cases (eg. ssize_t could be int or long
  // or long long, so three summary variants would be enough).
  // Of course, function variants are also useful for C++ overloads.
  const QualType VoidTy = ACtx.VoidTy;
  const QualType CharTy = ACtx.CharTy;
  const QualType WCharTy = ACtx.WCharTy;
  const QualType IntTy = ACtx.IntTy;
  const QualType UnsignedIntTy = ACtx.UnsignedIntTy;
  const QualType LongTy = ACtx.LongTy;
  const QualType SizeTy = ACtx.getSizeType();

  const QualType VoidPtrTy = getPointerTy(VoidTy); // void *
  const QualType IntPtrTy = getPointerTy(IntTy);   // int *
  const QualType UnsignedIntPtrTy =
      getPointerTy(UnsignedIntTy); // unsigned int *
  const QualType VoidPtrRestrictTy = getRestrictTy(VoidPtrTy);
  const QualType ConstVoidPtrTy =
      getPointerTy(getConstTy(VoidTy));            // const void *
  const QualType CharPtrTy = getPointerTy(CharTy); // char *
  const QualType CharPtrRestrictTy = getRestrictTy(CharPtrTy);
  const QualType ConstCharPtrTy =
      getPointerTy(getConstTy(CharTy)); // const char *
  const QualType ConstCharPtrRestrictTy = getRestrictTy(ConstCharPtrTy);
  const QualType Wchar_tPtrTy = getPointerTy(WCharTy); // wchar_t *
  const QualType ConstWchar_tPtrTy =
      getPointerTy(getConstTy(WCharTy)); // const wchar_t *
  const QualType ConstVoidPtrRestrictTy = getRestrictTy(ConstVoidPtrTy);
  const QualType SizePtrTy = getPointerTy(SizeTy);
  const QualType SizePtrRestrictTy = getRestrictTy(SizePtrTy);

  const RangeInt IntMax = BVF.getMaxValue(IntTy).getLimitedValue();
  const RangeInt UnsignedIntMax =
      BVF.getMaxValue(UnsignedIntTy).getLimitedValue();
  const RangeInt LongMax = BVF.getMaxValue(LongTy).getLimitedValue();
  const RangeInt SizeMax = BVF.getMaxValue(SizeTy).getLimitedValue();

  // Set UCharRangeMax to min of int or uchar maximum value.
  // The C standard states that the arguments of functions like isalpha must
  // be representable as an unsigned char. Their type is 'int', so the max
  // value of the argument should be min(UCharMax, IntMax). This just happen
  // to be true for commonly used and well tested instruction set
  // architectures, but not for others.
  const RangeInt UCharRangeMax =
      std::min(BVF.getMaxValue(ACtx.UnsignedCharTy).getLimitedValue(), IntMax);

  // Get platform dependent values of some macros.
  // Try our best to parse this from the Preprocessor, otherwise fallback to a
  // default value (what is found in a library header).
  const auto EOFv = tryExpandAsInteger("EOF", PP).value_or(-1);
  const auto AT_FDCWDv = tryExpandAsInteger("AT_FDCWD", PP).value_or(-100);

  // Auxiliary class to aid adding summaries to the summary map.
  struct AddToFunctionSummaryMap {
    const ASTContext &ACtx;
    FunctionSummaryMapType &Map;
    bool DisplayLoadedSummaries;
    AddToFunctionSummaryMap(const ASTContext &ACtx, FunctionSummaryMapType &FSM,
                            bool DisplayLoadedSummaries)
        : ACtx(ACtx), Map(FSM), DisplayLoadedSummaries(DisplayLoadedSummaries) {
    }

    // Add a summary to a FunctionDecl found by lookup. The lookup is performed
    // by the given Name, and in the global scope. The summary will be attached
    // to the found FunctionDecl only if the signatures match.
    //
    // Returns true if the summary has been added, false otherwise.
    bool operator()(StringRef Name, Signature Sign, Summary Sum) {
      if (Sign.isInvalid())
        return false;
      IdentifierInfo &II = ACtx.Idents.get(Name);
      auto LookupRes = ACtx.getTranslationUnitDecl()->lookup(&II);
      if (LookupRes.empty())
        return false;
      for (Decl *D : LookupRes) {
        if (auto *FD = dyn_cast<FunctionDecl>(D)) {
          if (Sum.matchesAndSet(Sign, FD)) {
            auto Res = Map.insert({FD->getCanonicalDecl(), Sum});
            assert(Res.second && "Function already has a summary set!");
            (void)Res;
            if (DisplayLoadedSummaries) {
              llvm::errs() << "Loaded summary for: ";
              FD->print(llvm::errs());
              llvm::errs() << "\n";
            }
            return true;
          }
        }
      }
      return false;
    }
    // Add the same summary for different names with the Signature explicitly
    // given.
    void operator()(std::vector<StringRef> Names, Signature Sign, Summary Sum) {
      for (StringRef Name : Names)
        operator()(Name, Sign, Sum);
    }
  } addToFunctionSummaryMap(ACtx, FunctionSummaryMap, DisplayLoadedSummaries);

  // Below are helpers functions to create the summaries.
  auto ArgumentCondition = [](ArgNo ArgN, RangeKind Kind, IntRangeVector Ranges,
                              StringRef Desc = "") {
    return std::make_shared<RangeConstraint>(ArgN, Kind, Ranges, Desc);
  };
  auto BufferSize = [](auto... Args) {
    return std::make_shared<BufferSizeConstraint>(Args...);
  };
  struct {
    auto operator()(RangeKind Kind, IntRangeVector Ranges) {
      return std::make_shared<RangeConstraint>(Ret, Kind, Ranges);
    }
    auto operator()(BinaryOperator::Opcode Op, ArgNo OtherArgN) {
      return std::make_shared<ComparisonConstraint>(Ret, Op, OtherArgN);
    }
  } ReturnValueCondition;
  struct {
    auto operator()(RangeInt b, RangeInt e) {
      return IntRangeVector{std::pair<RangeInt, RangeInt>{b, e}};
    }
    auto operator()(RangeInt b, std::optional<RangeInt> e) {
      if (e)
        return IntRangeVector{std::pair<RangeInt, RangeInt>{b, *e}};
      return IntRangeVector{};
    }
    auto operator()(std::pair<RangeInt, RangeInt> i0,
                    std::pair<RangeInt, std::optional<RangeInt>> i1) {
      if (i1.second)
        return IntRangeVector{i0, {i1.first, *(i1.second)}};
      return IntRangeVector{i0};
    }
  } Range;
  auto SingleValue = [](RangeInt v) {
    return IntRangeVector{std::pair<RangeInt, RangeInt>{v, v}};
  };
  auto LessThanOrEq = BO_LE;
  auto NotNull = [&](ArgNo ArgN) {
    return std::make_shared<NotNullConstraint>(ArgN);
  };
  auto IsNull = [&](ArgNo ArgN) {
    return std::make_shared<NotNullConstraint>(ArgN, false);
  };
  auto NotNullBuffer = [&](ArgNo ArgN, ArgNo SizeArg1N, ArgNo SizeArg2N) {
    return std::make_shared<NotNullBufferConstraint>(ArgN, SizeArg1N,
                                                     SizeArg2N);
  };

  std::optional<QualType> FileTy = lookupTy("FILE");
  std::optional<QualType> FilePtrTy = getPointerTy(FileTy);
  std::optional<QualType> FilePtrRestrictTy = getRestrictTy(FilePtrTy);

  std::optional<QualType> FPosTTy = lookupTy("fpos_t");
  std::optional<QualType> FPosTPtrTy = getPointerTy(FPosTTy);
  std::optional<QualType> ConstFPosTPtrTy = getPointerTy(getConstTy(FPosTTy));
  std::optional<QualType> FPosTPtrRestrictTy = getRestrictTy(FPosTPtrTy);

  constexpr llvm::StringLiteral GenericSuccessMsg(
      "Assuming that '{0}' is successful");
  constexpr llvm::StringLiteral GenericFailureMsg("Assuming that '{0}' fails");

  // We are finally ready to define specifications for all supported functions.
  //
  // Argument ranges should always cover all variants. If return value
  // is completely unknown, omit it from the respective range set.
  //
  // Every item in the list of range sets represents a particular
  // execution path the analyzer would need to explore once
  // the call is modeled - a new program state is constructed
  // for every range set, and each range line in the range set
  // corresponds to a specific constraint within this state.

  // The isascii() family of functions.
  // The behavior is undefined if the value of the argument is not
  // representable as unsigned char or is not equal to EOF. See e.g. C99
  // 7.4.1.2 The isalpha function (p: 181-182).
  addToFunctionSummaryMap(
      "isalnum", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          // Boils down to isupper() or islower() or isdigit().
          .Case({ArgumentCondition(0U, WithinRange,
                                   {{'0', '9'}, {'A', 'Z'}, {'a', 'z'}}),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is alphanumeric")
          // The locale-specific range.
          // No post-condition. We are completely unaware of
          // locale-specific return values.
          .Case({ArgumentCondition(0U, WithinRange, {{128, UCharRangeMax}})},
                ErrnoIrrelevant)
          .Case(
              {ArgumentCondition(
                   0U, OutOfRange,
                   {{'0', '9'}, {'A', 'Z'}, {'a', 'z'}, {128, UCharRangeMax}}),
               ReturnValueCondition(WithinRange, SingleValue(0))},
              ErrnoIrrelevant, "Assuming the character is non-alphanumeric")
          .ArgConstraint(ArgumentCondition(0U, WithinRange,
                                           {{EOFv, EOFv}, {0, UCharRangeMax}},
                                           "an unsigned char value or EOF")));
  addToFunctionSummaryMap(
      "isalpha", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .Case({ArgumentCondition(0U, WithinRange, {{'A', 'Z'}, {'a', 'z'}}),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is alphabetical")
          // The locale-specific range.
          .Case({ArgumentCondition(0U, WithinRange, {{128, UCharRangeMax}})},
                ErrnoIrrelevant)
          .Case({ArgumentCondition(
                     0U, OutOfRange,
                     {{'A', 'Z'}, {'a', 'z'}, {128, UCharRangeMax}}),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is non-alphabetical"));
  addToFunctionSummaryMap(
      "isascii", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .Case({ArgumentCondition(0U, WithinRange, Range(0, 127)),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is an ASCII character")
          .Case({ArgumentCondition(0U, OutOfRange, Range(0, 127)),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is not an ASCII character"));
  addToFunctionSummaryMap(
      "isblank", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .Case({ArgumentCondition(0U, WithinRange, {{'\t', '\t'}, {' ', ' '}}),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is a blank character")
          .Case({ArgumentCondition(0U, OutOfRange, {{'\t', '\t'}, {' ', ' '}}),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is not a blank character"));
  addToFunctionSummaryMap(
      "iscntrl", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .Case({ArgumentCondition(0U, WithinRange, {{0, 32}, {127, 127}}),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is a control character")
          .Case({ArgumentCondition(0U, OutOfRange, {{0, 32}, {127, 127}}),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is not a control character"));
  addToFunctionSummaryMap(
      "isdigit", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .Case({ArgumentCondition(0U, WithinRange, Range('0', '9')),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is a digit")
          .Case({ArgumentCondition(0U, OutOfRange, Range('0', '9')),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is not a digit"));
  addToFunctionSummaryMap(
      "isgraph", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .Case({ArgumentCondition(0U, WithinRange, Range(33, 126)),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character has graphical representation")
          .Case(
              {ArgumentCondition(0U, OutOfRange, Range(33, 126)),
               ReturnValueCondition(WithinRange, SingleValue(0))},
              ErrnoIrrelevant,
              "Assuming the character does not have graphical representation"));
  addToFunctionSummaryMap(
      "islower", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          // Is certainly lowercase.
          .Case({ArgumentCondition(0U, WithinRange, Range('a', 'z')),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is a lowercase letter")
          // Is ascii but not lowercase.
          .Case({ArgumentCondition(0U, WithinRange, Range(0, 127)),
                 ArgumentCondition(0U, OutOfRange, Range('a', 'z')),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is not a lowercase letter")
          // The locale-specific range.
          .Case({ArgumentCondition(0U, WithinRange, {{128, UCharRangeMax}})},
                ErrnoIrrelevant)
          // Is not an unsigned char.
          .Case({ArgumentCondition(0U, OutOfRange, Range(0, UCharRangeMax)),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant));
  addToFunctionSummaryMap(
      "isprint", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .Case({ArgumentCondition(0U, WithinRange, Range(32, 126)),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is printable")
          .Case({ArgumentCondition(0U, OutOfRange, Range(32, 126)),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is non-printable"));
  addToFunctionSummaryMap(
      "ispunct", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .Case({ArgumentCondition(
                     0U, WithinRange,
                     {{'!', '/'}, {':', '@'}, {'[', '`'}, {'{', '~'}}),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant, "Assuming the character is a punctuation mark")
          .Case({ArgumentCondition(
                     0U, OutOfRange,
                     {{'!', '/'}, {':', '@'}, {'[', '`'}, {'{', '~'}}),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is not a punctuation mark"));
  addToFunctionSummaryMap(
      "isspace", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          // Space, '\f', '\n', '\r', '\t', '\v'.
          .Case({ArgumentCondition(0U, WithinRange, {{9, 13}, {' ', ' '}}),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is a whitespace character")
          // The locale-specific range.
          .Case({ArgumentCondition(0U, WithinRange, {{128, UCharRangeMax}})},
                ErrnoIrrelevant)
          .Case({ArgumentCondition(0U, OutOfRange,
                                   {{9, 13}, {' ', ' '}, {128, UCharRangeMax}}),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is not a whitespace character"));
  addToFunctionSummaryMap(
      "isupper", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          // Is certainly uppercase.
          .Case({ArgumentCondition(0U, WithinRange, Range('A', 'Z')),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is an uppercase letter")
          // The locale-specific range.
          .Case({ArgumentCondition(0U, WithinRange, {{128, UCharRangeMax}})},
                ErrnoIrrelevant)
          // Other.
          .Case({ArgumentCondition(0U, OutOfRange,
                                   {{'A', 'Z'}, {128, UCharRangeMax}}),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is not an uppercase letter"));
  addToFunctionSummaryMap(
      "isxdigit", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .Case({ArgumentCondition(0U, WithinRange,
                                   {{'0', '9'}, {'A', 'F'}, {'a', 'f'}}),
                 ReturnValueCondition(OutOfRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is a hexadecimal digit")
          .Case({ArgumentCondition(0U, OutOfRange,
                                   {{'0', '9'}, {'A', 'F'}, {'a', 'f'}}),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoIrrelevant,
                "Assuming the character is not a hexadecimal digit"));
  addToFunctionSummaryMap(
      "toupper", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .ArgConstraint(ArgumentCondition(0U, WithinRange,
                                           {{EOFv, EOFv}, {0, UCharRangeMax}},
                                           "an unsigned char value or EOF")));
  addToFunctionSummaryMap(
      "tolower", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .ArgConstraint(ArgumentCondition(0U, WithinRange,
                                           {{EOFv, EOFv}, {0, UCharRangeMax}},
                                           "an unsigned char value or EOF")));
  addToFunctionSummaryMap(
      "toascii", Signature(ArgTypes{IntTy}, RetType{IntTy}),
      Summary(EvalCallAsPure)
          .ArgConstraint(ArgumentCondition(0U, WithinRange,
                                           {{EOFv, EOFv}, {0, UCharRangeMax}},
                                           "an unsigned char value or EOF")));

  addToFunctionSummaryMap(
      "getchar", Signature(ArgTypes{}, RetType{IntTy}),
      Summary(NoEvalCall)
          .Case({ReturnValueCondition(WithinRange,
                                      {{EOFv, EOFv}, {0, UCharRangeMax}})},
                ErrnoIrrelevant));

  // read()-like functions that never return more than buffer size.
  auto FreadSummary =
      Summary(NoEvalCall)
          .Case({ArgumentCondition(1U, WithinRange, Range(1, SizeMax)),
                 ArgumentCondition(2U, WithinRange, Range(1, SizeMax)),
                 ReturnValueCondition(BO_LT, ArgNo(2)),
                 ReturnValueCondition(WithinRange, Range(0, SizeMax))},
                ErrnoNEZeroIrrelevant, GenericFailureMsg)
          .Case({ArgumentCondition(1U, WithinRange, Range(1, SizeMax)),
                 ReturnValueCondition(BO_EQ, ArgNo(2)),
                 ReturnValueCondition(WithinRange, Range(0, SizeMax))},
                ErrnoMustNotBeChecked, GenericSuccessMsg)
          .Case({ArgumentCondition(1U, WithinRange, SingleValue(0)),
                 ReturnValueCondition(WithinRange, SingleValue(0))},
                ErrnoMustNotBeChecked,
                "Assuming that argument 'size' to '{0}' is 0")
          .ArgConstraint(NotNullBuffer(ArgNo(0), ArgNo(1), ArgNo(2)))
          .ArgConstraint(NotNull(ArgNo(3)))
          .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1),
                                    /*BufSizeMultiplier=*/ArgNo(2)));

  // size_t fread(void *restrict ptr, size_t size, size_t nitems,
  //              FILE *restrict stream);
  addToFunctionSummaryMap(
      "fread",
      Signature(ArgTypes{VoidPtrRestrictTy, SizeTy, SizeTy, FilePtrRestrictTy},
                RetType{SizeTy}),
      FreadSummary);
  // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems,
  //               FILE *restrict stream);
  addToFunctionSummaryMap("fwrite",
                          Signature(ArgTypes{ConstVoidPtrRestrictTy, SizeTy,
                                             SizeTy, FilePtrRestrictTy},
                                    RetType{SizeTy}),
                          FreadSummary);

  std::optional<QualType> Ssize_tTy = lookupTy("ssize_t");
  std::optional<RangeInt> Ssize_tMax = getMaxValue(Ssize_tTy);

  auto ReadSummary =
      Summary(NoEvalCall)
          .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
                 ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))},
                ErrnoIrrelevant);

  // FIXME these are actually defined by POSIX and not by the C standard, we
  // should handle them together with the rest of the POSIX functions.
  // ssize_t read(int fildes, void *buf, size_t nbyte);
  addToFunctionSummaryMap(
      "read", Signature(ArgTypes{IntTy, VoidPtrTy, SizeTy}, RetType{Ssize_tTy}),
      ReadSummary);
  // ssize_t write(int fildes, const void *buf, size_t nbyte);
  addToFunctionSummaryMap(
      "write",
      Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy}, RetType{Ssize_tTy}),
      ReadSummary);

  auto GetLineSummary =
      Summary(NoEvalCall)
          .Case({ReturnValueCondition(WithinRange,
                                      Range({-1, -1}, {1, Ssize_tMax}))},
                ErrnoIrrelevant);

  QualType CharPtrPtrRestrictTy = getRestrictTy(getPointerTy(CharPtrTy));

  // getline()-like functions either fail or read at least the delimiter.
  // FIXME these are actually defined by POSIX and not by the C standard, we
  // should handle them together with the rest of the POSIX functions.
  // ssize_t getline(char **restrict lineptr, size_t *restrict n,
  //                 FILE *restrict stream);
  addToFunctionSummaryMap(
      "getline",
      Signature(
          ArgTypes{CharPtrPtrRestrictTy, SizePtrRestrictTy, FilePtrRestrictTy},
          RetType{Ssize_tTy}),
      GetLineSummary);
  // ssize_t getdelim(char **restrict lineptr, size_t *restrict n,
  //                  int delimiter, FILE *restrict stream);
  addToFunctionSummaryMap(
      "getdelim",
      Signature(ArgTypes{CharPtrPtrRestrictTy, SizePtrRestrictTy, IntTy,
                         FilePtrRestrictTy},
                RetType{Ssize_tTy}),
      GetLineSummary);

  {
    Summary GetenvSummary =
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .Case({NotNull(Ret)}, ErrnoIrrelevant,
                  "Assuming the environment variable exists");
    // In untrusted environments the envvar might not exist.
    if (!ShouldAssumeControlledEnvironment)
      GetenvSummary.Case({NotNull(Ret)->negate()}, ErrnoIrrelevant,
                         "Assuming the environment variable does not exist");

    // char *getenv(const char *name);
    addToFunctionSummaryMap(
        "getenv", Signature(ArgTypes{ConstCharPtrTy}, RetType{CharPtrTy}),
        std::move(GetenvSummary));
  }

  if (!ModelPOSIX) {
    // Without POSIX use of 'errno' is not specified (in these cases).
    // Add these functions without 'errno' checks.
    addToFunctionSummaryMap(
        {"getc", "fgetc"}, Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(WithinRange,
                                        {{EOFv, EOFv}, {0, UCharRangeMax}})},
                  ErrnoIrrelevant)
            .ArgConstraint(NotNull(ArgNo(0))));
  } else {
    const auto ReturnsZeroOrMinusOne =
        ConstraintSet{ReturnValueCondition(WithinRange, Range(-1, 0))};
    const auto ReturnsZero =
        ConstraintSet{ReturnValueCondition(WithinRange, SingleValue(0))};
    const auto ReturnsMinusOne =
        ConstraintSet{ReturnValueCondition(WithinRange, SingleValue(-1))};
    const auto ReturnsEOF =
        ConstraintSet{ReturnValueCondition(WithinRange, SingleValue(EOFv))};
    const auto ReturnsNonnegative =
        ConstraintSet{ReturnValueCondition(WithinRange, Range(0, IntMax))};
    const auto ReturnsNonZero =
        ConstraintSet{ReturnValueCondition(OutOfRange, SingleValue(0))};
    const auto ReturnsFileDescriptor =
        ConstraintSet{ReturnValueCondition(WithinRange, Range(-1, IntMax))};
    const auto &ReturnsValidFileDescriptor = ReturnsNonnegative;

    auto ValidFileDescriptorOrAtFdcwd = [&](ArgNo ArgN) {
      return std::make_shared<RangeConstraint>(
          ArgN, WithinRange, Range({AT_FDCWDv, AT_FDCWDv}, {0, IntMax}),
          "a valid file descriptor or AT_FDCWD");
    };

    // FILE *fopen(const char *restrict pathname, const char *restrict mode);
    addToFunctionSummaryMap(
        "fopen",
        Signature(ArgTypes{ConstCharPtrRestrictTy, ConstCharPtrRestrictTy},
                  RetType{FilePtrTy}),
        Summary(NoEvalCall)
            .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // FILE *fdopen(int fd, const char *mode);
    addToFunctionSummaryMap(
        "fdopen",
        Signature(ArgTypes{IntTy, ConstCharPtrTy}, RetType{FilePtrTy}),
        Summary(NoEvalCall)
            .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // FILE *tmpfile(void);
    addToFunctionSummaryMap(
        "tmpfile", Signature(ArgTypes{}, RetType{FilePtrTy}),
        Summary(NoEvalCall)
            .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg));

    // FILE *freopen(const char *restrict pathname, const char *restrict mode,
    //               FILE *restrict stream);
    addToFunctionSummaryMap(
        "freopen",
        Signature(ArgTypes{ConstCharPtrRestrictTy, ConstCharPtrRestrictTy,
                           FilePtrRestrictTy},
                  RetType{FilePtrTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(BO_EQ, ArgNo(2))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(1)))
            .ArgConstraint(NotNull(ArgNo(2))));

    // FILE *popen(const char *command, const char *type);
    addToFunctionSummaryMap(
        "popen",
        Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}),
        Summary(NoEvalCall)
            .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int fclose(FILE *stream);
    addToFunctionSummaryMap(
        "fclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsEOF, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int pclose(FILE *stream);
    addToFunctionSummaryMap(
        "pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(WithinRange, {{0, IntMax}})},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    std::optional<QualType> Off_tTy = lookupTy("off_t");
    std::optional<RangeInt> Off_tMax = getMaxValue(Off_tTy);

    // int fgetc(FILE *stream);
    // 'getc' is the same as 'fgetc' but may be a macro
    addToFunctionSummaryMap(
        {"getc", "fgetc"}, Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(WithinRange, {{0, UCharRangeMax}})},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
                  ErrnoIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int fputc(int c, FILE *stream);
    // 'putc' is the same as 'fputc' but may be a macro
    addToFunctionSummaryMap(
        {"putc", "fputc"},
        Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case({ArgumentCondition(0, WithinRange, Range(0, UCharRangeMax)),
                   ReturnValueCondition(BO_EQ, ArgNo(0))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ArgumentCondition(0, OutOfRange, Range(0, UCharRangeMax)),
                   ReturnValueCondition(WithinRange, Range(0, UCharRangeMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
                  ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(1))));

    // char *fgets(char *restrict s, int n, FILE *restrict stream);
    addToFunctionSummaryMap(
        "fgets",
        Signature(ArgTypes{CharPtrRestrictTy, IntTy, FilePtrRestrictTy},
                  RetType{CharPtrTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(BO_EQ, ArgNo(0))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(ArgumentCondition(1, WithinRange, Range(0, IntMax)))
            .ArgConstraint(
                BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1)))
            .ArgConstraint(NotNull(ArgNo(2))));

    // int fputs(const char *restrict s, FILE *restrict stream);
    addToFunctionSummaryMap(
        "fputs",
        Signature(ArgTypes{ConstCharPtrRestrictTy, FilePtrRestrictTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsNonnegative, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
                  ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int ungetc(int c, FILE *stream);
    addToFunctionSummaryMap(
        "ungetc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(BO_EQ, ArgNo(0)),
                   ArgumentCondition(0, WithinRange, {{0, UCharRangeMax}})},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv)),
                   ArgumentCondition(0, WithinRange, SingleValue(EOFv))},
                  ErrnoNEZeroIrrelevant,
                  "Assuming that 'ungetc' fails because EOF was passed as "
                  "character")
            .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv)),
                   ArgumentCondition(0, WithinRange, {{0, UCharRangeMax}})},
                  ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ArgumentCondition(
                0, WithinRange, {{EOFv, EOFv}, {0, UCharRangeMax}}))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int fseek(FILE *stream, long offset, int whence);
    // FIXME: It can be possible to get the 'SEEK_' values (like EOFv) and use
    // these for condition of arg 2.
    // Now the range [0,2] is used (the `SEEK_*` constants are usually 0,1,2).
    addToFunctionSummaryMap(
        "fseek", Signature(ArgTypes{FilePtrTy, LongTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(ArgumentCondition(2, WithinRange, {{0, 2}})));

    // int fseeko(FILE *stream, off_t offset, int whence);
    addToFunctionSummaryMap(
        "fseeko",
        Signature(ArgTypes{FilePtrTy, Off_tTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(ArgumentCondition(2, WithinRange, {{0, 2}})));

    // int fgetpos(FILE *restrict stream, fpos_t *restrict pos);
    // From 'The Open Group Base Specifications Issue 7, 2018 edition':
    // "The fgetpos() function shall not change the setting of errno if
    // successful."
    addToFunctionSummaryMap(
        "fgetpos",
        Signature(ArgTypes{FilePtrRestrictTy, FPosTPtrRestrictTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoUnchanged, GenericSuccessMsg)
            .Case(ReturnsNonZero, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int fsetpos(FILE *stream, const fpos_t *pos);
    // From 'The Open Group Base Specifications Issue 7, 2018 edition':
    // "The fsetpos() function shall not change the setting of errno if
    // successful."
    addToFunctionSummaryMap(
        "fsetpos",
        Signature(ArgTypes{FilePtrTy, ConstFPosTPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoUnchanged, GenericSuccessMsg)
            .Case(ReturnsNonZero, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int fflush(FILE *stream);
    addToFunctionSummaryMap(
        "fflush", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsEOF, ErrnoNEZeroIrrelevant, GenericFailureMsg));

    // long ftell(FILE *stream);
    // From 'The Open Group Base Specifications Issue 7, 2018 edition':
    // "The ftell() function shall not change the setting of errno if
    // successful."
    addToFunctionSummaryMap(
        "ftell", Signature(ArgTypes{FilePtrTy}, RetType{LongTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(WithinRange, Range(0, LongMax))},
                  ErrnoUnchanged, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // off_t ftello(FILE *stream);
    addToFunctionSummaryMap(
        "ftello", Signature(ArgTypes{FilePtrTy}, RetType{Off_tTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(WithinRange, Range(0, Off_tMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int fileno(FILE *stream);
    // According to POSIX 'fileno' may fail and set 'errno'.
    // But in Linux it may fail only if the specified file pointer is invalid.
    // At many places 'fileno' is used without check for failure and a failure
    // case here would produce a large amount of likely false positive warnings.
    // To avoid this, we assume here that it does not fail.
    addToFunctionSummaryMap(
        "fileno", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoUnchanged, GenericSuccessMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // void rewind(FILE *stream);
    // This function indicates error only by setting of 'errno'.
    addToFunctionSummaryMap("rewind",
                            Signature(ArgTypes{FilePtrTy}, RetType{VoidTy}),
                            Summary(NoEvalCall)
                                .Case({}, ErrnoMustBeChecked)
                                .ArgConstraint(NotNull(ArgNo(0))));

    // void clearerr(FILE *stream);
    addToFunctionSummaryMap(
        "clearerr", Signature(ArgTypes{FilePtrTy}, RetType{VoidTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // int feof(FILE *stream);
    addToFunctionSummaryMap(
        "feof", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // int ferror(FILE *stream);
    addToFunctionSummaryMap(
        "ferror", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // long a64l(const char *str64);
    addToFunctionSummaryMap(
        "a64l", Signature(ArgTypes{ConstCharPtrTy}, RetType{LongTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // char *l64a(long value);
    addToFunctionSummaryMap("l64a",
                            Signature(ArgTypes{LongTy}, RetType{CharPtrTy}),
                            Summary(NoEvalCall)
                                .ArgConstraint(ArgumentCondition(
                                    0, WithinRange, Range(0, LongMax))));

    // int open(const char *path, int oflag, ...);
    addToFunctionSummaryMap(
        "open", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
                  GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int openat(int fd, const char *path, int oflag, ...);
    addToFunctionSummaryMap(
        "openat",
        Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
                  GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int access(const char *pathname, int amode);
    addToFunctionSummaryMap(
        "access", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int faccessat(int dirfd, const char *pathname, int mode, int flags);
    addToFunctionSummaryMap(
        "faccessat",
        Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy, IntTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int dup(int fildes);
    addToFunctionSummaryMap(
        "dup", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
                  GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int dup2(int fildes1, int filedes2);
    addToFunctionSummaryMap(
        "dup2", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
                  GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
            .ArgConstraint(
                ArgumentCondition(1, WithinRange, Range(0, IntMax))));

    // int fdatasync(int fildes);
    addToFunctionSummaryMap(
        "fdatasync", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int fnmatch(const char *pattern, const char *string, int flags);
    addToFunctionSummaryMap(
        "fnmatch",
        Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy, IntTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int fsync(int fildes);
    addToFunctionSummaryMap(
        "fsync", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int truncate(const char *path, off_t length);
    addToFunctionSummaryMap(
        "truncate",
        Signature(ArgTypes{ConstCharPtrTy, Off_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int symlink(const char *oldpath, const char *newpath);
    addToFunctionSummaryMap(
        "symlink",
        Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int symlinkat(const char *oldpath, int newdirfd, const char *newpath);
    addToFunctionSummaryMap(
        "symlinkat",
        Signature(ArgTypes{ConstCharPtrTy, IntTy, ConstCharPtrTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(1)))
            .ArgConstraint(NotNull(ArgNo(2))));

    // int lockf(int fd, int cmd, off_t len);
    addToFunctionSummaryMap(
        "lockf", Signature(ArgTypes{IntTy, IntTy, Off_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    std::optional<QualType> Mode_tTy = lookupTy("mode_t");

    // int creat(const char *pathname, mode_t mode);
    addToFunctionSummaryMap(
        "creat", Signature(ArgTypes{ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
                  GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // unsigned int sleep(unsigned int seconds);
    addToFunctionSummaryMap(
        "sleep", Signature(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}),
        Summary(NoEvalCall)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, UnsignedIntMax))));

    std::optional<QualType> DirTy = lookupTy("DIR");
    std::optional<QualType> DirPtrTy = getPointerTy(DirTy);

    // int dirfd(DIR *dirp);
    addToFunctionSummaryMap(
        "dirfd", Signature(ArgTypes{DirPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
                  GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // unsigned int alarm(unsigned int seconds);
    addToFunctionSummaryMap(
        "alarm", Signature(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}),
        Summary(NoEvalCall)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, UnsignedIntMax))));

    // int closedir(DIR *dir);
    addToFunctionSummaryMap(
        "closedir", Signature(ArgTypes{DirPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // char *strdup(const char *s);
    addToFunctionSummaryMap(
        "strdup", Signature(ArgTypes{ConstCharPtrTy}, RetType{CharPtrTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // char *strndup(const char *s, size_t n);
    addToFunctionSummaryMap(
        "strndup",
        Signature(ArgTypes{ConstCharPtrTy, SizeTy}, RetType{CharPtrTy}),
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(
                ArgumentCondition(1, WithinRange, Range(0, SizeMax))));

    // wchar_t *wcsdup(const wchar_t *s);
    addToFunctionSummaryMap(
        "wcsdup", Signature(ArgTypes{ConstWchar_tPtrTy}, RetType{Wchar_tPtrTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // int mkstemp(char *template);
    addToFunctionSummaryMap(
        "mkstemp", Signature(ArgTypes{CharPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
                  GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // char *mkdtemp(char *template);
    addToFunctionSummaryMap(
        "mkdtemp", Signature(ArgTypes{CharPtrTy}, RetType{CharPtrTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(BO_EQ, ArgNo(0))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // char *getcwd(char *buf, size_t size);
    addToFunctionSummaryMap(
        "getcwd", Signature(ArgTypes{CharPtrTy, SizeTy}, RetType{CharPtrTy}),
        Summary(NoEvalCall)
            .Case({ArgumentCondition(1, WithinRange, Range(1, SizeMax)),
                   ReturnValueCondition(BO_EQ, ArgNo(0))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ArgumentCondition(1, WithinRange, SingleValue(0)),
                   IsNull(Ret)},
                  ErrnoNEZeroIrrelevant, "Assuming that argument 'size' is 0")
            .Case({ArgumentCondition(1, WithinRange, Range(1, SizeMax)),
                   IsNull(Ret)},
                  ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(
                BufferSize(/*Buffer*/ ArgNo(0), /*BufSize*/ ArgNo(1)))
            .ArgConstraint(
                ArgumentCondition(1, WithinRange, Range(0, SizeMax))));

    // int mkdir(const char *pathname, mode_t mode);
    addToFunctionSummaryMap(
        "mkdir", Signature(ArgTypes{ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int mkdirat(int dirfd, const char *pathname, mode_t mode);
    addToFunctionSummaryMap(
        "mkdirat",
        Signature(ArgTypes{IntTy, ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    std::optional<QualType> Dev_tTy = lookupTy("dev_t");

    // int mknod(const char *pathname, mode_t mode, dev_t dev);
    addToFunctionSummaryMap(
        "mknod",
        Signature(ArgTypes{ConstCharPtrTy, Mode_tTy, Dev_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev);
    addToFunctionSummaryMap(
        "mknodat",
        Signature(ArgTypes{IntTy, ConstCharPtrTy, Mode_tTy, Dev_tTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int chmod(const char *path, mode_t mode);
    addToFunctionSummaryMap(
        "chmod", Signature(ArgTypes{ConstCharPtrTy, Mode_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);
    addToFunctionSummaryMap(
        "fchmodat",
        Signature(ArgTypes{IntTy, ConstCharPtrTy, Mode_tTy, IntTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int fchmod(int fildes, mode_t mode);
    addToFunctionSummaryMap(
        "fchmod", Signature(ArgTypes{IntTy, Mode_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    std::optional<QualType> Uid_tTy = lookupTy("uid_t");
    std::optional<QualType> Gid_tTy = lookupTy("gid_t");

    // int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group,
    //              int flags);
    addToFunctionSummaryMap(
        "fchownat",
        Signature(ArgTypes{IntTy, ConstCharPtrTy, Uid_tTy, Gid_tTy, IntTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int chown(const char *path, uid_t owner, gid_t group);
    addToFunctionSummaryMap(
        "chown",
        Signature(ArgTypes{ConstCharPtrTy, Uid_tTy, Gid_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int lchown(const char *path, uid_t owner, gid_t group);
    addToFunctionSummaryMap(
        "lchown",
        Signature(ArgTypes{ConstCharPtrTy, Uid_tTy, Gid_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int fchown(int fildes, uid_t owner, gid_t group);
    addToFunctionSummaryMap(
        "fchown", Signature(ArgTypes{IntTy, Uid_tTy, Gid_tTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int rmdir(const char *pathname);
    addToFunctionSummaryMap(
        "rmdir", Signature(ArgTypes{ConstCharPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int chdir(const char *path);
    addToFunctionSummaryMap(
        "chdir", Signature(ArgTypes{ConstCharPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int link(const char *oldpath, const char *newpath);
    addToFunctionSummaryMap(
        "link",
        Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int linkat(int fd1, const char *path1, int fd2, const char *path2,
    //            int flag);
    addToFunctionSummaryMap(
        "linkat",
        Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy, ConstCharPtrTy, IntTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1)))
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(2)))
            .ArgConstraint(NotNull(ArgNo(3))));

    // int unlink(const char *pathname);
    addToFunctionSummaryMap(
        "unlink", Signature(ArgTypes{ConstCharPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int unlinkat(int fd, const char *path, int flag);
    addToFunctionSummaryMap(
        "unlinkat",
        Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    std::optional<QualType> StructStatTy = lookupTy("stat");
    std::optional<QualType> StructStatPtrTy = getPointerTy(StructStatTy);
    std::optional<QualType> StructStatPtrRestrictTy =
        getRestrictTy(StructStatPtrTy);

    // int fstat(int fd, struct stat *statbuf);
    addToFunctionSummaryMap(
        "fstat", Signature(ArgTypes{IntTy, StructStatPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int stat(const char *restrict path, struct stat *restrict buf);
    addToFunctionSummaryMap(
        "stat",
        Signature(ArgTypes{ConstCharPtrRestrictTy, StructStatPtrRestrictTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int lstat(const char *restrict path, struct stat *restrict buf);
    addToFunctionSummaryMap(
        "lstat",
        Signature(ArgTypes{ConstCharPtrRestrictTy, StructStatPtrRestrictTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int fstatat(int fd, const char *restrict path,
    //             struct stat *restrict buf, int flag);
    addToFunctionSummaryMap(
        "fstatat",
        Signature(ArgTypes{IntTy, ConstCharPtrRestrictTy,
                           StructStatPtrRestrictTy, IntTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1)))
            .ArgConstraint(NotNull(ArgNo(2))));

    // DIR *opendir(const char *name);
    addToFunctionSummaryMap(
        "opendir", Signature(ArgTypes{ConstCharPtrTy}, RetType{DirPtrTy}),
        Summary(NoEvalCall)
            .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // DIR *fdopendir(int fd);
    addToFunctionSummaryMap(
        "fdopendir", Signature(ArgTypes{IntTy}, RetType{DirPtrTy}),
        Summary(NoEvalCall)
            .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int isatty(int fildes);
    addToFunctionSummaryMap(
        "isatty", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(WithinRange, Range(0, 1))},
                  ErrnoIrrelevant)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int close(int fildes);
    addToFunctionSummaryMap(
        "close", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(-1, IntMax))));

    // long fpathconf(int fildes, int name);
    addToFunctionSummaryMap("fpathconf",
                            Signature(ArgTypes{IntTy, IntTy}, RetType{LongTy}),
                            Summary(NoEvalCall)
                                .ArgConstraint(ArgumentCondition(
                                    0, WithinRange, Range(0, IntMax))));

    // long pathconf(const char *path, int name);
    addToFunctionSummaryMap(
        "pathconf", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{LongTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // void rewinddir(DIR *dir);
    addToFunctionSummaryMap(
        "rewinddir", Signature(ArgTypes{DirPtrTy}, RetType{VoidTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // void seekdir(DIR *dirp, long loc);
    addToFunctionSummaryMap(
        "seekdir", Signature(ArgTypes{DirPtrTy, LongTy}, RetType{VoidTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // int rand_r(unsigned int *seedp);
    addToFunctionSummaryMap(
        "rand_r", Signature(ArgTypes{UnsignedIntPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // void *mmap(void *addr, size_t length, int prot, int flags, int fd,
    // off_t offset);
    // FIXME: Improve for errno modeling.
    addToFunctionSummaryMap(
        "mmap",
        Signature(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, Off_tTy},
                  RetType{VoidPtrTy}),
        Summary(NoEvalCall)
            .ArgConstraint(ArgumentCondition(1, WithinRange, Range(1, SizeMax)))
            .ArgConstraint(
                ArgumentCondition(4, WithinRange, Range(-1, IntMax))));

    std::optional<QualType> Off64_tTy = lookupTy("off64_t");
    // void *mmap64(void *addr, size_t length, int prot, int flags, int fd,
    // off64_t offset);
    // FIXME: Improve for errno modeling.
    addToFunctionSummaryMap(
        "mmap64",
        Signature(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, Off64_tTy},
                  RetType{VoidPtrTy}),
        Summary(NoEvalCall)
            .ArgConstraint(ArgumentCondition(1, WithinRange, Range(1, SizeMax)))
            .ArgConstraint(
                ArgumentCondition(4, WithinRange, Range(-1, IntMax))));

    // int pipe(int fildes[2]);
    addToFunctionSummaryMap(
        "pipe", Signature(ArgTypes{IntPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // off_t lseek(int fildes, off_t offset, int whence);
    // In the first case we can not tell for sure if it failed or not.
    // A return value different from of the expected offset (that is unknown
    // here) may indicate failure. For this reason we do not enforce the errno
    // check (can cause false positive).
    addToFunctionSummaryMap(
        "lseek", Signature(ArgTypes{IntTy, Off_tTy, IntTy}, RetType{Off_tTy}),
        Summary(NoEvalCall)
            .Case(ReturnsNonnegative, ErrnoIrrelevant)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // ssize_t readlink(const char *restrict path, char *restrict buf,
    //                  size_t bufsize);
    addToFunctionSummaryMap(
        "readlink",
        Signature(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy},
                  RetType{Ssize_tTy}),
        Summary(NoEvalCall)
            .Case({ArgumentCondition(2, WithinRange, Range(1, IntMax)),
                   ReturnValueCondition(LessThanOrEq, ArgNo(2)),
                   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ArgumentCondition(2, WithinRange, SingleValue(0)),
                   ReturnValueCondition(WithinRange, SingleValue(0))},
                  ErrnoMustNotBeChecked,
                  "Assuming that argument 'bufsize' is 0")
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1)))
            .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
                                      /*BufSize=*/ArgNo(2)))
            .ArgConstraint(
                ArgumentCondition(2, WithinRange, Range(0, SizeMax))));

    // ssize_t readlinkat(int fd, const char *restrict path,
    //                    char *restrict buf, size_t bufsize);
    addToFunctionSummaryMap(
        "readlinkat",
        Signature(
            ArgTypes{IntTy, ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy},
            RetType{Ssize_tTy}),
        Summary(NoEvalCall)
            .Case({ArgumentCondition(3, WithinRange, Range(1, IntMax)),
                   ReturnValueCondition(LessThanOrEq, ArgNo(3)),
                   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ArgumentCondition(3, WithinRange, SingleValue(0)),
                   ReturnValueCondition(WithinRange, SingleValue(0))},
                  ErrnoMustNotBeChecked,
                  "Assuming that argument 'bufsize' is 0")
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1)))
            .ArgConstraint(NotNull(ArgNo(2)))
            .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(2),
                                      /*BufSize=*/ArgNo(3)))
            .ArgConstraint(
                ArgumentCondition(3, WithinRange, Range(0, SizeMax))));

    // int renameat(int olddirfd, const char *oldpath, int newdirfd, const char
    // *newpath);
    addToFunctionSummaryMap(
        "renameat",
        Signature(ArgTypes{IntTy, ConstCharPtrTy, IntTy, ConstCharPtrTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1)))
            .ArgConstraint(ValidFileDescriptorOrAtFdcwd(ArgNo(2)))
            .ArgConstraint(NotNull(ArgNo(3))));

    // char *realpath(const char *restrict file_name,
    //                char *restrict resolved_name);
    // FIXME: If the argument 'resolved_name' is not NULL, macro 'PATH_MAX'
    //        should be defined in "limits.h" to guarrantee a success.
    addToFunctionSummaryMap(
        "realpath",
        Signature(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy},
                  RetType{CharPtrTy}),
        Summary(NoEvalCall)
            .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    QualType CharPtrConstPtr = getPointerTy(getConstTy(CharPtrTy));

    // int execv(const char *path, char *const argv[]);
    addToFunctionSummaryMap(
        "execv",
        Signature(ArgTypes{ConstCharPtrTy, CharPtrConstPtr}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int execvp(const char *file, char *const argv[]);
    addToFunctionSummaryMap(
        "execvp",
        Signature(ArgTypes{ConstCharPtrTy, CharPtrConstPtr}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int getopt(int argc, char * const argv[], const char *optstring);
    addToFunctionSummaryMap(
        "getopt",
        Signature(ArgTypes{IntTy, CharPtrConstPtr, ConstCharPtrTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(WithinRange, Range(-1, UCharRangeMax))},
                  ErrnoIrrelevant)
            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
            .ArgConstraint(NotNull(ArgNo(1)))
            .ArgConstraint(NotNull(ArgNo(2))));

    std::optional<QualType> StructSockaddrTy = lookupTy("sockaddr");
    std::optional<QualType> StructSockaddrPtrTy =
        getPointerTy(StructSockaddrTy);
    std::optional<QualType> ConstStructSockaddrPtrTy =
        getPointerTy(getConstTy(StructSockaddrTy));
    std::optional<QualType> StructSockaddrPtrRestrictTy =
        getRestrictTy(StructSockaddrPtrTy);
    std::optional<QualType> ConstStructSockaddrPtrRestrictTy =
        getRestrictTy(ConstStructSockaddrPtrTy);
    std::optional<QualType> Socklen_tTy = lookupTy("socklen_t");
    std::optional<QualType> Socklen_tPtrTy = getPointerTy(Socklen_tTy);
    std::optional<QualType> Socklen_tPtrRestrictTy =
        getRestrictTy(Socklen_tPtrTy);
    std::optional<RangeInt> Socklen_tMax = getMaxValue(Socklen_tTy);

    // In 'socket.h' of some libc implementations with C99, sockaddr parameter
    // is a transparent union of the underlying sockaddr_ family of pointers
    // instead of being a pointer to struct sockaddr. In these cases, the
    // standardized signature will not match, thus we try to match with another
    // signature that has the joker Irrelevant type. We also remove those
    // constraints which require pointer types for the sockaddr param.

    // int socket(int domain, int type, int protocol);
    addToFunctionSummaryMap(
        "socket", Signature(ArgTypes{IntTy, IntTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
                  GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg));

    auto Accept =
        Summary(NoEvalCall)
            .Case(ReturnsValidFileDescriptor, ErrnoMustNotBeChecked,
                  GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)));
    if (!addToFunctionSummaryMap(
            "accept",
            // int accept(int socket, struct sockaddr *restrict address,
            //            socklen_t *restrict address_len);
            Signature(ArgTypes{IntTy, StructSockaddrPtrRestrictTy,
                               Socklen_tPtrRestrictTy},
                      RetType{IntTy}),
            Accept))
      addToFunctionSummaryMap(
          "accept",
          Signature(ArgTypes{IntTy, Irrelevant, Socklen_tPtrRestrictTy},
                    RetType{IntTy}),
          Accept);

    // int bind(int socket, const struct sockaddr *address, socklen_t
    //          address_len);
    if (!addToFunctionSummaryMap(
            "bind",
            Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy},
                      RetType{IntTy}),
            Summary(NoEvalCall)
                .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
                .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
                .ArgConstraint(
                    ArgumentCondition(0, WithinRange, Range(0, IntMax)))
                .ArgConstraint(NotNull(ArgNo(1)))
                .ArgConstraint(
                    BufferSize(/*Buffer=*/ArgNo(1), /*BufSize=*/ArgNo(2)))
                .ArgConstraint(
                    ArgumentCondition(2, WithinRange, Range(0, Socklen_tMax)))))
      // Do not add constraints on sockaddr.
      addToFunctionSummaryMap(
          "bind",
          Signature(ArgTypes{IntTy, Irrelevant, Socklen_tTy}, RetType{IntTy}),
          Summary(NoEvalCall)
              .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
              .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
              .ArgConstraint(
                  ArgumentCondition(0, WithinRange, Range(0, IntMax)))
              .ArgConstraint(
                  ArgumentCondition(2, WithinRange, Range(0, Socklen_tMax))));

    // int getpeername(int socket, struct sockaddr *restrict address,
    //                 socklen_t *restrict address_len);
    if (!addToFunctionSummaryMap(
            "getpeername",
            Signature(ArgTypes{IntTy, StructSockaddrPtrRestrictTy,
                               Socklen_tPtrRestrictTy},
                      RetType{IntTy}),
            Summary(NoEvalCall)
                .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
                .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
                .ArgConstraint(
                    ArgumentCondition(0, WithinRange, Range(0, IntMax)))
                .ArgConstraint(NotNull(ArgNo(1)))
                .ArgConstraint(NotNull(ArgNo(2)))))
      addToFunctionSummaryMap(
          "getpeername",
          Signature(ArgTypes{IntTy, Irrelevant, Socklen_tPtrRestrictTy},
                    RetType{IntTy}),
          Summary(NoEvalCall)
              .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
              .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
              .ArgConstraint(
                  ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int getsockname(int socket, struct sockaddr *restrict address,
    //                 socklen_t *restrict address_len);
    if (!addToFunctionSummaryMap(
            "getsockname",
            Signature(ArgTypes{IntTy, StructSockaddrPtrRestrictTy,
                               Socklen_tPtrRestrictTy},
                      RetType{IntTy}),
            Summary(NoEvalCall)
                .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
                .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
                .ArgConstraint(
                    ArgumentCondition(0, WithinRange, Range(0, IntMax)))
                .ArgConstraint(NotNull(ArgNo(1)))
                .ArgConstraint(NotNull(ArgNo(2)))))
      addToFunctionSummaryMap(
          "getsockname",
          Signature(ArgTypes{IntTy, Irrelevant, Socklen_tPtrRestrictTy},
                    RetType{IntTy}),
          Summary(NoEvalCall)
              .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
              .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
              .ArgConstraint(
                  ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int connect(int socket, const struct sockaddr *address, socklen_t
    //             address_len);
    if (!addToFunctionSummaryMap(
            "connect",
            Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy},
                      RetType{IntTy}),
            Summary(NoEvalCall)
                .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
                .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
                .ArgConstraint(
                    ArgumentCondition(0, WithinRange, Range(0, IntMax)))
                .ArgConstraint(NotNull(ArgNo(1)))))
      addToFunctionSummaryMap(
          "connect",
          Signature(ArgTypes{IntTy, Irrelevant, Socklen_tTy}, RetType{IntTy}),
          Summary(NoEvalCall)
              .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
              .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
              .ArgConstraint(
                  ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    auto Recvfrom =
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
                   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
                   ArgumentCondition(2, WithinRange, SingleValue(0))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
            .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
                                      /*BufSize=*/ArgNo(2)));
    if (!addToFunctionSummaryMap(
            "recvfrom",
            // ssize_t recvfrom(int socket, void *restrict buffer,
            //                  size_t length,
            //                  int flags, struct sockaddr *restrict address,
            //                  socklen_t *restrict address_len);
            Signature(ArgTypes{IntTy, VoidPtrRestrictTy, SizeTy, IntTy,
                               StructSockaddrPtrRestrictTy,
                               Socklen_tPtrRestrictTy},
                      RetType{Ssize_tTy}),
            Recvfrom))
      addToFunctionSummaryMap(
          "recvfrom",
          Signature(ArgTypes{IntTy, VoidPtrRestrictTy, SizeTy, IntTy,
                             Irrelevant, Socklen_tPtrRestrictTy},
                    RetType{Ssize_tTy}),
          Recvfrom);

    auto Sendto =
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
                   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
                   ArgumentCondition(2, WithinRange, SingleValue(0))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
            .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
                                      /*BufSize=*/ArgNo(2)));
    if (!addToFunctionSummaryMap(
            "sendto",
            // ssize_t sendto(int socket, const void *message, size_t length,
            //                int flags, const struct sockaddr *dest_addr,
            //                socklen_t dest_len);
            Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy,
                               ConstStructSockaddrPtrTy, Socklen_tTy},
                      RetType{Ssize_tTy}),
            Sendto))
      addToFunctionSummaryMap(
          "sendto",
          Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy, Irrelevant,
                             Socklen_tTy},
                    RetType{Ssize_tTy}),
          Sendto);

    // int listen(int sockfd, int backlog);
    addToFunctionSummaryMap(
        "listen", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    addToFunctionSummaryMap(
        "recv",
        Signature(ArgTypes{IntTy, VoidPtrTy, SizeTy, IntTy},
                  RetType{Ssize_tTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
                   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
                   ArgumentCondition(2, WithinRange, SingleValue(0))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
            .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
                                      /*BufSize=*/ArgNo(2))));

    std::optional<QualType> StructMsghdrTy = lookupTy("msghdr");
    std::optional<QualType> StructMsghdrPtrTy = getPointerTy(StructMsghdrTy);
    std::optional<QualType> ConstStructMsghdrPtrTy =
        getPointerTy(getConstTy(StructMsghdrTy));

    // ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
    addToFunctionSummaryMap(
        "recvmsg",
        Signature(ArgTypes{IntTy, StructMsghdrPtrTy, IntTy},
                  RetType{Ssize_tTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
    addToFunctionSummaryMap(
        "sendmsg",
        Signature(ArgTypes{IntTy, ConstStructMsghdrPtrTy, IntTy},
                  RetType{Ssize_tTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int setsockopt(int socket, int level, int option_name,
    //                const void *option_value, socklen_t option_len);
    addToFunctionSummaryMap(
        "setsockopt",
        Signature(ArgTypes{IntTy, IntTy, IntTy, ConstVoidPtrTy, Socklen_tTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(3)))
            .ArgConstraint(
                BufferSize(/*Buffer=*/ArgNo(3), /*BufSize=*/ArgNo(4)))
            .ArgConstraint(
                ArgumentCondition(4, WithinRange, Range(0, Socklen_tMax))));

    // int getsockopt(int socket, int level, int option_name,
    //                void *restrict option_value,
    //                socklen_t *restrict option_len);
    addToFunctionSummaryMap(
        "getsockopt",
        Signature(ArgTypes{IntTy, IntTy, IntTy, VoidPtrRestrictTy,
                           Socklen_tPtrRestrictTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(3)))
            .ArgConstraint(NotNull(ArgNo(4))));

    // ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    addToFunctionSummaryMap(
        "send",
        Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy},
                  RetType{Ssize_tTy}),
        Summary(NoEvalCall)
            .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
                   ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case({ReturnValueCondition(WithinRange, SingleValue(0)),
                   ArgumentCondition(2, WithinRange, SingleValue(0))},
                  ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
            .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
                                      /*BufSize=*/ArgNo(2))));

    // int socketpair(int domain, int type, int protocol, int sv[2]);
    addToFunctionSummaryMap(
        "socketpair",
        Signature(ArgTypes{IntTy, IntTy, IntTy, IntPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(3))));

    // int shutdown(int socket, int how);
    addToFunctionSummaryMap(
        "shutdown", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
    //                 char *restrict node, socklen_t nodelen,
    //                 char *restrict service,
    //                 socklen_t servicelen, int flags);
    //
    // This is defined in netdb.h. And contrary to 'socket.h', the sockaddr
    // parameter is never handled as a transparent union in netdb.h
    addToFunctionSummaryMap(
        "getnameinfo",
        Signature(ArgTypes{ConstStructSockaddrPtrRestrictTy, Socklen_tTy,
                           CharPtrRestrictTy, Socklen_tTy, CharPtrRestrictTy,
                           Socklen_tTy, IntTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .ArgConstraint(
                BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1)))
            .ArgConstraint(
                ArgumentCondition(1, WithinRange, Range(0, Socklen_tMax)))
            .ArgConstraint(
                BufferSize(/*Buffer=*/ArgNo(2), /*BufSize=*/ArgNo(3)))
            .ArgConstraint(
                ArgumentCondition(3, WithinRange, Range(0, Socklen_tMax)))
            .ArgConstraint(
                BufferSize(/*Buffer=*/ArgNo(4), /*BufSize=*/ArgNo(5)))
            .ArgConstraint(
                ArgumentCondition(5, WithinRange, Range(0, Socklen_tMax))));

    std::optional<QualType> StructUtimbufTy = lookupTy("utimbuf");
    std::optional<QualType> StructUtimbufPtrTy = getPointerTy(StructUtimbufTy);

    // int utime(const char *filename, struct utimbuf *buf);
    addToFunctionSummaryMap(
        "utime",
        Signature(ArgTypes{ConstCharPtrTy, StructUtimbufPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    std::optional<QualType> StructTimespecTy = lookupTy("timespec");
    std::optional<QualType> StructTimespecPtrTy =
        getPointerTy(StructTimespecTy);
    std::optional<QualType> ConstStructTimespecPtrTy =
        getPointerTy(getConstTy(StructTimespecTy));

    // int futimens(int fd, const struct timespec times[2]);
    addToFunctionSummaryMap(
        "futimens",
        Signature(ArgTypes{IntTy, ConstStructTimespecPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(
                ArgumentCondition(0, WithinRange, Range(0, IntMax))));

    // int utimensat(int dirfd, const char *pathname,
    //               const struct timespec times[2], int flags);
    addToFunctionSummaryMap(
        "utimensat",
        Signature(
            ArgTypes{IntTy, ConstCharPtrTy, ConstStructTimespecPtrTy, IntTy},
            RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(1))));

    std::optional<QualType> StructTimevalTy = lookupTy("timeval");
    std::optional<QualType> ConstStructTimevalPtrTy =
        getPointerTy(getConstTy(StructTimevalTy));

    // int utimes(const char *filename, const struct timeval times[2]);
    addToFunctionSummaryMap(
        "utimes",
        Signature(ArgTypes{ConstCharPtrTy, ConstStructTimevalPtrTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    // int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
    addToFunctionSummaryMap(
        "nanosleep",
        Signature(ArgTypes{ConstStructTimespecPtrTy, StructTimespecPtrTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(0))));

    std::optional<QualType> Time_tTy = lookupTy("time_t");
    std::optional<QualType> ConstTime_tPtrTy =
        getPointerTy(getConstTy(Time_tTy));
    std::optional<QualType> ConstTime_tPtrRestrictTy =
        getRestrictTy(ConstTime_tPtrTy);

    std::optional<QualType> StructTmTy = lookupTy("tm");
    std::optional<QualType> StructTmPtrTy = getPointerTy(StructTmTy);
    std::optional<QualType> StructTmPtrRestrictTy =
        getRestrictTy(StructTmPtrTy);
    std::optional<QualType> ConstStructTmPtrTy =
        getPointerTy(getConstTy(StructTmTy));
    std::optional<QualType> ConstStructTmPtrRestrictTy =
        getRestrictTy(ConstStructTmPtrTy);

    // struct tm * localtime(const time_t *tp);
    addToFunctionSummaryMap(
        "localtime",
        Signature(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // struct tm *localtime_r(const time_t *restrict timer,
    //                        struct tm *restrict result);
    addToFunctionSummaryMap(
        "localtime_r",
        Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
                  RetType{StructTmPtrTy}),
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // char *asctime_r(const struct tm *restrict tm, char *restrict buf);
    addToFunctionSummaryMap(
        "asctime_r",
        Signature(ArgTypes{ConstStructTmPtrRestrictTy, CharPtrRestrictTy},
                  RetType{CharPtrTy}),
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1)))
            .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
                                      /*MinBufSize=*/BVF.getValue(26, IntTy))));

    // char *ctime_r(const time_t *timep, char *buf);
    addToFunctionSummaryMap(
        "ctime_r",
        Signature(ArgTypes{ConstTime_tPtrTy, CharPtrTy}, RetType{CharPtrTy}),
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1)))
            .ArgConstraint(BufferSize(
                /*Buffer=*/ArgNo(1),
                /*MinBufSize=*/BVF.getValue(26, IntTy))));

    // struct tm *gmtime_r(const time_t *restrict timer,
    //                     struct tm *restrict result);
    addToFunctionSummaryMap(
        "gmtime_r",
        Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
                  RetType{StructTmPtrTy}),
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // struct tm * gmtime(const time_t *tp);
    addToFunctionSummaryMap(
        "gmtime", Signature(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    std::optional<QualType> Clockid_tTy = lookupTy("clockid_t");

    // int clock_gettime(clockid_t clock_id, struct timespec *tp);
    addToFunctionSummaryMap(
        "clock_gettime",
        Signature(ArgTypes{Clockid_tTy, StructTimespecPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(1))));

    std::optional<QualType> StructItimervalTy = lookupTy("itimerval");
    std::optional<QualType> StructItimervalPtrTy =
        getPointerTy(StructItimervalTy);

    // int getitimer(int which, struct itimerval *curr_value);
    addToFunctionSummaryMap(
        "getitimer",
        Signature(ArgTypes{IntTy, StructItimervalPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
            .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
            .ArgConstraint(NotNull(ArgNo(1))));

    std::optional<QualType> Pthread_cond_tTy = lookupTy("pthread_cond_t");
    std::optional<QualType> Pthread_cond_tPtrTy =
        getPointerTy(Pthread_cond_tTy);
    std::optional<QualType> Pthread_tTy = lookupTy("pthread_t");
    std::optional<QualType> Pthread_tPtrTy = getPointerTy(Pthread_tTy);
    std::optional<QualType> Pthread_tPtrRestrictTy =
        getRestrictTy(Pthread_tPtrTy);
    std::optional<QualType> Pthread_mutex_tTy = lookupTy("pthread_mutex_t");
    std::optional<QualType> Pthread_mutex_tPtrTy =
        getPointerTy(Pthread_mutex_tTy);
    std::optional<QualType> Pthread_mutex_tPtrRestrictTy =
        getRestrictTy(Pthread_mutex_tPtrTy);
    std::optional<QualType> Pthread_attr_tTy = lookupTy("pthread_attr_t");
    std::optional<QualType> Pthread_attr_tPtrTy =
        getPointerTy(Pthread_attr_tTy);
    std::optional<QualType> ConstPthread_attr_tPtrTy =
        getPointerTy(getConstTy(Pthread_attr_tTy));
    std::optional<QualType> ConstPthread_attr_tPtrRestrictTy =
        getRestrictTy(ConstPthread_attr_tPtrTy);
    std::optional<QualType> Pthread_mutexattr_tTy =
        lookupTy("pthread_mutexattr_t");
    std::optional<QualType> ConstPthread_mutexattr_tPtrTy =
        getPointerTy(getConstTy(Pthread_mutexattr_tTy));
    std::optional<QualType> ConstPthread_mutexattr_tPtrRestrictTy =
        getRestrictTy(ConstPthread_mutexattr_tPtrTy);

    QualType PthreadStartRoutineTy = getPointerTy(
        ACtx.getFunctionType(/*ResultTy=*/VoidPtrTy, /*Args=*/VoidPtrTy,
                             FunctionProtoType::ExtProtoInfo()));

    // int pthread_cond_signal(pthread_cond_t *cond);
    // int pthread_cond_broadcast(pthread_cond_t *cond);
    addToFunctionSummaryMap(
        {"pthread_cond_signal", "pthread_cond_broadcast"},
        Signature(ArgTypes{Pthread_cond_tPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // int pthread_create(pthread_t *restrict thread,
    //                    const pthread_attr_t *restrict attr,
    //                    void *(*start_routine)(void*), void *restrict arg);
    addToFunctionSummaryMap(
        "pthread_create",
        Signature(ArgTypes{Pthread_tPtrRestrictTy,
                           ConstPthread_attr_tPtrRestrictTy,
                           PthreadStartRoutineTy, VoidPtrRestrictTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(2))));

    // int pthread_attr_destroy(pthread_attr_t *attr);
    // int pthread_attr_init(pthread_attr_t *attr);
    addToFunctionSummaryMap(
        {"pthread_attr_destroy", "pthread_attr_init"},
        Signature(ArgTypes{Pthread_attr_tPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // int pthread_attr_getstacksize(const pthread_attr_t *restrict attr,
    //                               size_t *restrict stacksize);
    // int pthread_attr_getguardsize(const pthread_attr_t *restrict attr,
    //                               size_t *restrict guardsize);
    addToFunctionSummaryMap(
        {"pthread_attr_getstacksize", "pthread_attr_getguardsize"},
        Signature(ArgTypes{ConstPthread_attr_tPtrRestrictTy, SizePtrRestrictTy},
                  RetType{IntTy}),
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));

    // int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
    // int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
    addToFunctionSummaryMap(
        {"pthread_attr_setstacksize", "pthread_attr_setguardsize"},
        Signature(ArgTypes{Pthread_attr_tPtrTy, SizeTy}, RetType{IntTy}),
        Summary(NoEvalCall)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(
                ArgumentCondition(1, WithinRange, Range(0, SizeMax))));

    // int pthread_mutex_init(pthread_mutex_t *restrict mutex, const
    //                        pthread_mutexattr_t *restrict attr);
    addToFunctionSummaryMap(
        "pthread_mutex_init",
        Signature(ArgTypes{Pthread_mutex_tPtrRestrictTy,
                           ConstPthread_mutexattr_tPtrRestrictTy},
                  RetType{IntTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

    // int pthread_mutex_destroy(pthread_mutex_t *mutex);
    // int pthread_mutex_lock(pthread_mutex_t *mutex);
    // int pthread_mutex_trylock(pthread_mutex_t *mutex);
    // int pthread_mutex_unlock(pthread_mutex_t *mutex);
    addToFunctionSummaryMap(
        {"pthread_mutex_destroy", "pthread_mutex_lock", "pthread_mutex_trylock",
         "pthread_mutex_unlock"},
        Signature(ArgTypes{Pthread_mutex_tPtrTy}, RetType{IntTy}),
        Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
  }

  // Functions for testing.
  if (AddTestFunctions) {
    const RangeInt IntMin = BVF.getMinValue(IntTy).getLimitedValue();

    addToFunctionSummaryMap(
        "__not_null", Signature(ArgTypes{IntPtrTy}, RetType{IntTy}),
        Summary(EvalCallAsPure).ArgConstraint(NotNull(ArgNo(0))));

    addToFunctionSummaryMap(
        "__not_null_buffer",
        Signature(ArgTypes{VoidPtrTy, IntTy, IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(NotNullBuffer(ArgNo(0), ArgNo(1), ArgNo(2))));

    // Test inside range constraints.
    addToFunctionSummaryMap(
        "__single_val_0", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, WithinRange, SingleValue(0))));
    addToFunctionSummaryMap(
        "__single_val_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, WithinRange, SingleValue(1))));
    addToFunctionSummaryMap(
        "__range_1_2", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, WithinRange, Range(1, 2))));
    addToFunctionSummaryMap(
        "__range_m1_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, WithinRange, Range(-1, 1))));
    addToFunctionSummaryMap(
        "__range_m2_m1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, WithinRange, Range(-2, -1))));
    addToFunctionSummaryMap(
        "__range_m10_10", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, WithinRange, Range(-10, 10))));
    addToFunctionSummaryMap("__range_m1_inf",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, WithinRange, Range(-1, IntMax))));
    addToFunctionSummaryMap("__range_0_inf",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, WithinRange, Range(0, IntMax))));
    addToFunctionSummaryMap("__range_1_inf",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, WithinRange, Range(1, IntMax))));
    addToFunctionSummaryMap("__range_minf_m1",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, WithinRange, Range(IntMin, -1))));
    addToFunctionSummaryMap("__range_minf_0",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, WithinRange, Range(IntMin, 0))));
    addToFunctionSummaryMap("__range_minf_1",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, WithinRange, Range(IntMin, 1))));
    addToFunctionSummaryMap("__range_1_2__4_6",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, WithinRange, Range({1, 2}, {4, 6}))));
    addToFunctionSummaryMap(
        "__range_1_2__4_inf", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, WithinRange,
                                             Range({1, 2}, {4, IntMax}))));

    // Test out of range constraints.
    addToFunctionSummaryMap(
        "__single_val_out_0", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, OutOfRange, SingleValue(0))));
    addToFunctionSummaryMap(
        "__single_val_out_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, OutOfRange, SingleValue(1))));
    addToFunctionSummaryMap(
        "__range_out_1_2", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, OutOfRange, Range(1, 2))));
    addToFunctionSummaryMap(
        "__range_out_m1_1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, OutOfRange, Range(-1, 1))));
    addToFunctionSummaryMap(
        "__range_out_m2_m1", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, OutOfRange, Range(-2, -1))));
    addToFunctionSummaryMap(
        "__range_out_m10_10", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, OutOfRange, Range(-10, 10))));
    addToFunctionSummaryMap("__range_out_m1_inf",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, OutOfRange, Range(-1, IntMax))));
    addToFunctionSummaryMap("__range_out_0_inf",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, OutOfRange, Range(0, IntMax))));
    addToFunctionSummaryMap("__range_out_1_inf",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, OutOfRange, Range(1, IntMax))));
    addToFunctionSummaryMap("__range_out_minf_m1",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, OutOfRange, Range(IntMin, -1))));
    addToFunctionSummaryMap("__range_out_minf_0",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, OutOfRange, Range(IntMin, 0))));
    addToFunctionSummaryMap("__range_out_minf_1",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, OutOfRange, Range(IntMin, 1))));
    addToFunctionSummaryMap("__range_out_1_2__4_6",
                            Signature(ArgTypes{IntTy}, RetType{IntTy}),
                            Summary(EvalCallAsPure)
                                .ArgConstraint(ArgumentCondition(
                                    0U, OutOfRange, Range({1, 2}, {4, 6}))));
    addToFunctionSummaryMap(
        "__range_out_1_2__4_inf", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(
                ArgumentCondition(0U, OutOfRange, Range({1, 2}, {4, IntMax}))));

    // Test range kind.
    addToFunctionSummaryMap(
        "__within", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, WithinRange, SingleValue(1))));
    addToFunctionSummaryMap(
        "__out_of", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, OutOfRange, SingleValue(1))));

    addToFunctionSummaryMap(
        "__two_constrained_args",
        Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, WithinRange, SingleValue(1)))
            .ArgConstraint(ArgumentCondition(1U, WithinRange, SingleValue(1))));
    addToFunctionSummaryMap(
        "__arg_constrained_twice", Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(ArgumentCondition(0U, OutOfRange, SingleValue(1)))
            .ArgConstraint(ArgumentCondition(0U, OutOfRange, SingleValue(2))));
    addToFunctionSummaryMap(
        "__defaultparam",
        Signature(ArgTypes{Irrelevant, IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure).ArgConstraint(NotNull(ArgNo(0))));
    addToFunctionSummaryMap(
        "__variadic",
        Signature(ArgTypes{VoidPtrTy, ConstCharPtrTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(NotNull(ArgNo(0)))
            .ArgConstraint(NotNull(ArgNo(1))));
    addToFunctionSummaryMap(
        "__buf_size_arg_constraint",
        Signature(ArgTypes{ConstVoidPtrTy, SizeTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(
                BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1))));
    addToFunctionSummaryMap(
        "__buf_size_arg_constraint_mul",
        Signature(ArgTypes{ConstVoidPtrTy, SizeTy, SizeTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1),
                                      /*BufSizeMultiplier=*/ArgNo(2))));
    addToFunctionSummaryMap(
        "__buf_size_arg_constraint_concrete",
        Signature(ArgTypes{ConstVoidPtrTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(0),
                                      /*BufSize=*/BVF.getValue(10, IntTy))));
    addToFunctionSummaryMap(
        {"__test_restrict_param_0", "__test_restrict_param_1",
         "__test_restrict_param_2"},
        Signature(ArgTypes{VoidPtrRestrictTy}, RetType{VoidTy}),
        Summary(EvalCallAsPure));

    // Test the application of cases.
    addToFunctionSummaryMap(
        "__test_case_note", Signature(ArgTypes{}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .Case({ReturnValueCondition(WithinRange, SingleValue(0))},
                  ErrnoIrrelevant, "Function returns 0")
            .Case({ReturnValueCondition(WithinRange, SingleValue(1))},
                  ErrnoIrrelevant, "Function returns 1"));
    addToFunctionSummaryMap(
        "__test_case_range_1_2__4_6",
        Signature(ArgTypes{IntTy}, RetType{IntTy}),
        Summary(EvalCallAsPure)
            .Case({ArgumentCondition(0U, WithinRange,
                                     IntRangeVector{{IntMin, 0}, {3, 3}}),
                   ReturnValueCondition(WithinRange, SingleValue(1))},
                  ErrnoIrrelevant)
            .Case({ArgumentCondition(0U, WithinRange,
                                     IntRangeVector{{3, 3}, {7, IntMax}}),
                   ReturnValueCondition(WithinRange, SingleValue(2))},
                  ErrnoIrrelevant)
            .Case({ArgumentCondition(0U, WithinRange,
                                     IntRangeVector{{IntMin, 0}, {7, IntMax}}),
                   ReturnValueCondition(WithinRange, SingleValue(3))},
                  ErrnoIrrelevant)
            .Case({ArgumentCondition(
                       0U, WithinRange,
                       IntRangeVector{{IntMin, 0}, {3, 3}, {7, IntMax}}),
                   ReturnValueCondition(WithinRange, SingleValue(4))},
                  ErrnoIrrelevant));
  }
}

void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) {
  auto *Checker = mgr.registerChecker<StdLibraryFunctionsChecker>();
  Checker->CheckName = mgr.getCurrentCheckerName();
  const AnalyzerOptions &Opts = mgr.getAnalyzerOptions();
  Checker->DisplayLoadedSummaries =
      Opts.getCheckerBooleanOption(Checker, "DisplayLoadedSummaries");
  Checker->ModelPOSIX = Opts.getCheckerBooleanOption(Checker, "ModelPOSIX");
  Checker->ShouldAssumeControlledEnvironment =
      Opts.ShouldAssumeControlledEnvironment;
}

bool ento::shouldRegisterStdCLibraryFunctionsChecker(
    const CheckerManager &mgr) {
  return true;
}

void ento::registerStdCLibraryFunctionsTesterChecker(CheckerManager &mgr) {
  auto *Checker = mgr.getChecker<StdLibraryFunctionsChecker>();
  Checker->AddTestFunctions = true;
}

bool ento::shouldRegisterStdCLibraryFunctionsTesterChecker(
    const CheckerManager &mgr) {
  return true;
}
