[clang] [clang][analyzer] Improve modeling of 'fdopen' in StdLibraryFunctionsChecker (PR #78680)
Ben Shi via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 19 00:09:48 PST 2024
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 <bennshi at 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 at -1 {{'fdopen' is successful}}
if (!F)
// expected-note at -1 {{'F' is non-null}}
// expected-note at -2 {{Taking false branch}}
More information about the cfe-commits
mailing list