[clang] [clang][dataflow] Consider `CXXDefaultInitExpr` to be an "original record ctor". (PR #78423)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 17 02:33:40 PST 2024
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 <mboehme at 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) {
More information about the cfe-commits
mailing list