[llvm-branch-commits] [clang] [clang][ssaf][NFC] Add unittests for PointerFlow and UnsafeBufferUsage about local entities (PR #209227)
Balázs Benics via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Jul 13 08:46:31 PDT 2026
https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/209227
Part §6 of rdar://179151023
Depends on #209225.
Approved in #205351.
>From 56e713c6d610a3b7d6821c51022ffd27bc4d0a0c Mon Sep 17 00:00:00 2001
From: Jan Korous <jkorous at apple.com>
Date: Tue, 12 May 2026 18:39:13 -0700
Subject: [PATCH] [clang][ssaf][NFC] Add unittests for PointerFlow and
UnsafeBufferUsage about local entities
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Part §6 of rdar://179151023
Co-Authored-By: Jan Korous <jkorous at apple.com>
Co-Authored-By: Claude Opus 4.7 <noreply at anthropic.com>
---
.../Analyses/PointerFlow/PointerFlowTest.cpp | 47 ++++++++++++++++++-
.../UnsafeBufferUsageTest.cpp | 47 ++++++++++++++++++-
2 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/clang/unittests/ScalableStaticAnalysis/Analyses/PointerFlow/PointerFlowTest.cpp b/clang/unittests/ScalableStaticAnalysis/Analyses/PointerFlow/PointerFlowTest.cpp
index b6d2b8b1af3cf..a56a9072be097 100644
--- a/clang/unittests/ScalableStaticAnalysis/Analyses/PointerFlow/PointerFlowTest.cpp
+++ b/clang/unittests/ScalableStaticAnalysis/Analyses/PointerFlow/PointerFlowTest.cpp
@@ -161,7 +161,8 @@ class PointerFlowTest : public TestFixture {
template <typename ContributorDecl = NamedDecl,
typename =
std::enable_if_t<std::is_base_of_v<NamedDecl, ContributorDecl>>>
- bool setUpTest(StringRef Code) {
+ bool setUpTest(StringRef Code, const SSAFOptions &Opts = {}) {
+ this->Opts = Opts; // Override the options.
AST = tooling::buildASTFromCodeWithArgs(
Code, {"-Wno-unused-value", "-Wno-int-to-pointer-cast"});
@@ -1573,4 +1574,48 @@ TEST_F(PointerFlowTest, RefBindFunctionCallInitializer) {
EXPECT_EQ(*Sum, makeEdges(__LINE__, {{{"r", 1U}, {"g", 1U, true}}}));
}
+//////////////////////////////////////////////////////////////
+// Local-entity inclusion option tests //
+//////////////////////////////////////////////////////////////
+
+TEST_F(PointerFlowTest, LocalPointerSkippedByDefault) {
+ StringRef Code = R"cpp(
+ void foo(int *param) {
+ int *local_ptr = param;
+ local_ptr = param;
+ }
+ )cpp";
+
+ ASSERT_TRUE(setUpTest(Code));
+
+ // Without IncludeLocalEntities, the local pointer is not registered as a
+ // contributor and therefore has no entity summary of its own.
+ EXPECT_FALSE(getEntitySummary<VarDecl>("local_ptr"));
+ // The enclosing function still has its summary describing the assignment
+ // edge from `local_ptr` to `param` (via the initializer).
+ EXPECT_TRUE(getEntitySummary("foo"));
+}
+
+TEST_F(PointerFlowTest, LocalPointerReportedWhenIncluded) {
+ SSAFOptions Opts;
+ Opts.IncludeLocalEntities = true;
+ StringRef Code = R"cpp(
+ void foo(int *param) {
+ int *local_ptr = param;
+ local_ptr = param;
+ }
+ )cpp";
+
+ ASSERT_TRUE(setUpTest(Code, Opts));
+
+ // With the option enabled, the local pointer becomes a contributor and gets
+ // its own entity summary describing the same edge that was previously only
+ // observable through `foo`.
+ const auto *LocalSum = getEntitySummary<VarDecl>("local_ptr");
+ ASSERT_TRUE(LocalSum);
+ EXPECT_EQ(*LocalSum,
+ makeEdges(__LINE__, {{{"local_ptr", 1U}, {"param", 1U}}}));
+
+ EXPECT_TRUE(getEntitySummary("foo"));
+}
} // namespace
diff --git a/clang/unittests/ScalableStaticAnalysis/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp b/clang/unittests/ScalableStaticAnalysis/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp
index c2f4cb97c0fae..6d47bff85a059 100644
--- a/clang/unittests/ScalableStaticAnalysis/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp
+++ b/clang/unittests/ScalableStaticAnalysis/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp
@@ -47,7 +47,8 @@ class UnsafeBufferUsageTest : public TestFixture {
BuildNamespace(BuildNamespaceKind::CompilationUnit, "Mock.cpp")),
Builder(TUSum, Opts) {}
- bool setUpTest(StringRef Code) {
+ bool setUpTest(StringRef Code, const SSAFOptions &Opts = {}) {
+ this->Opts = Opts; // Override the options.
AST = tooling::buildASTFromCodeWithArgs(
Code, {"-Wno-unused-value", "-Wno-int-to-pointer-cast"});
@@ -779,5 +780,49 @@ TEST_F(UnsafeBufferUsageTest, StmtExprArrayAccess) {
.contains("attempt to translate StmtExpr to EntityPointerLevels"));
}
#endif
+//////////////////////////////////////////////////////////////
+// Local-entity inclusion option tests //
+//////////////////////////////////////////////////////////////
+
+TEST_F(UnsafeBufferUsageTest, LocalVarSkippedByDefault) {
+ // The unsafe subscript p[5] sits inside a local-variable initializer.
+ // Without IncludeLocalEntities, only `use` (the enclosing function) is a
+ // contributor. The initializer is still walked as part of `use`'s body, so
+ // `use` gets a summary attributing the unsafe usage to its parameter.
+ ASSERT_TRUE(setUpTest(R"cpp(
+ int use(int *param) {
+ int x = param[5];
+ return x;
+ }
+ )cpp"));
+
+ EXPECT_TRUE(getEntitySummary("use"));
+ // `x` is not a contributor and therefore has no entity summary of its own.
+ EXPECT_FALSE(getEntitySummary<VarDecl>("x"));
+}
+
+TEST_F(UnsafeBufferUsageTest, LocalVarReportedWhenIncluded) {
+ // With IncludeLocalEntities, the local var `x` becomes its own contributor.
+ // The matcher then walks `x`'s scope (the initializer) and reports the
+ // unsafe subscript on `param` against `x` as well.
+ SSAFOptions Opts;
+ Opts.IncludeLocalEntities = true;
+ ASSERT_TRUE(setUpTest(R"cpp(
+ int use(int *param) {
+ int x = param[5];
+ return x;
+ }
+ )cpp",
+ Opts));
+
+ // Pre-existing per-function summary is still produced.
+ EXPECT_TRUE(getEntitySummary("use"));
+
+ // The new local-entity summary describes the same unsafe-pointer usage,
+ // but is attributed to the local variable's own scope.
+ const auto *LocalSum = getEntitySummary<VarDecl>("x");
+ ASSERT_TRUE(LocalSum);
+ EXPECT_EQ(*LocalSum, makeSet(__LINE__, {{"param", 1U}}));
+}
} // namespace
More information about the llvm-branch-commits
mailing list