[clang][analyzer] Cleanup tests of StdCLibraryFunctionsChecker (NFC)
authorBalázs Kéri <1.int32@gmail.com>
Fri, 12 May 2023 07:20:35 +0000 (09:20 +0200)
committerBalázs Kéri <balazs.keri@ericsson.com>
Fri, 12 May 2023 07:54:01 +0000 (09:54 +0200)
Function declarations are moved into common header that can be reused
to avoid repetitions in different test files.
Some small problems in the tests were found and fixed.

Reviewed By: steakhal

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

clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h [new file with mode: 0644]
clang/test/Analysis/Inputs/std-c-library-functions.h [new file with mode: 0644]
clang/test/Analysis/std-c-library-functions-POSIX.c
clang/test/Analysis/std-c-library-functions-arg-constraints.c
clang/test/Analysis/std-c-library-functions.c

diff --git a/clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h b/clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
new file mode 100644 (file)
index 0000000..942c918
--- /dev/null
@@ -0,0 +1,181 @@
+#include "std-c-library-functions.h"
+
+typedef int off_t;
+typedef unsigned int mode_t;
+typedef __WCHAR_TYPE__ wchar_t;
+typedef unsigned int dev_t;
+typedef unsigned int uid_t;
+typedef unsigned int gid_t;
+typedef unsigned long socklen_t;
+typedef unsigned long int pthread_t;
+typedef unsigned long time_t;
+typedef unsigned long clockid_t;
+typedef __INT64_TYPE__ off64_t;
+
+typedef struct {
+  int a;
+} DIR;
+struct stat {
+  int a;
+};
+struct timespec { int x; };
+struct timeval { int x; };
+struct sockaddr;
+struct sockaddr_at;
+struct msghdr;
+struct utimbuf;
+struct itimerval;
+typedef union {
+  int x;
+} pthread_cond_t;
+typedef union {
+  int x;
+} pthread_attr_t;
+typedef union {
+  int x;
+} pthread_mutex_t;
+typedef union {
+  int x;
+} pthread_mutexattr_t;
+
+FILE *fopen(const char *restrict pathname, const char *restrict mode);
+FILE *tmpfile(void);
+FILE *freopen(const char *restrict pathname, const char *restrict mode,
+              FILE *restrict stream);
+int fclose(FILE *stream);
+int fseek(FILE *stream, long offset, int whence);
+int fileno(FILE *stream);
+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);
+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);
+int creat(const char *pathname, mode_t mode);
+unsigned int sleep(unsigned int seconds);
+int dirfd(DIR *dirp);
+unsigned int alarm(unsigned int seconds);
+int closedir(DIR *dir);
+char *strdup(const char *s);
+char *strndup(const char *s, size_t n);
+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);
+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);
+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);
+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);
+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 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);
+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);
+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);
+
+// In some libc implementations, sockaddr parameter is a transparent
+// union of the underlying sockaddr_ pointers instead of being a
+// pointer to struct sockaddr.
+// We match that with the joker Irrelevant type.
+#define __SOCKADDR_ALLTYPES    \
+  __SOCKADDR_ONETYPE(sockaddr) \
+  __SOCKADDR_ONETYPE(sockaddr_at)
+#define __SOCKADDR_ONETYPE(type) struct type *restrict __##type##__;
+typedef union {
+  __SOCKADDR_ALLTYPES
+} __SOCKADDR_ARG __attribute__((__transparent_union__));
+#undef __SOCKADDR_ONETYPE
+#define __SOCKADDR_ONETYPE(type) const struct type *restrict __##type##__;
+typedef union {
+  __SOCKADDR_ALLTYPES
+} __CONST_SOCKADDR_ARG __attribute__((__transparent_union__));
+#undef __SOCKADDR_ONETYPE
+
+int accept(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len);
+int bind(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len);
+int getpeername(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len);
+int getsockname(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len);
+int connect(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len);
+ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags, __SOCKADDR_ARG address, socklen_t *restrict address_len);
+ssize_t sendto(int socket, const void *message, size_t length, int flags, __CONST_SOCKADDR_ARG dest_addr, socklen_t dest_len);
+int listen(int sockfd, int backlog);
+ssize_t recv(int sockfd, void *buf, size_t len, int flags);
+ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
+ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
+int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);
+int getsockopt(int socket, int level, int option_name, void *restrict option_value, socklen_t *restrict option_len);
+ssize_t send(int sockfd, const void *buf, size_t len, int flags);
+int socketpair(int domain, int type, int protocol, int sv[2]);
+int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags);
+int utime(const char *filename, struct utimbuf *buf);
+int futimens(int fd, const struct timespec times[2]);
+int utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags);
+int utimes(const char *filename, const struct timeval times[2]);
+int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
+struct tm *localtime(const time_t *tp);
+struct tm *localtime_r(const time_t *restrict timer, struct tm *restrict result);
+char *asctime_r(const struct tm *restrict tm, char *restrict buf);
+char *ctime_r(const time_t *timep, char *buf);
+struct tm *gmtime_r(const time_t *restrict timer, struct tm *restrict result);
+struct tm *gmtime(const time_t *tp);
+int clock_gettime(clockid_t clock_id, struct timespec *tp);
+int getitimer(int which, struct itimerval *curr_value);
+
+int pthread_cond_signal(pthread_cond_t *cond);
+int pthread_cond_broadcast(pthread_cond_t *cond);
+int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg);
+int pthread_attr_destroy(pthread_attr_t *attr);
+int pthread_attr_init(pthread_attr_t *attr);
+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);
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
+int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
+int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
+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);
diff --git a/clang/test/Analysis/Inputs/std-c-library-functions.h b/clang/test/Analysis/Inputs/std-c-library-functions.h
new file mode 100644 (file)
index 0000000..7c86c35
--- /dev/null
@@ -0,0 +1,47 @@
+typedef __SIZE_TYPE__ size_t;
+#define __SSIZE_TYPE__                                                         \
+  __typeof__(_Generic((__SIZE_TYPE__)0,                                        \
+                      unsigned long long int : (long long int)0,               \
+                      unsigned long int : (long int)0,                         \
+                      unsigned int : (int)0,                                   \
+                      unsigned short : (short)0))
+typedef __SSIZE_TYPE__ ssize_t;
+typedef struct {
+  int x;
+} FILE;
+
+// do not use the default values for these constants to verify that this
+// definition is found
+#define EOF (-2)
+#define AT_FDCWD (-101)
+
+#ifdef __cplusplus
+#define restrict /*restrict*/
+#endif
+
+int isascii(int);
+int islower(int);
+int isalpha(int);
+int isalnum(int);
+int isblank(int);
+int ispunct(int);
+int isupper(int);
+int isgraph(int);
+int isprint(int);
+int isdigit(int);
+int isspace(int);
+int isxdigit(int);
+int toupper(int);
+int tolower(int);
+int toascii(int);
+
+int getc(FILE *);
+int fgetc(FILE *);
+int getchar(void);
+size_t fread(void *restrict, size_t, size_t, FILE *restrict);
+size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
+ssize_t read(int, void *, size_t);
+ssize_t write(int, const void *, size_t);
+ssize_t getline(char **restrict, size_t *restrict, FILE *restrict);
+ssize_t getdelim(char **restrict, size_t *restrict, int, FILE *restrict);
+char *getenv(const char *);
index 12ee769..a646e63 100644 (file)
 // CHECK: Loaded summary for: int pthread_mutex_trylock(pthread_mutex_t *mutex)
 // CHECK: Loaded summary for: int pthread_mutex_unlock(pthread_mutex_t *mutex)
 
-typedef struct {
-  int x;
-} FILE;
-FILE *fopen(const char *restrict pathname, const char *restrict mode);
-FILE *tmpfile(void);
-FILE *freopen(const char *restrict pathname, const char *restrict mode,
-              FILE *restrict stream);
-int fclose(FILE *stream);
-int fseek(FILE *stream, long offset, int whence);
-int fileno(FILE *stream);
-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);
-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 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);
-
-// In some libc implementations, sockaddr parameter is a transparent
-// union of the underlying sockaddr_ pointers instead of being a
-// pointer to struct sockaddr.
-// We match that with the joker Irrelevant type.
-struct sockaddr;
-struct sockaddr_at;
-#define __SOCKADDR_ALLTYPES    \
-  __SOCKADDR_ONETYPE(sockaddr) \
-  __SOCKADDR_ONETYPE(sockaddr_at)
-#define __SOCKADDR_ONETYPE(type) struct type *__restrict __##type##__;
-typedef union {
-  __SOCKADDR_ALLTYPES
-} __SOCKADDR_ARG __attribute__((__transparent_union__));
-#undef __SOCKADDR_ONETYPE
-#define __SOCKADDR_ONETYPE(type) const struct type *__restrict __##type##__;
-typedef union {
-  __SOCKADDR_ALLTYPES
-} __CONST_SOCKADDR_ARG __attribute__((__transparent_union__));
-#undef __SOCKADDR_ONETYPE
-typedef unsigned socklen_t;
-
-int accept(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len);
-int bind(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len);
-int getpeername(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len);
-int getsockname(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len);
-int connect(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len);
-ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags, __SOCKADDR_ARG address, socklen_t *restrict address_len);
-ssize_t sendto(int socket, const void *message, size_t length, int flags, __CONST_SOCKADDR_ARG dest_addr, socklen_t dest_len);
-
-int listen(int sockfd, int backlog);
-ssize_t recv(int sockfd, void *buf, size_t len, int flags);
-struct msghdr;
-ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
-ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
-int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);
-int getsockopt(int socket, int level, int option_name, void *restrict option_value, socklen_t *restrict option_len);
-ssize_t send(int sockfd, const void *buf, size_t len, int flags);
-int socketpair(int domain, int type, int protocol, int sv[2]);
-int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags);
-struct utimbuf;
-struct timespec { int x; };
-struct timeval { int x; };
-int utime(const char *filename, struct utimbuf *buf);
-int futimens(int fd, const struct timespec times[2]);
-int utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags);
-int utimes(const char *filename, const struct timeval times[2]);
-int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
-typedef unsigned long time_t;
-struct tm *localtime(const time_t *tp);
-struct tm *localtime_r(const time_t *restrict timer, struct tm *restrict result);
-char *asctime_r(const struct tm *restrict tm, char *restrict buf);
-char *ctime_r(const time_t *timep, char *buf);
-struct tm *gmtime_r(const time_t *restrict timer, struct tm *restrict result);
-struct tm *gmtime(const time_t *tp);
-typedef unsigned long clockid_t;
-int clock_gettime(clockid_t clock_id, struct timespec *tp);
-struct itimerval;
-int getitimer(int which, struct itimerval *curr_value);
-
-typedef union {
-  int x;
-} pthread_cond_t;
-int pthread_cond_signal(pthread_cond_t *cond);
-int pthread_cond_broadcast(pthread_cond_t *cond);
-typedef union {
-  int x;
-} pthread_attr_t;
-typedef unsigned long int pthread_t;
-int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg);
-int pthread_attr_destroy(pthread_attr_t *attr);
-int pthread_attr_init(pthread_attr_t *attr);
-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);
-int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
-int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
-typedef union {
-  int x;
-} pthread_mutex_t;
-typedef union {
-  int x;
-} pthread_mutexattr_t;
-int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
-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);
+#include "Inputs/std-c-library-functions-POSIX.h"
 
 // Must have at least one call expression to initialize the summary map.
 int bar(void);
index 83666f3..1d9e3ae 100644 (file)
 // RUN:   -analyzer-output=text \
 // RUN:   -verify=bugpath
 
+#include "Inputs/std-c-library-functions-POSIX.h"
+
 void clang_analyzer_eval(int);
 void clang_analyzer_warnIfReached();
 
 int glob;
 
-#define EOF -1
-
-int isalnum(int);
-
 void test_alnum_concrete(int v) {
   int ret = isalnum(256); // \
   // report-warning{{The 1st argument to 'isalnum' is 256 but should be an unsigned char value or EOF}} \
@@ -63,8 +61,6 @@ void test_alnum_symbolic2(int x) {
   }
 }
 
-int toupper(int);
-
 void test_toupper_concrete(int v) {
   int ret = toupper(256); // \
   // report-warning{{The 1st argument to 'toupper' is 256 but should be an unsigned char value or EOF}} \
@@ -99,8 +95,6 @@ void test_toupper_symbolic2(int x) {
   }
 }
 
-int tolower(int);
-
 void test_tolower_concrete(int v) {
   int ret = tolower(256); // \
   // report-warning{{The 1st argument to 'tolower' is 256 but should be an unsigned char value or EOF}} \
@@ -135,8 +129,6 @@ void test_tolower_symbolic2(int x) {
   }
 }
 
-int toascii(int);
-
 void test_toascii_concrete(int v) {
   int ret = toascii(256); // \
   // report-warning{{The 1st argument to 'toascii' is 256 but should be an unsigned char value or EOF}} \
@@ -171,9 +163,6 @@ void test_toascii_symbolic2(int x) {
   }
 }
 
-typedef struct FILE FILE;
-typedef typeof(sizeof(int)) size_t;
-size_t fread(void *restrict, size_t, size_t, FILE *restrict);
 void test_notnull_concrete(FILE *fp) {
   fread(0, sizeof(int), 10, fp); // \
   // report-warning{{The 1st argument to 'fread' is NULL but should not be NULL}} \
@@ -208,7 +197,6 @@ void test_no_node_after_bug(FILE *fp, size_t size, size_t n, void *buf) {
   clang_analyzer_warnIfReached(); // not reachable
 }
 
-typedef __WCHAR_TYPE__ wchar_t;
 // This is one test case for the ARR38-C SEI-CERT rule.
 void ARR38_C_F(FILE *file) {
   enum { BUFFER_SIZE = 1024 };
index a403229..419f98b 100644 (file)
@@ -50,6 +50,9 @@
 // CHECK-NEXT: Loaded summary for: int isspace(int)
 // CHECK-NEXT: Loaded summary for: int isupper(int)
 // CHECK-NEXT: Loaded summary for: int isxdigit(int)
+// CHECK-NEXT: Loaded summary for: int toupper(int)
+// CHECK-NEXT: Loaded summary for: int tolower(int)
+// CHECK-NEXT: Loaded summary for: int toascii(int)
 // CHECK-NEXT: Loaded summary for: int getc(FILE *)
 // CHECK-NEXT: Loaded summary for: int fgetc(FILE *)
 // CHECK-NEXT: Loaded summary for: int getchar(void)
 // CHECK-NEXT: Loaded summary for: ssize_t write(int, const void *, size_t)
 // CHECK-NEXT: Loaded summary for: ssize_t getline(char **restrict, size_t *restrict, FILE *restrict)
 // CHECK-NEXT: Loaded summary for: ssize_t getdelim(char **restrict, size_t *restrict, int, FILE *restrict)
+// CHECK-NEXT: Loaded summary for: char *getenv(const char *)
 
+#include "Inputs/std-c-library-functions.h"
 
 void clang_analyzer_eval(int);
 
 int glob;
 
-typedef struct FILE FILE;
-#define EOF -1
-
-int getc(FILE *);
 void test_getc(FILE *fp) {
   int x;
   while ((x = getc(fp)) != EOF) {
@@ -77,17 +78,11 @@ void test_getc(FILE *fp) {
   }
 }
 
-int fgetc(FILE *);
 void test_fgets(FILE *fp) {
   clang_analyzer_eval(fgetc(fp) < 256); // expected-warning{{TRUE}}
   clang_analyzer_eval(fgetc(fp) >= 0); // expected-warning{{UNKNOWN}}
 }
 
-
-typedef typeof(sizeof(int)) size_t;
-typedef signed long ssize_t;
-ssize_t read(int, void *, size_t);
-ssize_t write(int, const void *, size_t);
 void test_read_write(int fd, char *buf) {
   glob = 1;
   ssize_t x = write(fd, buf, 10);
@@ -106,8 +101,6 @@ void test_read_write(int fd, char *buf) {
   }
 }
 
-size_t fread(void *restrict, size_t, size_t, FILE *restrict);
-size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
 void test_fread_fwrite(FILE *fp, int *buf) {
 
   size_t x = fwrite(buf, sizeof(int), 10, fp);
@@ -128,8 +121,6 @@ void test_fread_uninitialized(void) {
   (void)fread(ptr, sz, nmem, fp); // expected-warning {{1st function call argument is an uninitialized value}}
 }
 
-ssize_t getline(char **restrict, size_t *restrict, FILE *restrict);
-ssize_t getdelim(char **restrict, size_t *restrict, int, FILE *restrict);
 void test_getline(FILE *fp) {
   char *line = 0;
   size_t n = 0;
@@ -139,7 +130,6 @@ void test_getline(FILE *fp) {
   }
 }
 
-int isascii(int);
 void test_isascii(int x) {
   clang_analyzer_eval(isascii(123)); // expected-warning{{TRUE}}
   clang_analyzer_eval(isascii(-1)); // expected-warning{{FALSE}}
@@ -157,7 +147,6 @@ void test_isascii(int x) {
   clang_analyzer_eval(glob); // expected-warning{{TRUE}}
 }
 
-int islower(int);
 void test_islower(int x) {
   clang_analyzer_eval(islower('x')); // expected-warning{{TRUE}}
   clang_analyzer_eval(islower('X')); // expected-warning{{FALSE}}
@@ -165,7 +154,6 @@ void test_islower(int x) {
     clang_analyzer_eval(x < 'a'); // expected-warning{{FALSE}}
 }
 
-int getchar(void);
 void test_getchar(void) {
   int x = getchar();
   if (x == EOF)
@@ -174,27 +162,23 @@ void test_getchar(void) {
   clang_analyzer_eval(x < 256); // expected-warning{{TRUE}}
 }
 
-int isalpha(int);
 void test_isalpha(void) {
   clang_analyzer_eval(isalpha(']')); // expected-warning{{FALSE}}
   clang_analyzer_eval(isalpha('Q')); // expected-warning{{TRUE}}
   clang_analyzer_eval(isalpha(128)); // expected-warning{{UNKNOWN}}
 }
 
-int isalnum(int);
 void test_alnum(void) {
   clang_analyzer_eval(isalnum('1')); // expected-warning{{TRUE}}
   clang_analyzer_eval(isalnum(')')); // expected-warning{{FALSE}}
 }
 
-int isblank(int);
 void test_isblank(void) {
   clang_analyzer_eval(isblank('\t')); // expected-warning{{TRUE}}
   clang_analyzer_eval(isblank(' ')); // expected-warning{{TRUE}}
   clang_analyzer_eval(isblank('\n')); // expected-warning{{FALSE}}
 }
 
-int ispunct(int);
 void test_ispunct(int x) {
   clang_analyzer_eval(ispunct(' ')); // expected-warning{{FALSE}}
   clang_analyzer_eval(ispunct(-1)); // expected-warning{{FALSE}}
@@ -204,21 +188,17 @@ void test_ispunct(int x) {
     clang_analyzer_eval(x < 127); // expected-warning{{TRUE}}
 }
 
-int isupper(int);
 void test_isupper(int x) {
   if (isupper(x))
     clang_analyzer_eval(x < 'A'); // expected-warning{{FALSE}}
 }
 
-int isgraph(int);
-int isprint(int);
 void test_isgraph_isprint(int x) {
   char y = x;
   if (isgraph(y))
     clang_analyzer_eval(isprint(x)); // expected-warning{{TRUE}}
 }
 
-int isdigit(int);
 void test_mixed_branches(int x) {
   if (isdigit(x)) {
     clang_analyzer_eval(isgraph(x)); // expected-warning{{TRUE}}
@@ -230,7 +210,6 @@ void test_mixed_branches(int x) {
   }
 }
 
-int isspace(int);
 void test_isspace(int x) {
   if (!isascii(x))
     return;
@@ -239,7 +218,6 @@ void test_isspace(int x) {
     clang_analyzer_eval(isspace(x)); // expected-warning{{TRUE}}
 }
 
-int isxdigit(int);
 void test_isxdigit(int x) {
   if (isxdigit(x) && isupper(x)) {
     clang_analyzer_eval(x >= 'A'); // expected-warning{{TRUE}}
@@ -255,7 +233,6 @@ void test_call_by_pointer(void) {
   clang_analyzer_eval(f('A')); // expected-warning{{FALSE}}
 }
 
-char *getenv(const char *name);
 void test_getenv(void) {
   // getenv() bifurcates here.
   clang_analyzer_eval(getenv("FOO") == 0);