2020-03-20 23:20:53 +08:00
|
|
|
// RUN: %clang_analyze_cc1 %s \
|
|
|
|
// RUN: -analyzer-checker=core \
|
|
|
|
// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
|
|
|
|
// RUN: -analyzer-checker=debug.ExprInspection \
|
|
|
|
// RUN: -analyzer-config eagerly-assume=false \
|
|
|
|
// RUN: -triple i686-unknown-linux \
|
|
|
|
// RUN: -verify
|
|
|
|
|
|
|
|
// RUN: %clang_analyze_cc1 %s \
|
|
|
|
// RUN: -analyzer-checker=core \
|
|
|
|
// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
|
|
|
|
// RUN: -analyzer-checker=debug.ExprInspection \
|
|
|
|
// RUN: -analyzer-config eagerly-assume=false \
|
|
|
|
// RUN: -triple x86_64-unknown-linux \
|
|
|
|
// RUN: -verify
|
|
|
|
|
|
|
|
// RUN: %clang_analyze_cc1 %s \
|
|
|
|
// RUN: -analyzer-checker=core \
|
|
|
|
// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
|
|
|
|
// RUN: -analyzer-checker=debug.ExprInspection \
|
|
|
|
// RUN: -analyzer-config eagerly-assume=false \
|
|
|
|
// RUN: -triple armv7-a15-linux \
|
|
|
|
// RUN: -verify
|
|
|
|
|
|
|
|
// RUN: %clang_analyze_cc1 %s \
|
|
|
|
// RUN: -analyzer-checker=core \
|
|
|
|
// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
|
|
|
|
// RUN: -analyzer-checker=debug.ExprInspection \
|
|
|
|
// RUN: -analyzer-config eagerly-assume=false \
|
|
|
|
// RUN: -triple thumbv7-a15-linux \
|
|
|
|
// RUN: -verify
|
2016-10-24 17:41:38 +08:00
|
|
|
|
[analyzer] StdLibraryFunctionsChecker: Add option to display loaded summaries
Reviewers: NoQ, Szelethus, baloghadamsoftware, balazske
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, steakhal, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D78118
2020-04-14 23:40:42 +08:00
|
|
|
// RUN: %clang_analyze_cc1 %s \
|
|
|
|
// RUN: -analyzer-checker=core \
|
|
|
|
// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
|
|
|
|
// 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: int isalnum(int)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int isalpha(int)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int isascii(int)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int isblank(int)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int isdigit(int)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int isgraph(int)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int islower(int)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int isprint(int)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int ispunct(int)
|
|
|
|
// 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 getc(FILE *)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int fgetc(FILE *)
|
|
|
|
// CHECK-NEXT: Loaded summary for: int getchar()
|
[analyzer] StdLibraryFunctionsChecker: Add support to lookup types
Summary:
In this patch I am trying to get rid of the `Irrelevant` types from the
signatures of the functions from the standard C library. For that I've
introduced `lookupType()` to be able to lookup arbitrary types in the global
scope. This makes it possible to define the signatures precisely.
Note 1) `fread`'s signature is now fixed to have the proper `FILE *restrict`
type when C99 is the language.
Note 2) There are still existing `Irrelevant` types, but they are all from
POSIX. I am planning to address those together with the missing POSIX functions
(in D79433).
Reviewers: xazax.hun, NoQ, Szelethus, balazske
Subscribers: whisperity, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, steakhal, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D80016
2020-05-15 17:25:40 +08:00
|
|
|
// CHECK-NEXT: Loaded summary for: unsigned int fread(void *restrict, size_t, size_t, FILE *restrict)
|
|
|
|
// CHECK-NEXT: Loaded summary for: unsigned int fwrite(const void *restrict, size_t, size_t, FILE *restrict)
|
[analyzer] StdLibraryFunctionsChecker: Add option to display loaded summaries
Reviewers: NoQ, Szelethus, baloghadamsoftware, balazske
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, steakhal, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D78118
2020-04-14 23:40:42 +08:00
|
|
|
// CHECK-NEXT: Loaded summary for: ssize_t read(int, void *, size_t)
|
|
|
|
// CHECK-NEXT: Loaded summary for: ssize_t write(int, const void *, size_t)
|
|
|
|
// CHECK-NEXT: Loaded summary for: ssize_t getline(char **, size_t *, FILE *)
|
|
|
|
|
2016-10-24 17:41:38 +08:00
|
|
|
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) {
|
|
|
|
clang_analyzer_eval(x > 255); // expected-warning{{FALSE}}
|
|
|
|
clang_analyzer_eval(x >= 0); // expected-warning{{TRUE}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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}}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-11-03 03:35:20 +08:00
|
|
|
typedef typeof(sizeof(int)) size_t;
|
2016-10-24 17:41:38 +08:00
|
|
|
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);
|
|
|
|
clang_analyzer_eval(glob); // expected-warning{{UNKNOWN}}
|
|
|
|
if (x >= 0) {
|
|
|
|
clang_analyzer_eval(x <= 10); // expected-warning{{TRUE}}
|
|
|
|
ssize_t y = read(fd, &glob, sizeof(glob));
|
|
|
|
if (y >= 0) {
|
|
|
|
clang_analyzer_eval(y <= sizeof(glob)); // expected-warning{{TRUE}}
|
|
|
|
} else {
|
|
|
|
// -1 overflows on promotion!
|
|
|
|
clang_analyzer_eval(y <= sizeof(glob)); // expected-warning{{FALSE}}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
clang_analyzer_eval(x == -1); // expected-warning{{TRUE}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[analyzer] StdLibraryFunctionsChecker: Add support to lookup types
Summary:
In this patch I am trying to get rid of the `Irrelevant` types from the
signatures of the functions from the standard C library. For that I've
introduced `lookupType()` to be able to lookup arbitrary types in the global
scope. This makes it possible to define the signatures precisely.
Note 1) `fread`'s signature is now fixed to have the proper `FILE *restrict`
type when C99 is the language.
Note 2) There are still existing `Irrelevant` types, but they are all from
POSIX. I am planning to address those together with the missing POSIX functions
(in D79433).
Reviewers: xazax.hun, NoQ, Szelethus, balazske
Subscribers: whisperity, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, steakhal, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D80016
2020-05-15 17:25:40 +08:00
|
|
|
size_t fread(void *restrict, size_t, size_t, FILE *restrict);
|
2016-10-24 17:41:38 +08:00
|
|
|
size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
|
|
|
|
void test_fread_fwrite(FILE *fp, int *buf) {
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
|
2016-10-24 17:41:38 +08:00
|
|
|
size_t x = fwrite(buf, sizeof(int), 10, fp);
|
|
|
|
clang_analyzer_eval(x <= 10); // expected-warning{{TRUE}}
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
|
2016-10-24 17:41:38 +08:00
|
|
|
size_t y = fread(buf, sizeof(int), 10, fp);
|
|
|
|
clang_analyzer_eval(y <= 10); // expected-warning{{TRUE}}
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
|
2016-10-24 17:41:38 +08:00
|
|
|
size_t z = fwrite(buf, sizeof(int), y, fp);
|
2018-07-16 21:14:46 +08:00
|
|
|
clang_analyzer_eval(z <= y); // expected-warning{{TRUE}}
|
2016-10-24 17:41:38 +08:00
|
|
|
}
|
|
|
|
|
[analyzer] Fix StdLibraryFunctionsChecker NotNull Constraint Check
Summary:
This check was causing a crash in a test case where the 0th argument was
uninitialized ('Assertion `T::isKind(*this)' at line SVals.h:104). This
was happening since the argument was actually undefined, but the castAs
assumes the value is DefinedOrUnknownSVal.
The fix appears to be simply to check for an undefined value and skip
the check allowing the uninitalized value checker to detect the error.
I included a test case that I verified to produce the negative case
prior to the fix, and passes with the fix.
Reviewers: martong, NoQ
Subscribers: xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, Charusso, ASDenysPetrov, baloghadamsoftware, dkrupp, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77012
2020-03-29 20:48:26 +08:00
|
|
|
void test_fread_uninitialized(void) {
|
|
|
|
void *ptr;
|
|
|
|
size_t sz;
|
|
|
|
size_t nmem;
|
|
|
|
FILE *fp;
|
|
|
|
(void)fread(ptr, sz, nmem, fp); // expected-warning {{1st function call argument is an uninitialized value}}
|
|
|
|
}
|
|
|
|
|
2016-10-24 17:41:38 +08:00
|
|
|
ssize_t getline(char **, size_t *, FILE *);
|
|
|
|
void test_getline(FILE *fp) {
|
|
|
|
char *line = 0;
|
|
|
|
size_t n = 0;
|
|
|
|
ssize_t len;
|
|
|
|
while ((len = getline(&line, &n, fp)) != -1) {
|
|
|
|
clang_analyzer_eval(len == 0); // expected-warning{{FALSE}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int isascii(int);
|
|
|
|
void test_isascii(int x) {
|
|
|
|
clang_analyzer_eval(isascii(123)); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(isascii(-1)); // expected-warning{{FALSE}}
|
|
|
|
if (isascii(x)) {
|
|
|
|
clang_analyzer_eval(x < 128); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(x >= 0); // expected-warning{{TRUE}}
|
|
|
|
} else {
|
|
|
|
if (x > 42)
|
|
|
|
clang_analyzer_eval(x >= 128); // expected-warning{{TRUE}}
|
|
|
|
else
|
|
|
|
clang_analyzer_eval(x < 0); // expected-warning{{TRUE}}
|
|
|
|
}
|
|
|
|
glob = 1;
|
|
|
|
isascii('a');
|
|
|
|
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}}
|
|
|
|
if (islower(x))
|
|
|
|
clang_analyzer_eval(x < 'a'); // expected-warning{{FALSE}}
|
|
|
|
}
|
|
|
|
|
|
|
|
int getchar(void);
|
|
|
|
void test_getchar() {
|
|
|
|
int x = getchar();
|
|
|
|
if (x == EOF)
|
|
|
|
return;
|
|
|
|
clang_analyzer_eval(x < 0); // expected-warning{{FALSE}}
|
|
|
|
clang_analyzer_eval(x < 256); // expected-warning{{TRUE}}
|
|
|
|
}
|
|
|
|
|
|
|
|
int isalpha(int);
|
|
|
|
void test_isalpha() {
|
|
|
|
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() {
|
|
|
|
clang_analyzer_eval(isalnum('1')); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(isalnum(')')); // expected-warning{{FALSE}}
|
|
|
|
}
|
|
|
|
|
|
|
|
int isblank(int);
|
|
|
|
void test_isblank() {
|
|
|
|
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}}
|
|
|
|
clang_analyzer_eval(ispunct('#')); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(ispunct('_')); // expected-warning{{TRUE}}
|
|
|
|
if (ispunct(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}}
|
|
|
|
clang_analyzer_eval(isblank(x)); // expected-warning{{FALSE}}
|
|
|
|
} else if (isascii(x)) {
|
|
|
|
// isalnum() bifurcates here.
|
|
|
|
clang_analyzer_eval(isalnum(x)); // expected-warning{{TRUE}} // expected-warning{{FALSE}}
|
|
|
|
clang_analyzer_eval(isprint(x)); // expected-warning{{TRUE}} // expected-warning{{FALSE}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int isspace(int);
|
|
|
|
void test_isspace(int x) {
|
|
|
|
if (!isascii(x))
|
|
|
|
return;
|
|
|
|
char y = x;
|
|
|
|
if (y == ' ')
|
|
|
|
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}}
|
|
|
|
clang_analyzer_eval(x <= 'F'); // expected-warning{{TRUE}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_call_by_pointer() {
|
|
|
|
typedef int (*func)(int);
|
|
|
|
func f = isascii;
|
|
|
|
clang_analyzer_eval(f('A')); // expected-warning{{TRUE}}
|
|
|
|
f = ispunct;
|
|
|
|
clang_analyzer_eval(f('A')); // expected-warning{{FALSE}}
|
|
|
|
}
|