diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -167,6 +167,10 @@ LatticeJoinEffect join(const Environment &Other, Environment::ValueModel &Model); + /// Returns the `DeclCtx` of the block being analysed if provided, otherwise + /// returns nullptr. + const DeclContext *getDeclCtx() { return DeclCtx; } + // FIXME: Rename `createOrGetStorageLocation` to `getOrCreateStorageLocation`, // `getStableStorageLocation`, or something more appropriate. @@ -363,6 +367,9 @@ // `DACtx` is not null and not owned by this object. DataflowAnalysisContext *DACtx; + // `DeclCtx` of the block being analysed if provided. + const DeclContext *DeclCtx; + // Maps from program declarations and statements to storage locations that are // assigned to them. Unlike the maps in `DataflowAnalysisContext`, these // include only storage locations that are in scope for a particular basic diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -154,7 +154,7 @@ : DACtx(&DACtx), FlowConditionToken(&DACtx.makeFlowConditionToken()) {} Environment::Environment(const Environment &Other) - : DACtx(Other.DACtx), DeclToLoc(Other.DeclToLoc), + : DACtx(Other.DACtx), DeclCtx(Other.DeclCtx), DeclToLoc(Other.DeclToLoc), ExprToLoc(Other.ExprToLoc), LocToVal(Other.LocToVal), MemberLocToStruct(Other.MemberLocToStruct), FlowConditionToken(&DACtx->forkFlowCondition(*Other.FlowConditionToken)) { @@ -167,9 +167,11 @@ } Environment::Environment(DataflowAnalysisContext &DACtx, - const DeclContext &DeclCtx) + const DeclContext &DeclCtxArg) : Environment(DACtx) { - if (const auto *FuncDecl = dyn_cast(&DeclCtx)) { + DeclCtx = &DeclCtxArg; + + if (const auto *FuncDecl = dyn_cast(DeclCtx)) { assert(FuncDecl->getBody() != nullptr); initGlobalVars(*FuncDecl->getBody(), *this); for (const auto *ParamDecl : FuncDecl->parameters()) { @@ -181,7 +183,7 @@ } } - if (const auto *MethodDecl = dyn_cast(&DeclCtx)) { + if (const auto *MethodDecl = dyn_cast(DeclCtx)) { auto *Parent = MethodDecl->getParent(); assert(Parent != nullptr); if (Parent->isLambda()) @@ -268,12 +270,14 @@ LatticeJoinEffect Environment::join(const Environment &Other, Environment::ValueModel &Model) { - assert(DACtx == Other.DACtx); + assert(DACtx == Other.DACtx && DeclCtx == Other.DeclCtx); auto Effect = LatticeJoinEffect::Unchanged; Environment JoinedEnv(*DACtx); + JoinedEnv.DeclCtx = DeclCtx; + JoinedEnv.DeclToLoc = intersectDenseMaps(DeclToLoc, Other.DeclToLoc); if (DeclToLoc.size() != JoinedEnv.DeclToLoc.size()) Effect = LatticeJoinEffect::Changed;