[clang] Improve modeling of 'opendir' and 'fdopendir' in StdLibraryFunctionsChecker (PR #78079)
Ben Shi via cfe-commits
cfe-commits at lists.llvm.org
Sat Jan 13 20:53:54 PST 2024
https://github.com/benshi001 created https://github.com/llvm/llvm-project/pull/78079
None
>From 2b3d2800be52fb28246c2b51fad7eafc106e3e20 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] Improve modeling of 'opendir' and 'fdopendir' in
StdLibraryFunctionsChecker
---
.../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 3b36565681a7f3..2f05dd6997cfad 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 cd7ac616bcc67f..ba0e09ca77bc2a 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 f44ee6070708b2..f19109a3c0b481 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);
+ }
+}
More information about the cfe-commits
mailing list