Skip to content

Commit

Permalink
[clang][dataflow] Consider CXXDefaultInitExpr to be an "original re…
Browse files Browse the repository at this point in the history
…cord ctor". (#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.
  • Loading branch information
martinboehme committed Jan 18, 2024
1 parent 1b1b525 commit f1226ee
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
1 change: 1 addition & 0 deletions clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
42 changes: 42 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit f1226ee

Please sign in to comment.