Skip to content

Commit

Permalink
[clang][analyzer] Improve modeling of 'fdopen' in StdLibraryFunctions…
Browse files Browse the repository at this point in the history
…Checker (#78680)
  • Loading branch information
benshi001 committed Jan 20, 2024
1 parent b7a66d0 commit 0223230
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 10 deletions.
19 changes: 10 additions & 9 deletions clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2171,6 +2171,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
.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}),
Expand Down Expand Up @@ -2853,15 +2863,6 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
"pathconf", Signature(ArgTypes{ConstCharPtrTy, IntTy}, RetType{LongTy}),
Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));

// FILE *fdopen(int fd, const char *mode);
// FIXME: Improve for errno modeling.
addToFunctionSummaryMap(
"fdopen",
Signature(ArgTypes{IntTy, ConstCharPtrTy}, RetType{FilePtrTy}),
Summary(NoEvalCall)
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
.ArgConstraint(NotNull(ArgNo(1))));

// void rewinddir(DIR *dir);
addToFunctionSummaryMap(
"rewinddir", Signature(ArgTypes{DirPtrTy}, RetType{VoidTy}),
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/std-c-library-functions-POSIX.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// RUN: -triple i686-unknown-linux 2>&1 | FileCheck %s

// CHECK: Loaded summary for: FILE *fopen(const char *restrict pathname, const char *restrict mode)
// CHECK: Loaded summary for: FILE *fdopen(int fd, const char *mode)
// CHECK: Loaded summary for: FILE *tmpfile(void)
// CHECK: Loaded summary for: FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream)
// CHECK: Loaded summary for: int fclose(FILE *stream)
Expand Down Expand Up @@ -78,7 +79,6 @@
// 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)
Expand Down
10 changes: 10 additions & 0 deletions clang/test/Analysis/stream-errno.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ void check_fopen(void) {
if (errno) {} // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}
}

void check_fdopen(int Fd) {
FILE *F = fdopen(Fd, "r");
if (!F) {
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
if (errno) {} // no-warning
} else {
if (errno) {} // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}
}
}

void check_tmpfile(void) {
FILE *F = tmpfile();
if (!F) {
Expand Down
1 change: 1 addition & 0 deletions clang/test/Analysis/stream-note.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ void check_note_freopen(void) {

void check_note_fdopen(int fd) {
FILE *F = fdopen(fd, "r"); // expected-note {{Stream opened here}}
// stdargs-note@-1 {{'fdopen' is successful}}
if (!F)
// expected-note@-1 {{'F' is non-null}}
// expected-note@-2 {{Taking false branch}}
Expand Down

0 comments on commit 0223230

Please sign in to comment.