[clang] [clang][analyzer] Support `fflush` in the StreamChecker (PR #74296)
Alejandro Álvarez Ayllón via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 7 03:02:44 PST 2023
================
@@ -1191,6 +1199,84 @@ void StreamChecker::evalSetFeofFerror(const FnDescription *Desc,
C.addTransition(State);
}
+void StreamChecker::preFflush(const FnDescription *Desc, const CallEvent &Call,
+ CheckerContext &C) const {
+ ProgramStateRef State = C.getState();
+ SVal StreamVal = getStreamArg(Desc, Call);
+ std::optional<DefinedSVal> Stream = StreamVal.getAs<DefinedSVal>();
+ SymbolRef StreamSym = StreamVal.getAsSymbol();
+ if (!Stream || !StreamSym)
+ return;
+
+ ProgramStateRef StateNotNull, StateNull;
+ std::tie(StateNotNull, StateNull) =
+ C.getConstraintManager().assumeDual(State, *Stream);
+ if (StateNotNull)
+ if (State = ensureStreamOpened(StreamVal, C, StateNotNull))
+ C.addTransition(State);
+ if (StateNull) {
----------------
alejandro-alvarez-sonarsource wrote:
Due to this transition, these two test cases will behave differently:
```cpp
void test_fflush_2(FILE *F1) {
fflush(F1);
// Due to fflush, the analyzer follows a path where F1 is NULL, and another where it isn't.
// Raises a "Stream pointer might be NULL" on the next line
if (fwrite("1", 1, 1, F1) == 0)
return;
fclose(F1);
}
void test_fflush_3(FILE *F1) {
// no fflush, the warning does not raise
if (fwrite("1", 1, 1, F1) == 0)
return;
fclose(F1);
}
```
I feel this could be noisy. What do you think about adding the StateNull transition if, and only if, FILE* can be `NULL`?
https://github.com/llvm/llvm-project/pull/74296
More information about the cfe-commits
mailing list