[clang] [clang][analyzer] Implement modeling of 'fputc' in the StdLibraryFunctionsChecker (PR #77435)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 9 01:50:36 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/77435.diff
3 Files Affected:
- (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+14)
- (modified) clang/test/Analysis/Inputs/std-c-library-functions.h (+1)
- (modified) clang/test/Analysis/errno-stdlibraryfunctions.c (+14)
``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 034825d88a44de..f160c464dc273a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -2277,6 +2277,20 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
.Case({}, ErrnoMustBeChecked)
.ArgConstraint(NotNull(ArgNo(0))));
+ // int fputc(int c, FILE *stream);
+ addToFunctionSummaryMap(
+ "fputc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}),
+ Summary(NoEvalCall)
+ .Case({ArgumentCondition(0, WithinRange, Range(0, UCharRangeMax)),
+ ReturnValueCondition(BO_EQ, ArgNo(0))},
+ ErrnoMustNotBeChecked, GenericSuccessMsg)
+ .Case({ArgumentCondition(0, OutOfRange, Range(0, UCharRangeMax)),
+ ReturnValueCondition(WithinRange, Range(0, UCharRangeMax))},
+ ErrnoMustNotBeChecked, GenericSuccessMsg)
+ .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
+ ErrnoNEZeroIrrelevant, GenericFailureMsg)
+ .ArgConstraint(NotNull(ArgNo(1))));
+
// void clearerr(FILE *stream);
addToFunctionSummaryMap(
"clearerr", Signature(ArgTypes{FilePtrTy}, RetType{VoidTy}),
diff --git a/clang/test/Analysis/Inputs/std-c-library-functions.h b/clang/test/Analysis/Inputs/std-c-library-functions.h
index 7c86c359ee21de..6cb2d1be7a9b11 100644
--- a/clang/test/Analysis/Inputs/std-c-library-functions.h
+++ b/clang/test/Analysis/Inputs/std-c-library-functions.h
@@ -37,6 +37,7 @@ int toascii(int);
int getc(FILE *);
int fgetc(FILE *);
+int fputc(int c, FILE *stream);
int getchar(void);
size_t fread(void *restrict, size_t, size_t, FILE *restrict);
size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
diff --git a/clang/test/Analysis/errno-stdlibraryfunctions.c b/clang/test/Analysis/errno-stdlibraryfunctions.c
index 9e3d07e7aa88a0..9ece662a937072 100644
--- a/clang/test/Analysis/errno-stdlibraryfunctions.c
+++ b/clang/test/Analysis/errno-stdlibraryfunctions.c
@@ -89,3 +89,17 @@ void errno_getcwd(char *Buf, size_t Sz) {
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
}
}
+
+void errno_fputc(int C, FILE *Fp) {
+ int Ret = fputc(C, Fp);
+ if (Ret == EOF) {
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no warning
+ } else if (C >= 0 && C <= 255) {
+ clang_analyzer_eval(Ret == C); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ } else {
+ clang_analyzer_eval(Ret != C); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ }
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/77435
More information about the cfe-commits
mailing list