[clang] [clang][analyzer] Improve modeling of 'fseeko' and 'ftello' in StdLibraryFunctionsChecker (PR #77902)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 12 02:19:35 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Ben Shi (benshi001)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/77902.diff
2 Files Affected:
- (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+9-3)
- (modified) clang/test/Analysis/stream-errno.c (+32)
``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 3b36565681a7f3..f934444eb4bf48 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -2859,13 +2859,19 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
"fseeko",
Signature(ArgTypes{FilePtrTy, Off_tTy, IntTy}, RetType{IntTy}),
Summary(NoEvalCall)
- .Case(ReturnsZeroOrMinusOne, ErrnoIrrelevant)
- .ArgConstraint(NotNull(ArgNo(0))));
+ .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
+ .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
+ .ArgConstraint(NotNull(ArgNo(0)))
+ .ArgConstraint(ArgumentCondition(2, WithinRange, {{0, 2}})));
// off_t ftello(FILE *stream);
addToFunctionSummaryMap(
"ftello", Signature(ArgTypes{FilePtrTy}, RetType{Off_tTy}),
- Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
+ Summary(NoEvalCall)
+ .Case({ReturnValueCondition(WithinRange, Range(0, LongMax))},
+ ErrnoUnchanged, GenericSuccessMsg)
+ .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
+ .ArgConstraint(NotNull(ArgNo(0))));
// void *mmap(void *addr, size_t length, int prot, int flags, int fd,
// off_t offset);
diff --git a/clang/test/Analysis/stream-errno.c b/clang/test/Analysis/stream-errno.c
index f44ee6070708b2..bc184d5ce018d3 100644
--- a/clang/test/Analysis/stream-errno.c
+++ b/clang/test/Analysis/stream-errno.c
@@ -129,6 +129,7 @@ void check_fseek(void) {
int S = fseek(F, 11, SEEK_SET);
if (S != 0) {
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(S == -1); // expected-warning{{TRUE}}
if (errno) {} // no-warning
fclose(F);
return;
@@ -136,6 +137,21 @@ void check_fseek(void) {
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
}
+void check_fseeko(void) {
+ FILE *F = tmpfile();
+ if (!F)
+ return;
+ int S = fseeko(F, 11, SEEK_SET);
+ if (S == -1) {
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no-warning
+ } else {
+ clang_analyzer_eval(S == 0); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ }
+ fclose(F);
+}
+
void check_no_errno_change(void) {
FILE *F = tmpfile();
if (!F)
@@ -197,6 +213,22 @@ void check_ftell(void) {
fclose(F);
}
+void check_ftello(void) {
+ FILE *F = tmpfile();
+ if (!F)
+ return;
+ errno = 0;
+ off_t Ret = ftello(F);
+ if (Ret >= 0) {
+ clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}}
+ } else {
+ clang_analyzer_eval(Ret == -1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ }
+ if (errno) {} // no-warning
+ fclose(F);
+}
+
void check_rewind(void) {
FILE *F = tmpfile();
if (!F)
``````````
</details>
https://github.com/llvm/llvm-project/pull/77902
More information about the cfe-commits
mailing list