Author: Stanislav Gatev Date: 2022-02-23T10:32:17Z New Revision: 169e1aba55bed9f7ffa000f9f170ab2defbc40b2
URL: https://github.com/llvm/llvm-project/commit/169e1aba55bed9f7ffa000f9f170ab2defbc40b2 DIFF: https://github.com/llvm/llvm-project/commit/169e1aba55bed9f7ffa000f9f170ab2defbc40b2.diff LOG: Revert "[clang][dataflow] Add support for global storage values" This reverts commit 7ea103de140b59a64fc884fa90afd2213619384d. Added: Modified: clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp clang/lib/Analysis/FlowSensitive/Transfer.cpp clang/unittests/Analysis/FlowSensitive/TransferTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index bab20418a016a..af613c95bb8dc 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 f20c747c56c2d..eca58b313761b 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 <cassert> #include <memory> #include <utility> @@ -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<VarDecl>(&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<DeclStmt>(&S)) { - if (DS->isSingleDecl()) { - const auto &D = *cast<VarDecl>(DS->getSingleDecl()); - initGlobalVar(D, Env); - } else { - for (auto *D : DS->getDeclGroup()) - initGlobalVar(*D, Env); - } - } else if (auto *E = dyn_cast<DeclRefExpr>(&S)) { - initGlobalVar(*E->getDecl(), Env); - } else if (auto *E = dyn_cast<MemberExpr>(&S)) { - initGlobalVar(*E->getMemberDecl(), Env); - } -} - Environment::Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx) : Environment(DACtx) { if (const auto *FuncDecl = dyn_cast<FunctionDecl>(&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 4b5d23593a4bd..cd9b8b0e454e4 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -136,11 +136,6 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> { // Group decls are converted into single decls in the CFG so the cast below // is safe. const auto &D = *cast<VarDecl>(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 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> { if (Member->isFunctionOrFunctionTemplate()) return; - if (auto *D = dyn_cast<VarDecl>(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<ReferenceValue>(*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<AggregateStorageLocation>( diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index fda4af435c4a7..83ccba1a25382 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<std::string, DataflowAnalysisState<NoopLattice>>> - 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<ScalarStorageLocation>(FooLoc)); - - const Value *FooVal = Env.getValue(*FooLoc); - EXPECT_TRUE(isa_and_nonnull<IntegerValue>(FooVal)); - }); -} - -TEST_F(TransferTest, StaticIntGroupVarDecl) { - std::string Code = R"( - void target() { - static int Foo, Bar; - (void)0; - // [[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 *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<ScalarStorageLocation>(FooLoc)); - - const StorageLocation *BarLoc = - Env.getStorageLocation(*BarDecl, SkipPast::None); - ASSERT_TRUE(isa_and_nonnull<ScalarStorageLocation>(BarLoc)); - - const Value *FooVal = Env.getValue(*FooLoc); - EXPECT_TRUE(isa_and_nonnull<IntegerValue>(FooVal)); - - const Value *BarVal = Env.getValue(*BarLoc); - EXPECT_TRUE(isa_and_nonnull<IntegerValue>(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<std::string, DataflowAnalysisState<NoopLattice>>> - 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<IntegerValue>(Env.getValue(*BarDecl, SkipPast::None)); - const Value *BazVal = - cast<IntegerValue>(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<std::string, DataflowAnalysisState<NoopLattice>>> - 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<IntegerValue>(Env.getValue(*BarDecl, SkipPast::None)); - const Value *BazVal = - cast<IntegerValue>(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<std::string, DataflowAnalysisState<NoopLattice>>> - 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<IntegerValue>(Env.getValue(*BarDecl, SkipPast::None)); - const Value *BazVal = - cast<IntegerValue>(Env.getValue(*BazDecl, SkipPast::None)); - EXPECT_EQ(BarVal, BazVal); - }); -} - } // namespace _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits