[clang] [clang][dataflow] Handle CXXInheritedCtorInitExpr in ResultObjectVisitor. (PR #99616)
Pasquale Riello via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 24 11:40:44 PDT 2024
https://github.com/Pask00 updated https://github.com/llvm/llvm-project/pull/99616
>From 0c26f09117baa36308bf58fed0ac40794b04ce74 Mon Sep 17 00:00:00 2001
From: Pasquale Riello <pas.riello at gmail.com>
Date: Fri, 19 Jul 2024 08:34:14 +0000
Subject: [PATCH 1/3] [clang][dataflow] Handle CXXInheritedCtorInitExpr in
ResultObjectVisitor.
`CXXInheritedCtorInitExpr` is another of the node kinds that should be considered an "original initializer". An assertion failure in `assert(Children.size() == 1)` happens without this fix.
---
.../FlowSensitive/DataflowEnvironment.cpp | 2 +-
.../FlowSensitive/DataflowEnvironmentTest.cpp | 40 +++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f734168e647bd..3307981ce7e0f 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -416,7 +416,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
// below them can initialize the same object (or part of it).
if (isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || isa<LambdaExpr>(E) ||
isa<CXXDefaultArgExpr>(E) || isa<CXXStdInitializerListExpr>(E) ||
- isa<AtomicExpr>(E) ||
+ isa<AtomicExpr>(E) || isa<CXXInheritedCtorInitExpr>(E) ||
// We treat `BuiltinBitCastExpr` as an "original initializer" too as
// it may not even be casting from a record type -- and even if it is,
// the two objects are in general of unrelated type.
diff --git a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
index a4ac597bb06d6..8481026f7c1fc 100644
--- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
@@ -442,6 +442,46 @@ TEST_F(EnvironmentTest, CXXDefaultInitExprResultObjIsWrappedExprResultObj) {
&Env.getResultObjectLocation(*DefaultInit->getExpr()));
}
+TEST_F(EnvironmentTest, ResultObjectLocationForInheritedCtorInitExpr) {
+ using namespace ast_matchers;
+
+ std::string Code = R"(
+ struct Base {
+ Base(int b) {}
+ };
+ struct Derived : Base {
+ using Base::Base;
+ };
+
+ Derived d = Derived(0);
+ )";
+
+ auto Unit =
+ tooling::buildASTFromCodeWithArgs(Code, {"-fsyntax-only", "-std=c++20"});
+ auto &Context = Unit->getASTContext();
+
+ ASSERT_EQ(Context.getDiagnostics().getClient()->getNumErrors(), 0U);
+
+ auto Results =
+ match(cxxConstructorDecl(
+ hasAnyConstructorInitializer(cxxCtorInitializer(
+ withInitializer(expr().bind("inherited_ctor_init_expr")))))
+ .bind("ctor"),
+ Context);
+ const auto *Constructor = selectFirst<CXXConstructorDecl>("ctor", Results);
+ const auto *InheritedCtorInit =
+ selectFirst<CXXInheritedCtorInitExpr>("inherited_ctor_init_expr", Results);
+
+ // Verify that `inherited_ctor_init_expr` has no children.
+ ASSERT_EQ(InheritedCtorInit->child_begin(), InheritedCtorInit->child_end());
+
+ Environment Env(DAContext, *Constructor);
+ Env.initialize();
+
+ RecordStorageLocation &Loc = Env.getResultObjectLocation(*InheritedCtorInit);
+ ASSERT_NE(&Loc, nullptr);
+}
+
TEST_F(EnvironmentTest, Stmt) {
using namespace ast_matchers;
>From 0ab95a138b885f0eb5d7ef3ff171d1488facd0e5 Mon Sep 17 00:00:00 2001
From: Pasquale Riello <pas.riello at gmail.com>
Date: Wed, 24 Jul 2024 15:26:29 +0000
Subject: [PATCH 2/3] Update test and add comment
---
.../FlowSensitive/DataflowEnvironmentTest.cpp | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
index 8481026f7c1fc..90569e8e4418b 100644
--- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
@@ -442,6 +442,14 @@ TEST_F(EnvironmentTest, CXXDefaultInitExprResultObjIsWrappedExprResultObj) {
&Env.getResultObjectLocation(*DefaultInit->getExpr()));
}
+// This test verifies the behavior of `getResultObjectLocation()` in
+// scenarios involving inherited constructors.
+// Since the specific AST node of interest `CXXConstructorDecl` is implicitly
+// generated, we cannot annotate any statements inside of it as we do in tests
+// within TransferTest. Thus, the only way to get the right `Environment` is by
+// explicitly initializing it as we do in tests within EnvironmentTest.
+// This is why this test is not inside TransferTest, where most of the tests for
+// `getResultObjectLocation()` are located.
TEST_F(EnvironmentTest, ResultObjectLocationForInheritedCtorInitExpr) {
using namespace ast_matchers;
@@ -469,17 +477,18 @@ TEST_F(EnvironmentTest, ResultObjectLocationForInheritedCtorInitExpr) {
.bind("ctor"),
Context);
const auto *Constructor = selectFirst<CXXConstructorDecl>("ctor", Results);
- const auto *InheritedCtorInit =
- selectFirst<CXXInheritedCtorInitExpr>("inherited_ctor_init_expr", Results);
+ const auto *InheritedCtorInit = selectFirst<CXXInheritedCtorInitExpr>(
+ "inherited_ctor_init_expr", Results);
- // Verify that `inherited_ctor_init_expr` has no children.
- ASSERT_EQ(InheritedCtorInit->child_begin(), InheritedCtorInit->child_end());
+ EXPECT_EQ(InheritedCtorInit->child_begin(), InheritedCtorInit->child_end());
Environment Env(DAContext, *Constructor);
Env.initialize();
RecordStorageLocation &Loc = Env.getResultObjectLocation(*InheritedCtorInit);
- ASSERT_NE(&Loc, nullptr);
+ EXPECT_NE(&Loc, nullptr);
+
+ ASSERT_EQ(&Loc, Env.getThisPointeeStorageLocation());
}
TEST_F(EnvironmentTest, Stmt) {
>From b1fd17bd0c3b529c99f09f482b2da58185fb6ce6 Mon Sep 17 00:00:00 2001
From: Pasquale Riello <pas.riello at gmail.com>
Date: Wed, 24 Jul 2024 19:40:36 +0100
Subject: [PATCH 3/3] Update test
Co-authored-by: martinboehme <mboehme at google.com>
---
.../Analysis/FlowSensitive/DataflowEnvironmentTest.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
index 90569e8e4418b..f09ee68ada1d5 100644
--- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
@@ -488,7 +488,7 @@ TEST_F(EnvironmentTest, ResultObjectLocationForInheritedCtorInitExpr) {
RecordStorageLocation &Loc = Env.getResultObjectLocation(*InheritedCtorInit);
EXPECT_NE(&Loc, nullptr);
- ASSERT_EQ(&Loc, Env.getThisPointeeStorageLocation());
+ EXPECT_EQ(&Loc, Env.getThisPointeeStorageLocation());
}
TEST_F(EnvironmentTest, Stmt) {
More information about the cfe-commits
mailing list