https://github.com/martinboehme created https://github.com/llvm/llvm-project/pull/78423
The CFG doesn't contain a CFGElement for the `CXXDefaultInitExpr::getInit()`, so it makes sense to consider the `CXXDefaultInitExpr` to be the expression that originally constructs the object. >From 2a8a351c364848d27b38f4f25ac99e6ba1aee424 Mon Sep 17 00:00:00 2001 From: Martin Braenne <mboe...@google.com> Date: Wed, 17 Jan 2024 10:31:19 +0000 Subject: [PATCH] [clang][dataflow] Consider `CXXDefaultInitExpr` to be an "original record ctor". The CFG doesn't contain a CFGElement for the `CXXDefaultInitExpr::getInit()`, so it makes sense to consider the `CXXDefaultInitExpr` to be the expression that originally constructs the object. --- .../FlowSensitive/DataflowEnvironment.cpp | 1 + .../Analysis/FlowSensitive/TransferTest.cpp | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index a50ee57a3c11b44..c3dfac24837c98b 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -747,6 +747,7 @@ static bool isOriginalRecordConstructor(const Expr &RecordPRValue) { return !Init->isSemanticForm() || !Init->isTransparent(); return isa<CXXConstructExpr>(RecordPRValue) || isa<CallExpr>(RecordPRValue) || isa<LambdaExpr>(RecordPRValue) || + isa<CXXDefaultInitExpr>(RecordPRValue) || // The framework currently does not propagate the objects created in // the two branches of a `ConditionalOperator` because there is no way // to reconcile their storage locations, which are different. We diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 056c4f3383d8322..d0a0e6d3f583641 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -2684,6 +2684,48 @@ TEST(TransferTest, ResultObjectLocation) { }); } +TEST(TransferTest, ResultObjectLocationForDefaultInitExpr) { + std::string Code = R"( + struct S {}; + struct target { + target () { + (void)0; + // [[p]] + } + S s = {}; + }; + )"; + + using ast_matchers::cxxCtorInitializer; + using ast_matchers::match; + using ast_matchers::selectFirst; + runDataflow( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + const ValueDecl *SField = findValueDecl(ASTCtx, "s"); + + auto *CtorInit = selectFirst<CXXCtorInitializer>( + "ctor_initializer", + match(cxxCtorInitializer().bind("ctor_initializer"), ASTCtx)); + ASSERT_NE(CtorInit, nullptr); + + auto *DefaultInit = cast<CXXDefaultInitExpr>(CtorInit->getInit()); + + RecordStorageLocation &Loc = Env.getResultObjectLocation(*DefaultInit); + + // FIXME: The result object location for the `CXXDefaultInitExpr` should + // be the location of the member variable being initialized, but we + // don't do this correctly yet; see also comments in + // `builtinTransferInitializer()`. + // For the time being, we just document the current erroneous behavior + // here (this should be `EXPECT_EQ` when the behavior is fixed). + EXPECT_NE(&Loc, Env.getThisPointeeStorageLocation()->getChild(*SField)); + }); +} + TEST(TransferTest, StaticCast) { std::string Code = R"( void target(int Foo) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits