[clang] [analyzer] Avoid crashes in the stream checker (PR #100901)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 27 15:06:33 PDT 2024
https://github.com/vabridgers created https://github.com/llvm/llvm-project/pull/100901
This change avoids crashes in the stream checker when bifurcating the analysis state produces a non-null return value for opening a stream and does not produces a null return value because of constraints found during an analysis path.
A snippet of the crash stack seen is shown here.
...
#6 __restore_rt sigaction.c:0:0
#7 clang::ento::ProgramState::getStateManager() const
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h:148:13
#8 llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>
clang::ento::ProgramState::set<(anonymous namespace)::StreamMap>(clang::ento::ProgramStateTrait<(
anonymous namespace)::StreamMap>::key_type,clang::ento::ProgramStateTrait<(anonymous namespace)::StreamMap>::value_type) const
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h:864:10
#9 (anonymous namespace)::StreamChecker::evalFopen((anonymous namespace)::FnDescription const*,
clang::ento::CallEvent const&, clang::ento::CheckerContext&) const
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp:951:13
...
>From ab047fb7bd9ddc0f58d4652fe63c80738d60e8c4 Mon Sep 17 00:00:00 2001
From: Vince Bridgers <vince.a.bridgers at ericsson.com>
Date: Sat, 27 Jul 2024 23:41:17 +0200
Subject: [PATCH] [analyzer] Avoid crashes in the stream checker
This change avoids crashes in the stream checker when bifurcating the
analysis state produces a non-null return value for opening a stream and
does not produces a null return value because of constraints found
during an analysis path.
A snippet of the crash stack seen is shown here.
...
#6 __restore_rt sigaction.c:0:0
#7 clang::ento::ProgramState::getStateManager() const
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h:148:13
#8 llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>
clang::ento::ProgramState::set<(anonymous namespace)::StreamMap>(clang::ento::ProgramStateTrait<(
anonymous namespace)::StreamMap>::key_type,clang::ento::ProgramStateTrait<(anonymous namespace)::StreamMap>::value_type) const
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h:864:10
#9 (anonymous namespace)::StreamChecker::evalFopen((anonymous namespace)::FnDescription const*,
clang::ento::CallEvent const&, clang::ento::CheckerContext&) const
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp:951:13
...
---
.../StaticAnalyzer/Checkers/StreamChecker.cpp | 20 +++++++++------
clang/test/Analysis/stream-no-crash.c | 25 +++++++++++++++++++
2 files changed, 37 insertions(+), 8 deletions(-)
create mode 100644 clang/test/Analysis/stream-no-crash.c
diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 53770532609d5..c34c6b9fc6c0d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -946,14 +946,18 @@ void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent &Call,
std::tie(StateNotNull, StateNull) =
C.getConstraintManager().assumeDual(State, RetVal);
- StateNotNull =
- StateNotNull->set<StreamMap>(RetSym, StreamState::getOpened(Desc));
- StateNull =
- StateNull->set<StreamMap>(RetSym, StreamState::getOpenFailed(Desc));
-
- C.addTransition(StateNotNull,
- constructLeakNoteTag(C, RetSym, "Stream opened here"));
- C.addTransition(StateNull);
+ if (StateNotNull)
+ StateNotNull =
+ StateNotNull->set<StreamMap>(RetSym, StreamState::getOpened(Desc));
+ if (StateNull)
+ StateNull =
+ StateNull->set<StreamMap>(RetSym, StreamState::getOpenFailed(Desc));
+
+ if (StateNotNull)
+ C.addTransition(StateNotNull,
+ constructLeakNoteTag(C, RetSym, "Stream opened here"));
+ if (StateNull)
+ C.addTransition(StateNull);
}
void StreamChecker::preFreopen(const FnDescription *Desc, const CallEvent &Call,
diff --git a/clang/test/Analysis/stream-no-crash.c b/clang/test/Analysis/stream-no-crash.c
new file mode 100644
index 0000000000000..7a4922c8a35c2
--- /dev/null
+++ b/clang/test/Analysis/stream-no-crash.c
@@ -0,0 +1,25 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Stream -verify %s
+
+// This test is isolate since it uses line markers to repro the problem.
+// The test is expected to find the issues noted below without crashing.
+
+# 1 "" 1
+# 1 "" 1
+# 1 "" 1
+# 1 "" 1 3
+typedef FILE;
+extern *stdout;
+char a;
+*fopen();
+# 0 "" 2
+# 7 "" 2
+# 7 "" 2
+# 7 "" 2
+void b() {
+ fopen(&a, "");
+ int c = stdout && c;
+ b();
+}
+// expected-warning at -3{{Assigned value is garbage or undefined}}
+// expected-warning at -4{{Opened stream never closed. Potential resource leak}}
+
More information about the cfe-commits
mailing list