From 169e1aba55bed9f7ffa000f9f170ab2defbc40b2 Mon Sep 17 00:00:00 2001 From: Stanislav Gatev Date: Wed, 23 Feb 2022 10:32:17 +0000 Subject: [PATCH] Revert "[clang][dataflow] Add support for global storage values" This reverts commit 7ea103de140b59a64fc884fa90afd2213619384d. --- .../Analysis/FlowSensitive/DataflowEnvironment.h | 5 - .../Analysis/FlowSensitive/DataflowEnvironment.cpp | 46 ------ clang/lib/Analysis/FlowSensitive/Transfer.cpp | 23 --- .../Analysis/FlowSensitive/TransferTest.cpp | 167 --------------------- 4 files changed, 241 deletions(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index bab2041..af613c9 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -49,11 +49,6 @@ enum class SkipPast { }; /// Holds the state of the program (store and heap) at a given program point. -/// -/// WARNING: Symbolic values that are created by the environment for static -/// local and global variables are not currently invalidated on function calls. -/// This is unsound and should be taken into account when designing dataflow -/// analyses. class Environment { public: /// Supplements `Environment` with non-standard comparison and join diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index f20c747..eca58b3 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -22,7 +22,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/Support/ErrorHandling.h" -#include #include #include @@ -57,55 +56,10 @@ static bool equivalentValues(QualType Type, Value *Val1, Value *Val2, return Model.compareEquivalent(Type, *Val1, *Val2); } -/// Initializes a global storage value. -static void initGlobalVar(const VarDecl &D, Environment &Env) { - if (!D.hasGlobalStorage() || - Env.getStorageLocation(D, SkipPast::None) != nullptr) - return; - - auto &Loc = Env.createStorageLocation(D); - Env.setStorageLocation(D, Loc); - if (auto *Val = Env.createValue(D.getType())) - Env.setValue(Loc, *Val); -} - -/// Initializes a global storage value. -static void initGlobalVar(const Decl &D, Environment &Env) { - if (auto *V = dyn_cast(&D)) - initGlobalVar(*V, Env); -} - -/// Initializes global storage values that are declared or referenced from -/// sub-statements of `S`. -// FIXME: Add support for resetting globals after function calls to enable -// the implementation of sound analyses. -static void initGlobalVars(const Stmt &S, Environment &Env) { - for (auto *Child : S.children()) { - if (Child != nullptr) - initGlobalVars(*Child, Env); - } - - if (auto *DS = dyn_cast(&S)) { - if (DS->isSingleDecl()) { - const auto &D = *cast(DS->getSingleDecl()); - initGlobalVar(D, Env); - } else { - for (auto *D : DS->getDeclGroup()) - initGlobalVar(*D, Env); - } - } else if (auto *E = dyn_cast(&S)) { - initGlobalVar(*E->getDecl(), Env); - } else if (auto *E = dyn_cast(&S)) { - initGlobalVar(*E->getMemberDecl(), Env); - } -} - Environment::Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx) : Environment(DACtx) { if (const auto *FuncDecl = dyn_cast(&DeclCtx)) { - assert(FuncDecl->getBody() != nullptr); - initGlobalVars(*FuncDecl->getBody(), *this); for (const auto *ParamDecl : FuncDecl->parameters()) { assert(ParamDecl != nullptr); auto &ParamLoc = createStorageLocation(*ParamDecl); diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 4b5d235..cd9b8b0 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -136,11 +136,6 @@ public: // Group decls are converted into single decls in the CFG so the cast below // is safe. const auto &D = *cast(S->getSingleDecl()); - - // Static local vars are already initialized in `Environment`. - if (D.hasGlobalStorage()) - return; - auto &Loc = Env.createStorageLocation(D); Env.setStorageLocation(D, Loc); @@ -296,24 +291,6 @@ public: if (Member->isFunctionOrFunctionTemplate()) return; - if (auto *D = dyn_cast(Member)) { - if (D->hasGlobalStorage()) { - auto *VarDeclLoc = Env.getStorageLocation(*D, SkipPast::None); - if (VarDeclLoc == nullptr) - return; - - if (VarDeclLoc->getType()->isReferenceType()) { - Env.setStorageLocation(*S, *VarDeclLoc); - } else { - auto &Loc = Env.createStorageLocation(*S); - Env.setStorageLocation(*S, Loc); - Env.setValue(Loc, Env.takeOwnership( - std::make_unique(*VarDeclLoc))); - } - return; - } - } - // The receiver can be either a value or a pointer to a value. Skip past the // indirection to handle both cases. auto *BaseLoc = cast_or_null( diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index fda4af4..83ccba1 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -2153,171 +2153,4 @@ TEST_F(TransferTest, AssignFromBoolNegation) { }); } -TEST_F(TransferTest, StaticIntSingleVarDecl) { - std::string Code = R"( - void target() { - static int Foo; - // [[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 *FooDecl = findValueDecl(ASTCtx, "Foo"); - ASSERT_THAT(FooDecl, NotNull()); - - const StorageLocation *FooLoc = - Env.getStorageLocation(*FooDecl, SkipPast::None); - ASSERT_TRUE(isa_and_nonnull(FooLoc)); - - const Value *FooVal = Env.getValue(*FooLoc); - EXPECT_TRUE(isa_and_nonnull(FooVal)); - }); -} - -TEST_F(TransferTest, StaticIntGroupVarDecl) { - std::string Code = R"( - void target() { - static int Foo, Bar; - (void)0; - // [[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 *FooDecl = findValueDecl(ASTCtx, "Foo"); - ASSERT_THAT(FooDecl, NotNull()); - - const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); - ASSERT_THAT(BarDecl, NotNull()); - - const StorageLocation *FooLoc = - Env.getStorageLocation(*FooDecl, SkipPast::None); - ASSERT_TRUE(isa_and_nonnull(FooLoc)); - - const StorageLocation *BarLoc = - Env.getStorageLocation(*BarDecl, SkipPast::None); - ASSERT_TRUE(isa_and_nonnull(BarLoc)); - - const Value *FooVal = Env.getValue(*FooLoc); - EXPECT_TRUE(isa_and_nonnull(FooVal)); - - const Value *BarVal = Env.getValue(*BarLoc); - EXPECT_TRUE(isa_and_nonnull(BarVal)); - - EXPECT_NE(FooVal, BarVal); - }); -} - -TEST_F(TransferTest, GlobalIntVarDecl) { - std::string Code = R"( - static int Foo; - - void target() { - int Bar = Foo; - int Baz = Foo; - // [[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 *BarDecl = findValueDecl(ASTCtx, "Bar"); - ASSERT_THAT(BarDecl, NotNull()); - - const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz"); - ASSERT_THAT(BazDecl, NotNull()); - - const Value *BarVal = - cast(Env.getValue(*BarDecl, SkipPast::None)); - const Value *BazVal = - cast(Env.getValue(*BazDecl, SkipPast::None)); - EXPECT_EQ(BarVal, BazVal); - }); -} - -TEST_F(TransferTest, StaticMemberIntVarDecl) { - std::string Code = R"( - struct A { - static int Foo; - }; - - void target(A a) { - int Bar = a.Foo; - int Baz = a.Foo; - // [[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 *BarDecl = findValueDecl(ASTCtx, "Bar"); - ASSERT_THAT(BarDecl, NotNull()); - - const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz"); - ASSERT_THAT(BazDecl, NotNull()); - - const Value *BarVal = - cast(Env.getValue(*BarDecl, SkipPast::None)); - const Value *BazVal = - cast(Env.getValue(*BazDecl, SkipPast::None)); - EXPECT_EQ(BarVal, BazVal); - }); -} - -TEST_F(TransferTest, StaticMemberRefVarDecl) { - std::string Code = R"( - struct A { - static int &Foo; - }; - - void target(A a) { - int Bar = a.Foo; - int Baz = a.Foo; - // [[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 *BarDecl = findValueDecl(ASTCtx, "Bar"); - ASSERT_THAT(BarDecl, NotNull()); - - const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz"); - ASSERT_THAT(BazDecl, NotNull()); - - const Value *BarVal = - cast(Env.getValue(*BarDecl, SkipPast::None)); - const Value *BazVal = - cast(Env.getValue(*BazDecl, SkipPast::None)); - EXPECT_EQ(BarVal, BazVal); - }); -} - } // namespace -- 2.7.4