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 <benn...@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); + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits