sgatev created this revision. sgatev added reviewers: ymandel, xazax.hun, gribozavr2. Herald added subscribers: tschuett, steakhal, rnkovacs. sgatev requested review of this revision. Herald added a project: clang.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D118226 Files: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp clang/unittests/Analysis/FlowSensitive/TransferTest.cpp Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp =================================================================== --- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -1952,4 +1952,37 @@ } } +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 Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -100,7 +100,7 @@ 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;
Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp =================================================================== --- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -1952,4 +1952,37 @@ } } +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 Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -100,7 +100,7 @@ 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;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits