From 188d28f73cc7b7891c182a85fdb6e274123b5b69 Mon Sep 17 00:00:00 2001 From: Stanislav Gatev Date: Wed, 26 Jan 2022 09:15:07 +0000 Subject: [PATCH] [clang][dataflow] Assign aggregate storage locations to union stmts 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 --- .../Analysis/FlowSensitive/DataflowEnvironment.cpp | 2 +- .../Analysis/FlowSensitive/TransferTest.cpp | 33 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 6fbc3ec..512e3d9 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -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 FieldLocs; diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index cd3e582..0f7ac3a 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -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>> + 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( + Env.getStorageLocation(*BazDecl, SkipPast::None)); + ASSERT_THAT(BazLoc, NotNull()); + + // FIXME: Add support for union types. + EXPECT_THAT(Env.getValue(*BazLoc), IsNull()); + }); +} + } // namespace -- 2.7.4