@@ -154,7 +154,7 @@ Environment::Environment(DataflowAnalysisContext &DACtx)
154
154
: DACtx(&DACtx), FlowConditionToken(&DACtx.makeFlowConditionToken()) {}
155
155
156
156
Environment::Environment (const Environment &Other)
157
- : DACtx(Other.DACtx), ReturnLoc(Other.ReturnLoc),
157
+ : DACtx(Other.DACtx), DeclCtx(Other.DeclCtx), ReturnLoc(Other.ReturnLoc),
158
158
ThisPointeeLoc (Other.ThisPointeeLoc), DeclToLoc(Other.DeclToLoc),
159
159
ExprToLoc(Other.ExprToLoc), LocToVal(Other.LocToVal),
160
160
MemberLocToStruct(Other.MemberLocToStruct),
@@ -168,9 +168,11 @@ Environment &Environment::operator=(const Environment &Other) {
168
168
}
169
169
170
170
Environment::Environment (DataflowAnalysisContext &DACtx,
171
- const DeclContext &DeclCtx )
171
+ const DeclContext &DeclCtxArg )
172
172
: Environment(DACtx) {
173
- if (const auto *FuncDecl = dyn_cast<FunctionDecl>(&DeclCtx)) {
173
+ setDeclCtx (&DeclCtxArg);
174
+
175
+ if (const auto *FuncDecl = dyn_cast<FunctionDecl>(DeclCtx)) {
174
176
assert (FuncDecl->getBody () != nullptr );
175
177
initGlobalVars (*FuncDecl->getBody (), *this );
176
178
for (const auto *ParamDecl : FuncDecl->parameters ()) {
@@ -185,7 +187,7 @@ Environment::Environment(DataflowAnalysisContext &DACtx,
185
187
ReturnLoc = &createStorageLocation (ReturnType);
186
188
}
187
189
188
- if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(& DeclCtx)) {
190
+ if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(DeclCtx)) {
189
191
auto *Parent = MethodDecl->getParent ();
190
192
assert (Parent != nullptr );
191
193
if (Parent->isLambda ())
@@ -210,6 +212,9 @@ Environment Environment::pushCall(const CallExpr *Call) const {
210
212
211
213
const auto *FuncDecl = Call->getDirectCallee ();
212
214
assert (FuncDecl != nullptr );
215
+
216
+ Env.setDeclCtx (FuncDecl);
217
+
213
218
// FIXME: In order to allow the callee to reference globals, we probably need
214
219
// to call `initGlobalVars` here in some way.
215
220
@@ -252,12 +257,12 @@ Environment Environment::pushCall(const CallExpr *Call) const {
252
257
253
258
void Environment::popCall (const Environment &CalleeEnv) {
254
259
// We ignore `DACtx` because it's already the same in both. We don't want the
255
- // callee's `ReturnLoc` or `ThisPointeeLoc`. We don't bring back `DeclToLoc`
256
- // and `ExprToLoc` because we want to be able to later analyze the same callee
257
- // in a different context, and `setStorageLocation` requires there to not
258
- // already be a storage location assigned. Conceptually, these maps capture
259
- // information from the local scope, so when popping that scope, we do not
260
- // propagate the maps.
260
+ // callee's `DeclCtx`, ` ReturnLoc` or `ThisPointeeLoc`. We don't bring back
261
+ // `DeclToLoc` and `ExprToLoc` because we want to be able to later analyze the
262
+ // same callee in a different context, and `setStorageLocation` requires there
263
+ // to not already be a storage location assigned. Conceptually, these maps
264
+ // capture information from the local scope, so when popping that scope, we do
265
+ // not propagate the maps.
261
266
this ->LocToVal = std::move (CalleeEnv.LocToVal );
262
267
this ->MemberLocToStruct = std::move (CalleeEnv.MemberLocToStruct );
263
268
this ->FlowConditionToken = std::move (CalleeEnv.FlowConditionToken );
@@ -304,11 +309,13 @@ LatticeJoinEffect Environment::join(const Environment &Other,
304
309
assert (DACtx == Other.DACtx );
305
310
assert (ReturnLoc == Other.ReturnLoc );
306
311
assert (ThisPointeeLoc == Other.ThisPointeeLoc );
312
+ assert (DeclCtx == Other.DeclCtx );
307
313
308
314
auto Effect = LatticeJoinEffect::Unchanged;
309
315
310
316
Environment JoinedEnv (*DACtx);
311
317
318
+ JoinedEnv.setDeclCtx (DeclCtx);
312
319
JoinedEnv.ReturnLoc = ReturnLoc;
313
320
JoinedEnv.ThisPointeeLoc = ThisPointeeLoc;
314
321
0 commit comments