https://github.com/benshi001 created https://github.com/llvm/llvm-project/pull/78680
None >From 29b2f54387096951ecad53514251c4729d7c1947 Mon Sep 17 00:00:00 2001 From: Ben Shi <benn...@tencent.com> Date: Fri, 19 Jan 2024 16:08:30 +0800 Subject: [PATCH] [clang][analyzer] Improve modeling of 'fdopen' in StdLibraryFunctionsChecker --- .../Checkers/StdLibraryFunctionsChecker.cpp | 19 ++++++++++--------- .../Analysis/std-c-library-functions-POSIX.c | 2 +- clang/test/Analysis/stream-errno.c | 10 ++++++++++ clang/test/Analysis/stream-note.c | 1 + 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index 83f972c7072ec5..d0eb5091444f6b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -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}), @@ -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}), diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c index 8a26e0b0f27286..51b136d9ba3567 100644 --- a/clang/test/Analysis/std-c-library-functions-POSIX.c +++ b/clang/test/Analysis/std-c-library-functions-POSIX.c @@ -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) @@ -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) diff --git a/clang/test/Analysis/stream-errno.c b/clang/test/Analysis/stream-errno.c index 13981e9094d1c9..fab6a58b3275a8 100644 --- a/clang/test/Analysis/stream-errno.c +++ b/clang/test/Analysis/stream-errno.c @@ -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) { diff --git a/clang/test/Analysis/stream-note.c b/clang/test/Analysis/stream-note.c index e412015eb68393..abb4784c078aa8 100644 --- a/clang/test/Analysis/stream-note.c +++ b/clang/test/Analysis/stream-note.c @@ -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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits