Skip to content

Commit

Permalink
[clang][dataflow] Fix wrong assert for CXXConstructExpr
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D144546
  • Loading branch information
paulsemel committed Feb 24, 2023
1 parent 385c8cd commit e6e753d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
4 changes: 3 additions & 1 deletion clang/lib/Analysis/FlowSensitive/Transfer.cpp
Expand Up @@ -561,7 +561,9 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
assert(ConstructorDecl != nullptr);

if (ConstructorDecl->isCopyOrMoveConstructor()) {
assert(S->getNumArgs() == 1);
// It is permissible for a copy/move constructor to have additional
// parameters as long as they have default arguments defined for them.
assert(S->getNumArgs() != 0);

const Expr *Arg = S->getArg(0);
assert(Arg != nullptr);
Expand Down
48 changes: 48 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Expand Up @@ -2102,6 +2102,54 @@ TEST(TransferTest, CopyConstructor) {
});
}

TEST(TransferTest, CopyConstructorWithDefaultArgument) {
std::string Code = R"(
struct A {
int Baz;
A() = default;
A(const A& a, bool def = true) { Baz = a.Baz; }
};
void target() {
A Foo;
(void)Foo.Baz;
A Bar = Foo;
// [[p]]
}
)";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");

const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
ASSERT_THAT(FooDecl, NotNull());

const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
ASSERT_THAT(BarDecl, NotNull());

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

const auto *FooLoc = cast<AggregateStorageLocation>(
Env.getStorageLocation(*FooDecl, SkipPast::None));
const auto *BarLoc = cast<AggregateStorageLocation>(
Env.getStorageLocation(*BarDecl, SkipPast::None));

const auto *FooVal = cast<StructValue>(Env.getValue(*FooLoc));
const auto *BarVal = cast<StructValue>(Env.getValue(*BarLoc));
EXPECT_EQ(FooVal, BarVal);

const auto *FooBazVal =
cast<IntegerValue>(Env.getValue(FooLoc->getChild(*BazDecl)));
const auto *BarBazVal =
cast<IntegerValue>(Env.getValue(BarLoc->getChild(*BazDecl)));
EXPECT_EQ(FooBazVal, BarBazVal);
});
}

TEST(TransferTest, CopyConstructorWithParens) {
std::string Code = R"(
struct A {
Expand Down

0 comments on commit e6e753d

Please sign in to comment.