[clang] db4d5f7 - [analyzer][StdLibraryFunctionsChecker] Add POSIX file handling functions

Gabor Marton via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 2 05:28:46 PDT 2020


Author: Gabor Marton
Date: 2020-07-02T14:28:05+02:00
New Revision: db4d5f7048a26a7708821e46095742aecfd8ba46

URL: https://github.com/llvm/llvm-project/commit/db4d5f7048a26a7708821e46095742aecfd8ba46
DIFF: https://github.com/llvm/llvm-project/commit/db4d5f7048a26a7708821e46095742aecfd8ba46.diff

LOG: [analyzer][StdLibraryFunctionsChecker] Add POSIX file handling functions

Adding file handling functions from the POSIX standard (2017).
A new checker option is introduced to enable them.
In follow-up patches I am going to upstream networking, pthread, and other
groups of POSIX functions.

Differential Revision: https://reviews.llvm.org/D82288

Added: 
    clang/test/Analysis/std-c-library-functions-POSIX.c

Modified: 
    clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
    clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
    clang/test/Analysis/analyzer-config.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 8430dc123598..0ceedfb8771b 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -354,7 +354,14 @@ def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
                   "If set to true, the checker displays the found summaries "
                   "for the given translation unit.",
                   "false",
-                  Released>
+                  Released,
+                  Hide>,
+    CmdLineOption<Boolean,
+                  "ModelPOSIX",
+                  "If set to true, the checker models functions from the "
+                  "POSIX standard.",
+                  "false",
+                  InAlpha>
   ]>,
   Documentation<NotDocumented>;
 

diff  --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 6feae56502f1..29393c2ca02b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -461,6 +461,7 @@ class StdLibraryFunctionsChecker
   CheckerNameRef CheckNames[CK_NumCheckKinds];
 
   bool DisplayLoadedSummaries = false;
+  bool ModelPOSIX = false;
 
 private:
   Optional<Summary> findFunctionSummary(const FunctionDecl *FD,
@@ -736,13 +737,18 @@ llvm::Optional<QualType> lookupType(StringRef Name, const ASTContext &ACtx) {
   //   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) {
+  for (Decl *D : LookupRes)
     if (auto *TD = dyn_cast<TypedefNameDecl>(D))
       return ACtx.getTypeDeclType(TD).getCanonicalType();
-  }
-  assert(LookupRes.size() == 1 && "Type identifier should be unique");
-  auto *D = cast<TypeDecl>(LookupRes.front());
-  return ACtx.getTypeDeclType(D).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 None;
 }
 
 void StdLibraryFunctionsChecker::initFunctionSummaries(
@@ -761,26 +767,46 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
   // 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 IntTy = ACtx.IntTy;
+  const QualType UnsignedIntTy = ACtx.UnsignedIntTy;
   const QualType LongTy = ACtx.LongTy;
   const QualType LongLongTy = ACtx.LongLongTy;
   const QualType SizeTy = ACtx.getSizeType();
+
   const QualType VoidPtrTy = ACtx.VoidPtrTy; // void *
+  const QualType IntPtrTy = ACtx.getPointerType(IntTy); // int *
+  const QualType UnsignedIntPtrTy =
+      ACtx.getPointerType(UnsignedIntTy); // unsigned int *
   const QualType VoidPtrRestrictTy =
       ACtx.getLangOpts().C99 ? ACtx.getRestrictType(VoidPtrTy) // void *restrict
                              : VoidPtrTy;
   const QualType ConstVoidPtrTy =
       ACtx.getPointerType(ACtx.VoidTy.withConst()); // const void *
+  const QualType CharPtrTy = ACtx.getPointerType(ACtx.CharTy); // char *
+  const QualType CharPtrRestrictTy =
+      ACtx.getLangOpts().C99 ? ACtx.getRestrictType(CharPtrTy) // char *restrict
+                             : CharPtrTy;
   const QualType ConstCharPtrTy =
       ACtx.getPointerType(ACtx.CharTy.withConst()); // const char *
+  const QualType ConstCharPtrRestrictTy =
+      ACtx.getLangOpts().C99
+          ? ACtx.getRestrictType(ConstCharPtrTy) // const char *restrict
+          : ConstCharPtrTy;
+  const QualType Wchar_tPtrTy = ACtx.getPointerType(ACtx.WCharTy); // wchar_t *
+  const QualType ConstWchar_tPtrTy =
+      ACtx.getPointerType(ACtx.WCharTy.withConst()); // const wchar_t *
   const QualType ConstVoidPtrRestrictTy =
       ACtx.getLangOpts().C99
           ? ACtx.getRestrictType(ConstVoidPtrTy) // const void *restrict
           : ConstVoidPtrTy;
 
   const RangeInt IntMax = BVF.getMaxValue(IntTy).getLimitedValue();
+  const RangeInt UnsignedIntMax =
+      BVF.getMaxValue(UnsignedIntTy).getLimitedValue();
   const RangeInt LongMax = BVF.getMaxValue(LongTy).getLimitedValue();
   const RangeInt LongLongMax = BVF.getMaxValue(LongLongTy).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
@@ -1110,6 +1136,573 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
                           {Getline(IntTy, IntMax), Getline(LongTy, LongMax),
                            Getline(LongLongTy, LongLongMax)});
 
+  if (ModelPOSIX) {
+
+    // long a64l(const char *str64);
+    addToFunctionSummaryMap(
+        "a64l", Summary(ArgTypes{ConstCharPtrTy}, RetType{LongTy}, NoEvalCall)
+                    .ArgConstraint(NotNull(ArgNo(0))));
+
+    // char *l64a(long value);
+    addToFunctionSummaryMap(
+        "l64a", Summary(ArgTypes{LongTy}, RetType{CharPtrTy}, NoEvalCall)
+                    .ArgConstraint(
+                        ArgumentCondition(0, WithinRange, Range(0, LongMax))));
+
+    // int access(const char *pathname, int amode);
+    addToFunctionSummaryMap("access", Summary(ArgTypes{ConstCharPtrTy, IntTy},
+                                              RetType{IntTy}, NoEvalCall)
+                                          .ArgConstraint(NotNull(ArgNo(0))));
+
+    // int faccessat(int dirfd, const char *pathname, int mode, int flags);
+    addToFunctionSummaryMap(
+        "faccessat", Summary(ArgTypes{IntTy, ConstCharPtrTy, IntTy, IntTy},
+                             RetType{IntTy}, NoEvalCall)
+                         .ArgConstraint(NotNull(ArgNo(1))));
+
+    // int dup(int fildes);
+    addToFunctionSummaryMap(
+        "dup", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall)
+                   .ArgConstraint(
+                       ArgumentCondition(0, WithinRange, Range(0, IntMax))));
+
+    // int dup2(int fildes1, int filedes2);
+    addToFunctionSummaryMap(
+        "dup2",
+        Summary(ArgTypes{IntTy, IntTy}, RetType{IntTy}, NoEvalCall)
+            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
+            .ArgConstraint(
+                ArgumentCondition(1, WithinRange, Range(0, IntMax))));
+
+    // int fdatasync(int fildes);
+    addToFunctionSummaryMap(
+        "fdatasync", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall)
+                         .ArgConstraint(ArgumentCondition(0, WithinRange,
+                                                          Range(0, IntMax))));
+
+    // int fnmatch(const char *pattern, const char *string, int flags);
+    addToFunctionSummaryMap(
+        "fnmatch", Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy, IntTy},
+                           RetType{IntTy}, EvalCallAsPure)
+                       .ArgConstraint(NotNull(ArgNo(0)))
+                       .ArgConstraint(NotNull(ArgNo(1))));
+
+    // int fsync(int fildes);
+    addToFunctionSummaryMap(
+        "fsync", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall)
+                     .ArgConstraint(
+                         ArgumentCondition(0, WithinRange, Range(0, IntMax))));
+
+    Optional<QualType> Off_tTy = lookupType("off_t", ACtx);
+
+    if (Off_tTy)
+      // int truncate(const char *path, off_t length);
+      addToFunctionSummaryMap("truncate",
+                              Summary(ArgTypes{ConstCharPtrTy, *Off_tTy},
+                                      RetType{IntTy}, NoEvalCall)
+                                  .ArgConstraint(NotNull(ArgNo(0))));
+
+    // int symlink(const char *oldpath, const char *newpath);
+    addToFunctionSummaryMap("symlink",
+                            Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy},
+                                    RetType{IntTy}, NoEvalCall)
+                                .ArgConstraint(NotNull(ArgNo(0)))
+                                .ArgConstraint(NotNull(ArgNo(1))));
+
+    // int symlinkat(const char *oldpath, int newdirfd, const char *newpath);
+    addToFunctionSummaryMap(
+        "symlinkat",
+        Summary(ArgTypes{ConstCharPtrTy, IntTy, ConstCharPtrTy}, RetType{IntTy},
+                NoEvalCall)
+            .ArgConstraint(NotNull(ArgNo(0)))
+            .ArgConstraint(ArgumentCondition(1, WithinRange, Range(0, IntMax)))
+            .ArgConstraint(NotNull(ArgNo(2))));
+
+    if (Off_tTy)
+      // int lockf(int fd, int cmd, off_t len);
+      addToFunctionSummaryMap(
+          "lockf",
+          Summary(ArgTypes{IntTy, IntTy, *Off_tTy}, RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(
+                  ArgumentCondition(0, WithinRange, Range(0, IntMax))));
+
+    Optional<QualType> Mode_tTy = lookupType("mode_t", ACtx);
+
+    if (Mode_tTy)
+      // int creat(const char *pathname, mode_t mode);
+      addToFunctionSummaryMap("creat",
+                              Summary(ArgTypes{ConstCharPtrTy, *Mode_tTy},
+                                      RetType{IntTy}, NoEvalCall)
+                                  .ArgConstraint(NotNull(ArgNo(0))));
+
+    // unsigned int sleep(unsigned int seconds);
+    addToFunctionSummaryMap(
+        "sleep",
+        Summary(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}, NoEvalCall)
+            .ArgConstraint(
+                ArgumentCondition(0, WithinRange, Range(0, UnsignedIntMax))));
+
+    Optional<QualType> DirTy = lookupType("DIR", ACtx);
+    Optional<QualType> DirPtrTy;
+    if (DirTy)
+      DirPtrTy = ACtx.getPointerType(*DirTy);
+
+    if (DirPtrTy)
+      // int dirfd(DIR *dirp);
+      addToFunctionSummaryMap(
+          "dirfd", Summary(ArgTypes{*DirPtrTy}, RetType{IntTy}, NoEvalCall)
+                       .ArgConstraint(NotNull(ArgNo(0))));
+
+    // unsigned int alarm(unsigned int seconds);
+    addToFunctionSummaryMap(
+        "alarm",
+        Summary(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}, NoEvalCall)
+            .ArgConstraint(
+                ArgumentCondition(0, WithinRange, Range(0, UnsignedIntMax))));
+
+    if (DirPtrTy)
+      // int closedir(DIR *dir);
+      addToFunctionSummaryMap(
+          "closedir", Summary(ArgTypes{*DirPtrTy}, RetType{IntTy}, NoEvalCall)
+                          .ArgConstraint(NotNull(ArgNo(0))));
+
+    // char *strdup(const char *s);
+    addToFunctionSummaryMap("strdup", Summary(ArgTypes{ConstCharPtrTy},
+                                              RetType{CharPtrTy}, NoEvalCall)
+                                          .ArgConstraint(NotNull(ArgNo(0))));
+
+    // char *strndup(const char *s, size_t n);
+    addToFunctionSummaryMap(
+        "strndup", Summary(ArgTypes{ConstCharPtrTy, SizeTy}, RetType{CharPtrTy},
+                           NoEvalCall)
+                       .ArgConstraint(NotNull(ArgNo(0)))
+                       .ArgConstraint(ArgumentCondition(1, WithinRange,
+                                                        Range(0, SizeMax))));
+
+    // wchar_t *wcsdup(const wchar_t *s);
+    addToFunctionSummaryMap("wcsdup", Summary(ArgTypes{ConstWchar_tPtrTy},
+                                              RetType{Wchar_tPtrTy}, NoEvalCall)
+                                          .ArgConstraint(NotNull(ArgNo(0))));
+
+    // int mkstemp(char *template);
+    addToFunctionSummaryMap(
+        "mkstemp", Summary(ArgTypes{CharPtrTy}, RetType{IntTy}, NoEvalCall)
+                       .ArgConstraint(NotNull(ArgNo(0))));
+
+    // char *mkdtemp(char *template);
+    addToFunctionSummaryMap(
+        "mkdtemp", Summary(ArgTypes{CharPtrTy}, RetType{CharPtrTy}, NoEvalCall)
+                       .ArgConstraint(NotNull(ArgNo(0))));
+
+    // char *getcwd(char *buf, size_t size);
+    addToFunctionSummaryMap(
+        "getcwd",
+        Summary(ArgTypes{CharPtrTy, SizeTy}, RetType{CharPtrTy}, NoEvalCall)
+            .ArgConstraint(
+                ArgumentCondition(1, WithinRange, Range(0, SizeMax))));
+
+    if (Mode_tTy) {
+      // int mkdir(const char *pathname, mode_t mode);
+      addToFunctionSummaryMap("mkdir",
+                              Summary(ArgTypes{ConstCharPtrTy, *Mode_tTy},
+                                      RetType{IntTy}, NoEvalCall)
+                                  .ArgConstraint(NotNull(ArgNo(0))));
+
+      // int mkdirat(int dirfd, const char *pathname, mode_t mode);
+      addToFunctionSummaryMap(
+          "mkdirat", Summary(ArgTypes{IntTy, ConstCharPtrTy, *Mode_tTy},
+                             RetType{IntTy}, NoEvalCall)
+                         .ArgConstraint(NotNull(ArgNo(1))));
+    }
+
+    Optional<QualType> Dev_tTy = lookupType("dev_t", ACtx);
+
+    if (Mode_tTy && Dev_tTy) {
+      // int mknod(const char *pathname, mode_t mode, dev_t dev);
+      addToFunctionSummaryMap(
+          "mknod", Summary(ArgTypes{ConstCharPtrTy, *Mode_tTy, *Dev_tTy},
+                           RetType{IntTy}, NoEvalCall)
+                       .ArgConstraint(NotNull(ArgNo(0))));
+
+      // int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev);
+      addToFunctionSummaryMap("mknodat", Summary(ArgTypes{IntTy, ConstCharPtrTy,
+                                                          *Mode_tTy, *Dev_tTy},
+                                                 RetType{IntTy}, NoEvalCall)
+                                             .ArgConstraint(NotNull(ArgNo(1))));
+    }
+
+    if (Mode_tTy) {
+      // int chmod(const char *path, mode_t mode);
+      addToFunctionSummaryMap("chmod",
+                              Summary(ArgTypes{ConstCharPtrTy, *Mode_tTy},
+                                      RetType{IntTy}, NoEvalCall)
+                                  .ArgConstraint(NotNull(ArgNo(0))));
+
+      // int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);
+      addToFunctionSummaryMap(
+          "fchmodat", Summary(ArgTypes{IntTy, ConstCharPtrTy, *Mode_tTy, IntTy},
+                              RetType{IntTy}, NoEvalCall)
+                          .ArgConstraint(ArgumentCondition(0, WithinRange,
+                                                           Range(0, IntMax)))
+                          .ArgConstraint(NotNull(ArgNo(1))));
+
+      // int fchmod(int fildes, mode_t mode);
+      addToFunctionSummaryMap(
+          "fchmod",
+          Summary(ArgTypes{IntTy, *Mode_tTy}, RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(
+                  ArgumentCondition(0, WithinRange, Range(0, IntMax))));
+    }
+
+    Optional<QualType> Uid_tTy = lookupType("uid_t", ACtx);
+    Optional<QualType> Gid_tTy = lookupType("gid_t", ACtx);
+
+    if (Uid_tTy && Gid_tTy) {
+      // int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group,
+      //              int flags);
+      addToFunctionSummaryMap(
+          "fchownat",
+          Summary(ArgTypes{IntTy, ConstCharPtrTy, *Uid_tTy, *Gid_tTy, IntTy},
+                  RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(
+                  ArgumentCondition(0, WithinRange, Range(0, IntMax)))
+              .ArgConstraint(NotNull(ArgNo(1))));
+
+      // int chown(const char *path, uid_t owner, gid_t group);
+      addToFunctionSummaryMap(
+          "chown", Summary(ArgTypes{ConstCharPtrTy, *Uid_tTy, *Gid_tTy},
+                           RetType{IntTy}, NoEvalCall)
+                       .ArgConstraint(NotNull(ArgNo(0))));
+
+      // int lchown(const char *path, uid_t owner, gid_t group);
+      addToFunctionSummaryMap(
+          "lchown", Summary(ArgTypes{ConstCharPtrTy, *Uid_tTy, *Gid_tTy},
+                            RetType{IntTy}, NoEvalCall)
+                        .ArgConstraint(NotNull(ArgNo(0))));
+
+      // int fchown(int fildes, uid_t owner, gid_t group);
+      addToFunctionSummaryMap(
+          "fchown", Summary(ArgTypes{IntTy, *Uid_tTy, *Gid_tTy}, RetType{IntTy},
+                            NoEvalCall)
+                        .ArgConstraint(ArgumentCondition(0, WithinRange,
+                                                         Range(0, IntMax))));
+    }
+
+    // int rmdir(const char *pathname);
+    addToFunctionSummaryMap(
+        "rmdir", Summary(ArgTypes{ConstCharPtrTy}, RetType{IntTy}, NoEvalCall)
+                     .ArgConstraint(NotNull(ArgNo(0))));
+
+    // int chdir(const char *path);
+    addToFunctionSummaryMap(
+        "chdir", Summary(ArgTypes{ConstCharPtrTy}, RetType{IntTy}, NoEvalCall)
+                     .ArgConstraint(NotNull(ArgNo(0))));
+
+    // int link(const char *oldpath, const char *newpath);
+    addToFunctionSummaryMap("link",
+                            Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy},
+                                    RetType{IntTy}, NoEvalCall)
+                                .ArgConstraint(NotNull(ArgNo(0)))
+                                .ArgConstraint(NotNull(ArgNo(1))));
+
+    // int linkat(int fd1, const char *path1, int fd2, const char *path2,
+    //            int flag);
+    addToFunctionSummaryMap(
+        "linkat",
+        Summary(ArgTypes{IntTy, ConstCharPtrTy, IntTy, ConstCharPtrTy, IntTy},
+                RetType{IntTy}, NoEvalCall)
+            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
+            .ArgConstraint(NotNull(ArgNo(1)))
+            .ArgConstraint(ArgumentCondition(2, WithinRange, Range(0, IntMax)))
+            .ArgConstraint(NotNull(ArgNo(3))));
+
+    // int unlink(const char *pathname);
+    addToFunctionSummaryMap(
+        "unlink", Summary(ArgTypes{ConstCharPtrTy}, RetType{IntTy}, NoEvalCall)
+                      .ArgConstraint(NotNull(ArgNo(0))));
+
+    // int unlinkat(int fd, const char *path, int flag);
+    addToFunctionSummaryMap(
+        "unlinkat",
+        Summary(ArgTypes{IntTy, ConstCharPtrTy, IntTy}, RetType{IntTy},
+                NoEvalCall)
+            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
+            .ArgConstraint(NotNull(ArgNo(1))));
+
+    Optional<QualType> StructStatTy = lookupType("stat", ACtx);
+    Optional<QualType> StructStatPtrTy, StructStatPtrRestrictTy;
+    if (StructStatTy) {
+      StructStatPtrTy = ACtx.getPointerType(*StructStatTy);
+      StructStatPtrRestrictTy = ACtx.getLangOpts().C99
+                                    ? ACtx.getRestrictType(*StructStatPtrTy)
+                                    : *StructStatPtrTy;
+    }
+
+    if (StructStatPtrTy)
+      // int fstat(int fd, struct stat *statbuf);
+      addToFunctionSummaryMap(
+          "fstat",
+          Summary(ArgTypes{IntTy, *StructStatPtrTy}, RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(
+                  ArgumentCondition(0, WithinRange, Range(0, IntMax)))
+              .ArgConstraint(NotNull(ArgNo(1))));
+
+    if (StructStatPtrRestrictTy) {
+      // int stat(const char *restrict path, struct stat *restrict buf);
+      addToFunctionSummaryMap(
+          "stat",
+          Summary(ArgTypes{ConstCharPtrRestrictTy, *StructStatPtrRestrictTy},
+                  RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(NotNull(ArgNo(0)))
+              .ArgConstraint(NotNull(ArgNo(1))));
+
+      // int lstat(const char *restrict path, struct stat *restrict buf);
+      addToFunctionSummaryMap(
+          "lstat",
+          Summary(ArgTypes{ConstCharPtrRestrictTy, *StructStatPtrRestrictTy},
+                  RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(NotNull(ArgNo(0)))
+              .ArgConstraint(NotNull(ArgNo(1))));
+
+      // int fstatat(int fd, const char *restrict path,
+      //             struct stat *restrict buf, int flag);
+      addToFunctionSummaryMap(
+          "fstatat", Summary(ArgTypes{IntTy, ConstCharPtrRestrictTy,
+                                      *StructStatPtrRestrictTy, IntTy},
+                             RetType{IntTy}, NoEvalCall)
+                         .ArgConstraint(ArgumentCondition(0, WithinRange,
+                                                          Range(0, IntMax)))
+                         .ArgConstraint(NotNull(ArgNo(1)))
+                         .ArgConstraint(NotNull(ArgNo(2))));
+    }
+
+    if (DirPtrTy) {
+      // DIR *opendir(const char *name);
+      addToFunctionSummaryMap("opendir", Summary(ArgTypes{ConstCharPtrTy},
+                                                 RetType{*DirPtrTy}, NoEvalCall)
+                                             .ArgConstraint(NotNull(ArgNo(0))));
+
+      // DIR *fdopendir(int fd);
+      addToFunctionSummaryMap(
+          "fdopendir", Summary(ArgTypes{IntTy}, RetType{*DirPtrTy}, NoEvalCall)
+                           .ArgConstraint(ArgumentCondition(0, WithinRange,
+                                                            Range(0, IntMax))));
+    }
+
+    // int isatty(int fildes);
+    addToFunctionSummaryMap(
+        "isatty", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall)
+                      .ArgConstraint(
+                          ArgumentCondition(0, WithinRange, Range(0, IntMax))));
+
+    if (FilePtrTy) {
+      // FILE *popen(const char *command, const char *type);
+      addToFunctionSummaryMap("popen",
+                              Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy},
+                                      RetType{*FilePtrTy}, NoEvalCall)
+                                  .ArgConstraint(NotNull(ArgNo(0)))
+                                  .ArgConstraint(NotNull(ArgNo(1))));
+
+      // int pclose(FILE *stream);
+      addToFunctionSummaryMap(
+          "pclose", Summary(ArgTypes{*FilePtrTy}, RetType{IntTy}, NoEvalCall)
+                        .ArgConstraint(NotNull(ArgNo(0))));
+    }
+
+    // int close(int fildes);
+    addToFunctionSummaryMap(
+        "close", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall)
+                     .ArgConstraint(
+                         ArgumentCondition(0, WithinRange, Range(0, IntMax))));
+
+    // long fpathconf(int fildes, int name);
+    addToFunctionSummaryMap(
+        "fpathconf",
+        Summary(ArgTypes{IntTy, IntTy}, RetType{LongTy}, NoEvalCall)
+            .ArgConstraint(
+                ArgumentCondition(0, WithinRange, Range(0, IntMax))));
+
+    // long pathconf(const char *path, int name);
+    addToFunctionSummaryMap("pathconf", Summary(ArgTypes{ConstCharPtrTy, IntTy},
+                                                RetType{LongTy}, NoEvalCall)
+                                            .ArgConstraint(NotNull(ArgNo(0))));
+
+    if (FilePtrTy)
+      // FILE *fdopen(int fd, const char *mode);
+      addToFunctionSummaryMap(
+          "fdopen", Summary(ArgTypes{IntTy, ConstCharPtrTy},
+                            RetType{*FilePtrTy}, NoEvalCall)
+                        .ArgConstraint(
+                            ArgumentCondition(0, WithinRange, Range(0, IntMax)))
+                        .ArgConstraint(NotNull(ArgNo(1))));
+
+    if (DirPtrTy) {
+      // void rewinddir(DIR *dir);
+      addToFunctionSummaryMap(
+          "rewinddir", Summary(ArgTypes{*DirPtrTy}, RetType{VoidTy}, NoEvalCall)
+                           .ArgConstraint(NotNull(ArgNo(0))));
+
+      // void seekdir(DIR *dirp, long loc);
+      addToFunctionSummaryMap("seekdir", Summary(ArgTypes{*DirPtrTy, LongTy},
+                                                 RetType{VoidTy}, NoEvalCall)
+                                             .ArgConstraint(NotNull(ArgNo(0))));
+    }
+
+    // int rand_r(unsigned int *seedp);
+    addToFunctionSummaryMap("rand_r", Summary(ArgTypes{UnsignedIntPtrTy},
+                                              RetType{IntTy}, NoEvalCall)
+                                          .ArgConstraint(NotNull(ArgNo(0))));
+
+    // int strcasecmp(const char *s1, const char *s2);
+    addToFunctionSummaryMap("strcasecmp",
+                            Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy},
+                                    RetType{IntTy}, EvalCallAsPure)
+                                .ArgConstraint(NotNull(ArgNo(0)))
+                                .ArgConstraint(NotNull(ArgNo(1))));
+
+    // int strncasecmp(const char *s1, const char *s2, size_t n);
+    addToFunctionSummaryMap(
+        "strncasecmp", Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy, SizeTy},
+                               RetType{IntTy}, EvalCallAsPure)
+                           .ArgConstraint(NotNull(ArgNo(0)))
+                           .ArgConstraint(NotNull(ArgNo(1)))
+                           .ArgConstraint(ArgumentCondition(
+                               2, WithinRange, Range(0, SizeMax))));
+
+    if (FilePtrTy && Off_tTy) {
+
+      // int fileno(FILE *stream);
+      addToFunctionSummaryMap(
+          "fileno", Summary(ArgTypes{*FilePtrTy}, RetType{IntTy}, NoEvalCall)
+                        .ArgConstraint(NotNull(ArgNo(0))));
+
+      // int fseeko(FILE *stream, off_t offset, int whence);
+      addToFunctionSummaryMap("fseeko",
+                              Summary(ArgTypes{*FilePtrTy, *Off_tTy, IntTy},
+                                      RetType{IntTy}, NoEvalCall)
+                                  .ArgConstraint(NotNull(ArgNo(0))));
+
+      // off_t ftello(FILE *stream);
+      addToFunctionSummaryMap(
+          "ftello", Summary(ArgTypes{*FilePtrTy}, RetType{*Off_tTy}, NoEvalCall)
+                        .ArgConstraint(NotNull(ArgNo(0))));
+    }
+
+    if (Off_tTy) {
+      Optional<RangeInt> Off_tMax = BVF.getMaxValue(*Off_tTy).getLimitedValue();
+
+      // void *mmap(void *addr, size_t length, int prot, int flags, int fd,
+      // off_t offset);
+      addToFunctionSummaryMap(
+          "mmap",
+          Summary(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, *Off_tTy},
+                  RetType{VoidPtrTy}, NoEvalCall)
+              .ArgConstraint(
+                  ArgumentCondition(1, WithinRange, Range(1, SizeMax)))
+              .ArgConstraint(
+                  ArgumentCondition(4, WithinRange, Range(0, *Off_tMax))));
+    }
+
+    Optional<QualType> Off64_tTy = lookupType("off64_t", ACtx);
+    Optional<RangeInt> Off64_tMax;
+    if (Off64_tTy) {
+      Off64_tMax = BVF.getMaxValue(*Off_tTy).getLimitedValue();
+      // void *mmap64(void *addr, size_t length, int prot, int flags, int fd,
+      // off64_t offset);
+      addToFunctionSummaryMap(
+          "mmap64",
+          Summary(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, *Off64_tTy},
+                  RetType{VoidPtrTy}, NoEvalCall)
+              .ArgConstraint(
+                  ArgumentCondition(1, WithinRange, Range(1, SizeMax)))
+              .ArgConstraint(
+                  ArgumentCondition(4, WithinRange, Range(0, *Off64_tMax))));
+    }
+
+    // int pipe(int fildes[2]);
+    addToFunctionSummaryMap(
+        "pipe", Summary(ArgTypes{IntPtrTy}, RetType{IntTy}, NoEvalCall)
+                    .ArgConstraint(NotNull(ArgNo(0))));
+
+    if (Off_tTy)
+      // off_t lseek(int fildes, off_t offset, int whence);
+      addToFunctionSummaryMap(
+          "lseek", Summary(ArgTypes{IntTy, *Off_tTy, IntTy}, RetType{*Off_tTy},
+                           NoEvalCall)
+                       .ArgConstraint(ArgumentCondition(0, WithinRange,
+                                                        Range(0, IntMax))));
+
+    Optional<QualType> Ssize_tTy = lookupType("ssize_t", ACtx);
+
+    if (Ssize_tTy) {
+      // ssize_t readlink(const char *restrict path, char *restrict buf,
+      //                  size_t bufsize);
+      addToFunctionSummaryMap(
+          "readlink",
+          Summary(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy},
+                  RetType{*Ssize_tTy}, NoEvalCall)
+              .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", Summary(ArgTypes{IntTy, ConstCharPtrRestrictTy,
+                                         CharPtrRestrictTy, SizeTy},
+                                RetType{*Ssize_tTy}, NoEvalCall)
+                            .ArgConstraint(ArgumentCondition(0, WithinRange,
+                                                             Range(0, IntMax)))
+                            .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", Summary(ArgTypes{IntTy, ConstCharPtrTy,
+                                                         IntTy, ConstCharPtrTy},
+                                                RetType{IntTy}, NoEvalCall)
+                                            .ArgConstraint(NotNull(ArgNo(1)))
+                                            .ArgConstraint(NotNull(ArgNo(3))));
+
+    // char *realpath(const char *restrict file_name,
+    //                char *restrict resolved_name);
+    addToFunctionSummaryMap(
+        "realpath", Summary(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy},
+                            RetType{CharPtrTy}, NoEvalCall)
+                        .ArgConstraint(NotNull(ArgNo(0))));
+
+    QualType CharPtrConstPtr = ACtx.getPointerType(CharPtrTy.withConst());
+
+    // int execv(const char *path, char *const argv[]);
+    addToFunctionSummaryMap("execv",
+                            Summary(ArgTypes{ConstCharPtrTy, CharPtrConstPtr},
+                                    RetType{IntTy}, NoEvalCall)
+                                .ArgConstraint(NotNull(ArgNo(0))));
+
+    // int execvp(const char *file, char *const argv[]);
+    addToFunctionSummaryMap("execvp",
+                            Summary(ArgTypes{ConstCharPtrTy, CharPtrConstPtr},
+                                    RetType{IntTy}, NoEvalCall)
+                                .ArgConstraint(NotNull(ArgNo(0))));
+
+    // int getopt(int argc, char * const argv[], const char *optstring);
+    addToFunctionSummaryMap(
+        "getopt",
+        Summary(ArgTypes{IntTy, CharPtrConstPtr, ConstCharPtrTy},
+                RetType{IntTy}, NoEvalCall)
+            .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
+            .ArgConstraint(NotNull(ArgNo(1)))
+            .ArgConstraint(NotNull(ArgNo(2))));
+  }
+
   // Functions for testing.
   if (ChecksEnabled[CK_StdCLibraryFunctionsTesterChecker]) {
     addToFunctionSummaryMap(
@@ -1151,6 +1744,8 @@ void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) {
   Checker->DisplayLoadedSummaries =
       mgr.getAnalyzerOptions().getCheckerBooleanOption(
           Checker, "DisplayLoadedSummaries");
+  Checker->ModelPOSIX =
+      mgr.getAnalyzerOptions().getCheckerBooleanOption(Checker, "ModelPOSIX");
 }
 
 bool ento::shouldRegisterStdCLibraryFunctionsChecker(const CheckerManager &mgr) {

diff  --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c
index e4035cf755b2..56c749cc45d8 100644
--- a/clang/test/Analysis/analyzer-config.c
+++ b/clang/test/Analysis/analyzer-config.c
@@ -13,6 +13,7 @@
 // CHECK-NEXT: alpha.security.MmapWriteExec:MmapProtRead = 0x01
 // CHECK-NEXT: alpha.security.taint.TaintPropagation:Config = ""
 // CHECK-NEXT: apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries = false
+// CHECK-NEXT: apiModeling.StdCLibraryFunctions:ModelPOSIX = false
 // CHECK-NEXT: apply-fixits = false
 // CHECK-NEXT: avoid-suppressing-null-argument-paths = false
 // CHECK-NEXT: c++-allocator-inlining = true

diff  --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c
new file mode 100644
index 000000000000..e6f5b19baa00
--- /dev/null
+++ b/clang/test/Analysis/std-c-library-functions-POSIX.c
@@ -0,0 +1,178 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=apiModeling.StdCLibraryFunctions \
+// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true \
+// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries=true \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -triple i686-unknown-linux 2>&1 | FileCheck %s
+
+// CHECK: Loaded summary for: long a64l(const char *str64)
+// CHECK: Loaded summary for: char *l64a(long value)
+// CHECK: Loaded summary for: int access(const char *pathname, int amode)
+// CHECK: Loaded summary for: int faccessat(int dirfd, const char *pathname, int mode, int flags)
+// CHECK: Loaded summary for: int dup(int fildes)
+// CHECK: Loaded summary for: int dup2(int fildes1, int filedes2)
+// CHECK: Loaded summary for: int fdatasync(int fildes)
+// CHECK: Loaded summary for: int fnmatch(const char *pattern, const char *string, int flags)
+// CHECK: Loaded summary for: int fsync(int fildes)
+// CHECK: Loaded summary for: int truncate(const char *path, off_t length)
+// CHECK: Loaded summary for: int symlink(const char *oldpath, const char *newpath)
+// CHECK: Loaded summary for: int symlinkat(const char *oldpath, int newdirfd, const char *newpath)
+// CHECK: Loaded summary for: int lockf(int fd, int cmd, off_t len)
+// CHECK: Loaded summary for: int creat(const char *pathname, mode_t mode)
+// CHECK: Loaded summary for: unsigned int sleep(unsigned int seconds)
+// CHECK: Loaded summary for: int dirfd(DIR *dirp)
+// CHECK: Loaded summary for: unsigned int alarm(unsigned int seconds)
+// CHECK: Loaded summary for: int closedir(DIR *dir)
+// CHECK: Loaded summary for: char *strdup(const char *s)
+// CHECK: Loaded summary for: char *strndup(const char *s, size_t n)
+// CHECK: Loaded summary for: int mkstemp(char *template)
+// CHECK: Loaded summary for: char *mkdtemp(char *template)
+// CHECK: Loaded summary for: char *getcwd(char *buf, size_t size)
+// CHECK: Loaded summary for: int mkdir(const char *pathname, mode_t mode)
+// CHECK: Loaded summary for: int mkdirat(int dirfd, const char *pathname, mode_t mode)
+// CHECK: Loaded summary for: int mknod(const char *pathname, mode_t mode, dev_t dev)
+// CHECK: Loaded summary for: int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev)
+// CHECK: Loaded summary for: int chmod(const char *path, mode_t mode)
+// CHECK: Loaded summary for: int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags)
+// CHECK: Loaded summary for: int fchmod(int fildes, mode_t mode)
+// CHECK: Loaded summary for: int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags)
+// CHECK: Loaded summary for: int chown(const char *path, uid_t owner, gid_t group)
+// CHECK: Loaded summary for: int lchown(const char *path, uid_t owner, gid_t group)
+// CHECK: Loaded summary for: int fchown(int fildes, uid_t owner, gid_t group)
+// CHECK: Loaded summary for: int rmdir(const char *pathname)
+// CHECK: Loaded summary for: int chdir(const char *path)
+// CHECK: Loaded summary for: int link(const char *oldpath, const char *newpath)
+// CHECK: Loaded summary for: int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag)
+// CHECK: Loaded summary for: int unlink(const char *pathname)
+// CHECK: Loaded summary for: int unlinkat(int fd, const char *path, int flag)
+// CHECK: Loaded summary for: int fstat(int fd, struct stat *statbuf)
+// CHECK: Loaded summary for: int stat(const char *restrict path, struct stat *restrict buf)
+// CHECK: Loaded summary for: int lstat(const char *restrict path, struct stat *restrict buf)
+// CHECK: Loaded summary for: int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag)
+// CHECK: Loaded summary for: DIR *opendir(const char *name)
+// CHECK: Loaded summary for: DIR *fdopendir(int fd)
+// CHECK: Loaded summary for: int isatty(int fildes)
+// CHECK: Loaded summary for: FILE *popen(const char *command, const char *type)
+// CHECK: Loaded summary for: int pclose(FILE *stream)
+// CHECK: Loaded summary for: int close(int fildes)
+// CHECK: Loaded summary for: long fpathconf(int fildes, int name)
+// CHECK: Loaded summary for: long pathconf(const char *path, int name)
+// CHECK: Loaded summary for: FILE *fdopen(int fd, const char *mode)
+// CHECK: Loaded summary for: void rewinddir(DIR *dir)
+// CHECK: Loaded summary for: void seekdir(DIR *dirp, long loc)
+// CHECK: Loaded summary for: int rand_r(unsigned int *seedp)
+// CHECK: Loaded summary for: int strcasecmp(const char *s1, const char *s2)
+// CHECK: Loaded summary for: int strncasecmp(const char *s1, const char *s2, size_t n)
+// CHECK: Loaded summary for: int fileno(FILE *stream)
+// CHECK: Loaded summary for: int fseeko(FILE *stream, off_t offset, int whence)
+// CHECK: Loaded summary for: off_t ftello(FILE *stream)
+// CHECK: Loaded summary for: void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
+// CHECK: Loaded summary for: void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset)
+// CHECK: Loaded summary for: int pipe(int fildes[2])
+// CHECK: Loaded summary for: off_t lseek(int fildes, off_t offset, int whence)
+// CHECK: Loaded summary for: ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
+// CHECK: Loaded summary for: ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize)
+// CHECK: Loaded summary for: int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath)
+// CHECK: Loaded summary for: char *realpath(const char *restrict file_name, char *restrict resolved_name)
+// CHECK: Loaded summary for: int execv(const char *path, char *const argv[])
+// CHECK: Loaded summary for: int execvp(const char *file, char *const argv[])
+// CHECK: Loaded summary for: int getopt(int argc, char *const argv[], const char *optstring)
+
+long a64l(const char *str64);
+char *l64a(long value);
+int access(const char *pathname, int amode);
+int faccessat(int dirfd, const char *pathname, int mode, int flags);
+int dup(int fildes);
+int dup2(int fildes1, int filedes2);
+int fdatasync(int fildes);
+int fnmatch(const char *pattern, const char *string, int flags);
+int fsync(int fildes);
+typedef unsigned long off_t;
+int truncate(const char *path, off_t length);
+int symlink(const char *oldpath, const char *newpath);
+int symlinkat(const char *oldpath, int newdirfd, const char *newpath);
+int lockf(int fd, int cmd, off_t len);
+typedef unsigned mode_t;
+int creat(const char *pathname, mode_t mode);
+unsigned int sleep(unsigned int seconds);
+typedef struct {
+  int a;
+} DIR;
+int dirfd(DIR *dirp);
+unsigned int alarm(unsigned int seconds);
+int closedir(DIR *dir);
+char *strdup(const char *s);
+typedef typeof(sizeof(int)) size_t;
+char *strndup(const char *s, size_t n);
+/*FIXME How to define wchar_t in the test?*/
+/*typedef __wchar_t wchar_t;*/
+/*wchar_t *wcsdup(const wchar_t *s);*/
+int mkstemp(char *template);
+char *mkdtemp(char *template);
+char *getcwd(char *buf, size_t size);
+int mkdir(const char *pathname, mode_t mode);
+int mkdirat(int dirfd, const char *pathname, mode_t mode);
+typedef int dev_t;
+int mknod(const char *pathname, mode_t mode, dev_t dev);
+int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev);
+int chmod(const char *path, mode_t mode);
+int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);
+int fchmod(int fildes, mode_t mode);
+typedef int uid_t;
+typedef int gid_t;
+int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags);
+int chown(const char *path, uid_t owner, gid_t group);
+int lchown(const char *path, uid_t owner, gid_t group);
+int fchown(int fildes, uid_t owner, gid_t group);
+int rmdir(const char *pathname);
+int chdir(const char *path);
+int link(const char *oldpath, const char *newpath);
+int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag);
+int unlink(const char *pathname);
+int unlinkat(int fd, const char *path, int flag);
+struct stat;
+int fstat(int fd, struct stat *statbuf);
+int stat(const char *restrict path, struct stat *restrict buf);
+int lstat(const char *restrict path, struct stat *restrict buf);
+int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag);
+DIR *opendir(const char *name);
+DIR *fdopendir(int fd);
+int isatty(int fildes);
+typedef struct {
+  int x;
+} FILE;
+FILE *popen(const char *command, const char *type);
+int pclose(FILE *stream);
+int close(int fildes);
+long fpathconf(int fildes, int name);
+long pathconf(const char *path, int name);
+FILE *fdopen(int fd, const char *mode);
+void rewinddir(DIR *dir);
+void seekdir(DIR *dirp, long loc);
+int rand_r(unsigned int *seedp);
+int strcasecmp(const char *s1, const char *s2);
+int strncasecmp(const char *s1, const char *s2, size_t n);
+int fileno(FILE *stream);
+int fseeko(FILE *stream, off_t offset, int whence);
+off_t ftello(FILE *stream);
+void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
+typedef off_t off64_t;
+void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset);
+int pipe(int fildes[2]);
+off_t lseek(int fildes, off_t offset, int whence);
+typedef size_t ssize_t;
+ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);
+ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize);
+int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
+char *realpath(const char *restrict file_name, char *restrict resolved_name);
+int execv(const char *path, char *const argv[]);
+int execvp(const char *file, char *const argv[]);
+int getopt(int argc, char *const argv[], const char *optstring);
+
+// Must have at least one call expression to initialize the summary map.
+int bar(void);
+void foo() {
+  bar();
+}


        


More information about the cfe-commits mailing list