llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Balázs Benics (steakhal) <details> <summary>Changes</summary> Part §6 of rdar://179151023 Depends on #<!-- -->209225. Approved in #<!-- -->205351. --- Full diff: https://github.com/llvm/llvm-project/pull/209227.diff 2 Files Affected: - (modified) clang/unittests/ScalableStaticAnalysis/Analyses/PointerFlow/PointerFlowTest.cpp (+46-1) - (modified) clang/unittests/ScalableStaticAnalysis/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp (+46-1) ``````````diff 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 `````````` </details> https://github.com/llvm/llvm-project/pull/209227 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
