Skip to content

Commit

Permalink
[clang][dataflow] Assign aggregate storage locations to union stmts
Browse files Browse the repository at this point in the history
This patch ensures that the dataflow analysis framework does not crash
when it encounters access to members of union types.

This is part of the implementation of the dataflow analysis framework.
See "[RFC] A dataflow analysis framework for Clang AST" on cfe-dev.

Reviewed-by: xazax.hun

Differential Revision: https://reviews.llvm.org/D118226
  • Loading branch information
sgatev committed Jan 26, 2022
1 parent e9b4239 commit 188d28f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
2 changes: 1 addition & 1 deletion clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Expand Up @@ -100,7 +100,7 @@ LatticeJoinEffect Environment::join(const Environment &Other) {

StorageLocation &Environment::createStorageLocation(QualType Type) {
assert(!Type.isNull());
if (Type->isStructureOrClassType()) {
if (Type->isStructureOrClassType() || Type->isUnionType()) {
// FIXME: Explore options to avoid eager initialization of fields as some of
// them might not be needed for a particular analysis.
llvm::DenseMap<const ValueDecl *, StorageLocation *> FieldLocs;
Expand Down
33 changes: 33 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Expand Up @@ -1952,4 +1952,37 @@ TEST_F(TransferTest, AggregateInitialization) {
}
}

TEST_F(TransferTest, AssignToUnionMember) {
std::string Code = R"(
union A {
int Foo;
};
void target(int Bar) {
A Baz;
Baz.Foo = Bar;
// [[p]]
}
)";
runDataflow(Code,
[](llvm::ArrayRef<
std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
Results,
ASTContext &ASTCtx) {
ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
const Environment &Env = Results[0].second.Env;

const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz");
ASSERT_THAT(BazDecl, NotNull());
ASSERT_TRUE(BazDecl->getType()->isUnionType());

const auto *BazLoc = dyn_cast_or_null<AggregateStorageLocation>(
Env.getStorageLocation(*BazDecl, SkipPast::None));
ASSERT_THAT(BazLoc, NotNull());

// FIXME: Add support for union types.
EXPECT_THAT(Env.getValue(*BazLoc), IsNull());
});
}

} // namespace

0 comments on commit 188d28f

Please sign in to comment.