[clang] [clang][dataflow] Don't propagate result objects in nested declarations. (PR #89903)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 24 06:07:35 PDT 2024
https://github.com/martinboehme updated https://github.com/llvm/llvm-project/pull/89903
>From 0ed905fc227bc58f3ae8f5ead856bba7e8376e3c Mon Sep 17 00:00:00 2001
From: Martin Braenne <mboehme at google.com>
Date: Wed, 24 Apr 2024 09:41:18 +0000
Subject: [PATCH 1/2] [clang][dataflow] Don't propagate result objects in
nested declarations.
Trying to do so can cause crashes -- see newly added test and the comments in
the fix.
---
.../FlowSensitive/DataflowEnvironment.cpp | 12 ++++++++++
.../Analysis/FlowSensitive/TransferTest.cpp | 22 +++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 3cb656adcbdc0c..aec8ee6a4a07fc 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -333,6 +333,18 @@ class ResultObjectVisitor : public RecursiveASTVisitor<ResultObjectVisitor> {
}
}
+ bool TraverseDecl(Decl *D) {
+ // Don't traverse nested record or function declarations.
+ // - We won't be analyzing code contained in these anyway
+ // - We don't model fields that are used only in these nested declaration,
+ // so trying to propagate a result object to initializers of such fields
+ // would cause an error.
+ if (isa<RecordDecl>(D) || isa<FunctionDecl>(D))
+ return true;
+
+ return RecursiveASTVisitor<ResultObjectVisitor>::TraverseDecl(D);
+ }
+
bool TraverseBindingDecl(BindingDecl *BD) {
// `RecursiveASTVisitor` doesn't traverse holding variables for
// `BindingDecl`s by itself, so we need to tell it to.
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 215e208615ac23..5c7c39e52612ec 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3309,6 +3309,28 @@ TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
});
}
+TEST(TransferTest, ResultObjectLocationDontVisitNestedRecordDecl) {
+ // This is a crash repro.
+ // We used to crash because when propagating result objects, we would visit
+ // nested record and function declarations, but we don't model fields used
+ // only in these.
+ std::string Code = R"(
+ struct S1 {};
+ struct S2 { S1 s1; };
+ void target() {
+ struct Nested {
+ void f() {
+ S2 s2 = { S1() };
+ }
+ };
+ }
+ )";
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {});
+}
+
TEST(TransferTest, StaticCast) {
std::string Code = R"(
void target(int Foo) {
>From 21dead242d19077052d495b03d641854109ddcbb Mon Sep 17 00:00:00 2001
From: Martin Braenne <mboehme at google.com>
Date: Wed, 24 Apr 2024 13:07:13 +0000
Subject: [PATCH 2/2] fixup! [clang][dataflow] Don't propagate result objects
in nested declarations.
---
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index aec8ee6a4a07fc..636d2302093983 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -339,7 +339,7 @@ class ResultObjectVisitor : public RecursiveASTVisitor<ResultObjectVisitor> {
// - We don't model fields that are used only in these nested declaration,
// so trying to propagate a result object to initializers of such fields
// would cause an error.
- if (isa<RecordDecl>(D) || isa<FunctionDecl>(D))
+ if (isa_and_nonnull<RecordDecl>(D) || isa_and_nonnull<FunctionDecl>(D))
return true;
return RecursiveASTVisitor<ResultObjectVisitor>::TraverseDecl(D);
More information about the cfe-commits
mailing list