Author: Martin Braenne Date: 2023-04-03T08:25:10Z New Revision: ce0ab9d11cec0a81c4e48645a23fa8eddea926ab
URL: https://github.com/llvm/llvm-project/commit/ce0ab9d11cec0a81c4e48645a23fa8eddea926ab DIFF: https://github.com/llvm/llvm-project/commit/ce0ab9d11cec0a81c4e48645a23fa8eddea926ab.diff LOG: [clang][dataflow][NFC] Share code between Environment ctor and pushCallInternal(). The deduplicated code is moved into initVars(). As an added bonus, pushCallInternal() now also gets the "Add all fields mentioned in default member initializers" behavior, which apparently had been added to the Environment ctor but not pushCallInternal(). Reviewed By: xazax.hun, ymandel Differential Revision: https://reviews.llvm.org/D147326 Added: Modified: clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index 678e5b871cc83..b4ae172e3fa2f 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -460,8 +460,9 @@ class Environment { void pushCallInternal(const FunctionDecl *FuncDecl, ArrayRef<const Expr *> Args); - /// Assigns storage locations and values to all variables in `Vars`. - void initVars(llvm::DenseSet<const VarDecl *> Vars); + /// Assigns storage locations and values to all global variables and fields + /// referenced in `FuncDecl`. `FuncDecl` must have a body. + void initFieldsAndGlobals(const FunctionDecl *FuncDecl); // `DACtx` is not null and not owned by this object. DataflowAnalysisContext *DACtx; diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index e3bde37ea68f7..fbb8d8ab7edda 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -203,7 +203,33 @@ static void getFieldsAndGlobalVars(const Stmt &S, // FIXME: Add support for resetting globals after function calls to enable // the implementation of sound analyses. -void Environment::initVars(llvm::DenseSet<const VarDecl *> Vars) { +void Environment::initFieldsAndGlobals(const FunctionDecl *FuncDecl) { + assert(FuncDecl->getBody() != nullptr); + + llvm::DenseSet<const FieldDecl *> Fields; + llvm::DenseSet<const VarDecl *> Vars; + + // Look for global variable and field references in the + // constructor-initializers. + if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FuncDecl)) { + for (const auto *Init : CtorDecl->inits()) { + if (const auto *M = Init->getAnyMember()) + Fields.insert(M); + const Expr *E = Init->getInit(); + assert(E != nullptr); + getFieldsAndGlobalVars(*E, Fields, Vars); + } + // Add all fields mentioned in default member initializers. + for (const FieldDecl *F : CtorDecl->getParent()->fields()) + if (const auto *I = F->getInClassInitializer()) + getFieldsAndGlobalVars(*I, Fields, Vars); + } + getFieldsAndGlobalVars(*FuncDecl->getBody(), Fields, Vars); + + // These have to be added before the lines that follow to ensure that + // `create*` work correctly for structs. + DACtx->addModeledFields(Fields); + for (const VarDecl *D : Vars) { if (getStorageLocation(*D, SkipPast::None) != nullptr) continue; @@ -239,31 +265,7 @@ Environment::Environment(DataflowAnalysisContext &DACtx, if (const auto *FuncDecl = dyn_cast<FunctionDecl>(&DeclCtx)) { assert(FuncDecl->getBody() != nullptr); - llvm::DenseSet<const FieldDecl *> Fields; - llvm::DenseSet<const VarDecl *> Vars; - - // Look for global variable and field references in the - // constructor-initializers. - if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(&DeclCtx)) { - for (const auto *Init : CtorDecl->inits()) { - if (const auto *M = Init->getAnyMember()) - Fields.insert(M); - const Expr *E = Init->getInit(); - assert(E != nullptr); - getFieldsAndGlobalVars(*E, Fields, Vars); - } - // Add all fields mentioned in default member initializers. - for (const FieldDecl *F : CtorDecl->getParent()->fields()) - if (const auto *I = F->getInClassInitializer()) - getFieldsAndGlobalVars(*I, Fields, Vars); - } - getFieldsAndGlobalVars(*FuncDecl->getBody(), Fields, Vars); - - // These have to be added before the lines that follow to ensure that - // `create*` work correctly for structs. - DACtx.addModeledFields(Fields); - - initVars(Vars); + initFieldsAndGlobals(FuncDecl); for (const auto *ParamDecl : FuncDecl->parameters()) { assert(ParamDecl != nullptr); @@ -337,26 +339,7 @@ void Environment::pushCallInternal(const FunctionDecl *FuncDecl, ArrayRef<const Expr *> Args) { CallStack.push_back(FuncDecl); - // FIXME: Share this code with the constructor, rather than duplicating it. - llvm::DenseSet<const FieldDecl *> Fields; - llvm::DenseSet<const VarDecl *> Vars; - // Look for global variable references in the constructor-initializers. - if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FuncDecl)) { - for (const auto *Init : CtorDecl->inits()) { - if (const auto *M = Init->getAnyMember()) - Fields.insert(M); - const Expr *E = Init->getInit(); - assert(E != nullptr); - getFieldsAndGlobalVars(*E, Fields, Vars); - } - } - getFieldsAndGlobalVars(*FuncDecl->getBody(), Fields, Vars); - - // These have to be added before the lines that follow to ensure that - // `create*` work correctly for structs. - DACtx->addModeledFields(Fields); - - initVars(Vars); + initFieldsAndGlobals(FuncDecl); const auto *ParamIt = FuncDecl->param_begin(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits