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.rie...@gmail.com> Date: Fri, 19 Jul 2024 08:34:14 +0000 Subject: [PATCH 1/2] [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.rie...@gmail.com> Date: Wed, 24 Jul 2024 15:26:29 +0000 Subject: [PATCH 2/2] 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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits