Skip to content

Commit

Permalink
[clang][dataflow] fix bug for transparent ListInitExpr handling
Browse files Browse the repository at this point in the history
This fixes the handling of "transparent" ListInitExpr, when they're only
used as a copy constructor for records.

Without the fix, the two tests are crashing the process.
  • Loading branch information
paulsemel committed Jul 26, 2023
1 parent ebaac2b commit bc37893
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
7 changes: 7 additions & 0 deletions clang/lib/Analysis/FlowSensitive/Transfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,13 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
return;
}

// In case the initializer list is transparent, we just need to propagate
// the value that it contains.
if (S->isSemanticForm() && S->isTransparent()) {
propagateValue(*S->getInit(0), *S, Env);
return;
}

std::vector<FieldDecl *> Fields =
getFieldsForInitListExpr(Type->getAsRecordDecl());
llvm::DenseMap<const ValueDecl *, StorageLocation *> FieldLocs;
Expand Down
33 changes: 33 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2183,6 +2183,39 @@ TEST(TransferTest, CopyConstructorWithParens) {
});
}

TEST(TransferTest, CopyConstructorWithInitializerListAsSyntacticSugar) {
std::string Code = R"(
struct A {
int Baz;
};
void target() {
A Foo = {3};
(void)Foo.Baz;
A Bar = {A(Foo)};
// [[p]]
}
)";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");

const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz");

const auto &FooLoc =
getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "Foo");
const auto &BarLoc =
getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "Bar");

const auto *FooBazVal =
cast<IntegerValue>(getFieldValue(&FooLoc, *BazDecl, Env));
const auto *BarBazVal =
cast<IntegerValue>(getFieldValue(&BarLoc, *BazDecl, Env));
EXPECT_EQ(FooBazVal, BarBazVal);
});
}

TEST(TransferTest, CopyConstructorArgIsRefReturnedByFunction) {
// This is a crash repro.
std::string Code = R"(
Expand Down

0 comments on commit bc37893

Please sign in to comment.