[clang] ff05c30 - [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (#78895)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 26 17:46:09 PST 2024
Author: Ben Shi
Date: 2024-01-27T09:46:05+08:00
New Revision: ff05c3087b4b7e0121125d7f6860b3d9383ca91d
URL: https://github.com/llvm/llvm-project/commit/ff05c3087b4b7e0121125d7f6860b3d9383ca91d
DIFF: https://github.com/llvm/llvm-project/commit/ff05c3087b4b7e0121125d7f6860b3d9383ca91d.diff
LOG: [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (#78895)
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
clang/test/Analysis/Inputs/system-header-simulator.h
clang/test/Analysis/errno-stdlibraryfunctions.c
clang/test/Analysis/std-c-library-functions-POSIX.c
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 61bf3c8528be2b3..be26f5521c8d769 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -2204,6 +2204,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
.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}),
@@ -2212,6 +2222,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
.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))));
+
// int ungetc(int c, FILE *stream);
addToFunctionSummaryMap(
"ungetc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}),
@@ -2827,21 +2846,6 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
.ArgConstraint(
ArgumentCondition(0, WithinRange, Range(0, IntMax))));
- // FILE *popen(const char *command, const char *type);
- // FIXME: Improve for errno modeling.
- addToFunctionSummaryMap(
- "popen",
- Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}),
- Summary(NoEvalCall)
- .ArgConstraint(NotNull(ArgNo(0)))
- .ArgConstraint(NotNull(ArgNo(1))));
-
- // int pclose(FILE *stream);
- // FIXME: Improve for errno modeling.
- addToFunctionSummaryMap(
- "pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}),
- Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
-
// int close(int fildes);
addToFunctionSummaryMap(
"close", Signature(ArgTypes{IntTy}, RetType{IntTy}),
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h
index 96072741a8abc13..15986984802c0e6 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator.h
@@ -48,7 +48,9 @@ FILE *fopen(const char *restrict path, const char *restrict mode);
FILE *fdopen(int fd, const char *mode);
FILE *tmpfile(void);
FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream);
+FILE *popen(const char *command, const char *mode);
int fclose(FILE *fp);
+int pclose(FILE *stream);
size_t fread(void *restrict, size_t, size_t, FILE *restrict);
size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
int fgetc(FILE *stream);
diff --git a/clang/test/Analysis/errno-stdlibraryfunctions.c b/clang/test/Analysis/errno-stdlibraryfunctions.c
index 7876bafc2eb2109..9b487fed0a2eb8d 100644
--- a/clang/test/Analysis/errno-stdlibraryfunctions.c
+++ b/clang/test/Analysis/errno-stdlibraryfunctions.c
@@ -103,3 +103,28 @@ void errno_execvp(char *File, char * Argv[]) {
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
if (errno) {} // no warning
}
+
+void errno_popen(void) {
+ FILE *F = popen("xxx", "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]}}
+ pclose(F);
+ }
+}
+
+void errno_pclose(void) {
+ FILE *F = popen("xx", "w");
+ if (!F)
+ return;
+ int Ret = pclose(F);
+ if (Ret == -1) {
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no-warning
+ } else {
+ clang_analyzer_eval(Ret >= 0); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ }
+}
diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c
index 51b136d9ba35673..03aa8e2e00a75dd 100644
--- a/clang/test/Analysis/std-c-library-functions-POSIX.c
+++ b/clang/test/Analysis/std-c-library-functions-POSIX.c
@@ -20,7 +20,9 @@
// 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: FILE *popen(const char *command, const char *type)
// CHECK: Loaded summary for: int fclose(FILE *stream)
+// CHECK: Loaded summary for: int pclose(FILE *stream)
// CHECK: Loaded summary for: int fseek(FILE *stream, long offset, int whence)
// CHECK: Loaded summary for: int fseeko(FILE *stream, off_t offset, int whence)
// CHECK: Loaded summary for: off_t ftello(FILE *stream)
@@ -74,8 +76,6 @@
// 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)
More information about the cfe-commits
mailing list