[clang] Improve modeling of two functions in StdLibraryFunctionsChecker (PR #78079)
Ben Shi via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 16 01:01:27 PST 2024
https://github.com/benshi001 updated https://github.com/llvm/llvm-project/pull/78079
>From fd350eea466db33324f07e59469775e81479b33d Mon Sep 17 00:00:00 2001
From: Ben Shi <bennshi at tencent.com>
Date: Sun, 14 Jan 2024 12:44:45 +0800
Subject: [PATCH 1/2] [clang][analyzer] Improve modeling of two functions in
StdLibraryFunctionsChecker
Improve 'errno' modeling of 'opendir' and 'fdopendir'.
---
.../Checkers/StdLibraryFunctionsChecker.cpp | 19 +++++++++-------
.../Analysis/Inputs/system-header-simulator.h | 7 +++++-
clang/test/Analysis/stream-errno.c | 22 +++++++++++++++++++
3 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 3b36565681a7f33..2f05dd6997cfad8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -2772,18 +2772,21 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
.ArgConstraint(NotNull(ArgNo(2))));
// DIR *opendir(const char *name);
- // FIXME: Improve for errno modeling.
addToFunctionSummaryMap(
"opendir", Signature(ArgTypes{ConstCharPtrTy}, RetType{DirPtrTy}),
- Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
+ Summary(NoEvalCall)
+ .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
+ .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
+ .ArgConstraint(NotNull(ArgNo(0))));
// DIR *fdopendir(int fd);
- // FIXME: Improve for errno modeling.
- addToFunctionSummaryMap("fdopendir",
- Signature(ArgTypes{IntTy}, RetType{DirPtrTy}),
- Summary(NoEvalCall)
- .ArgConstraint(ArgumentCondition(
- 0, WithinRange, Range(0, IntMax))));
+ addToFunctionSummaryMap(
+ "fdopendir", Signature(ArgTypes{IntTy}, RetType{DirPtrTy}),
+ Summary(NoEvalCall)
+ .Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg)
+ .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
+ .ArgConstraint(
+ ArgumentCondition(0, WithinRange, Range(0, IntMax))));
// int isatty(int fildes);
addToFunctionSummaryMap(
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h
index cd7ac616bcc67fa..ba0e09ca77bc2af 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator.h
@@ -14,8 +14,9 @@ typedef long long __int64_t;
typedef __int64_t __darwin_off_t;
typedef __darwin_off_t fpos_t;
typedef int off_t;
-
typedef struct _FILE FILE;
+typedef struct _DIR DIR;
+
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
@@ -68,6 +69,10 @@ int ferror(FILE *stream);
int fileno(FILE *stream);
int fflush(FILE *stream);
+DIR *opendir(const char *name);
+DIR *fdopendir(int fd);
+int closedir(DIR *dir);
+
size_t strlen(const char *);
char *strcpy(char *restrict, const char *restrict);
diff --git a/clang/test/Analysis/stream-errno.c b/clang/test/Analysis/stream-errno.c
index f44ee6070708b26..f19109a3c0b481f 100644
--- a/clang/test/Analysis/stream-errno.c
+++ b/clang/test/Analysis/stream-errno.c
@@ -248,3 +248,25 @@ void check_fflush_all(void) {
if (errno) {} // no-warning
}
}
+
+void check_opendir(const char *Path) {
+ DIR *Dir = opendir(Path);
+ if (Dir == NULL) {
+ 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'}}
+ closedir(Dir);
+ }
+}
+
+void check_fdopendir(int Fd) {
+ DIR *Dir = fdopendir(Fd);
+ if (Dir == NULL) {
+ 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'}}
+ closedir(Dir);
+ }
+}
>From cf410b1d56747d5e292c3bf02c12df19f9aa03c5 Mon Sep 17 00:00:00 2001
From: Ben Shi <bennshi at tencent.com>
Date: Tue, 16 Jan 2024 17:01:04 +0800
Subject: [PATCH 2/2] [clang][analyzer] Improve modeling of two functions in
StdLibraryFunctionsChecker
---
.../Analysis/Inputs/system-header-simulator.h | 7 +-----
clang/test/Analysis/stream-errno.c | 22 -------------------
2 files changed, 1 insertion(+), 28 deletions(-)
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h
index ba0e09ca77bc2af..cd7ac616bcc67fa 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator.h
@@ -14,9 +14,8 @@ typedef long long __int64_t;
typedef __int64_t __darwin_off_t;
typedef __darwin_off_t fpos_t;
typedef int off_t;
-typedef struct _FILE FILE;
-typedef struct _DIR DIR;
+typedef struct _FILE FILE;
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
@@ -69,10 +68,6 @@ int ferror(FILE *stream);
int fileno(FILE *stream);
int fflush(FILE *stream);
-DIR *opendir(const char *name);
-DIR *fdopendir(int fd);
-int closedir(DIR *dir);
-
size_t strlen(const char *);
char *strcpy(char *restrict, const char *restrict);
diff --git a/clang/test/Analysis/stream-errno.c b/clang/test/Analysis/stream-errno.c
index f19109a3c0b481f..f44ee6070708b26 100644
--- a/clang/test/Analysis/stream-errno.c
+++ b/clang/test/Analysis/stream-errno.c
@@ -248,25 +248,3 @@ void check_fflush_all(void) {
if (errno) {} // no-warning
}
}
-
-void check_opendir(const char *Path) {
- DIR *Dir = opendir(Path);
- if (Dir == NULL) {
- 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'}}
- closedir(Dir);
- }
-}
-
-void check_fdopendir(int Fd) {
- DIR *Dir = fdopendir(Fd);
- if (Dir == NULL) {
- 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'}}
- closedir(Dir);
- }
-}
More information about the cfe-commits
mailing list