Coverage Report

Created: 2021-03-06 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- SymbolManager.h - Management of Symbolic Values --------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file defines SymbolManager, a class that manages symbolic values
10
//  created for use by ExprEngine and related classes.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
15
#include "clang/AST/ASTContext.h"
16
#include "clang/AST/Expr.h"
17
#include "clang/AST/StmtObjC.h"
18
#include "clang/Analysis/Analyses/LiveVariables.h"
19
#include "clang/Analysis/AnalysisDeclContext.h"
20
#include "clang/Basic/LLVM.h"
21
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
22
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
23
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
24
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
25
#include "llvm/ADT/FoldingSet.h"
26
#include "llvm/ADT/STLExtras.h"
27
#include "llvm/Support/Casting.h"
28
#include "llvm/Support/Compiler.h"
29
#include "llvm/Support/ErrorHandling.h"
30
#include "llvm/Support/raw_ostream.h"
31
#include <cassert>
32
33
using namespace clang;
34
using namespace ento;
35
36
0
void SymExpr::anchor() {}
37
38
202
StringRef SymbolConjured::getKindStr() const { return "conj_$"; }
39
0
StringRef SymbolDerived::getKindStr() const { return "derived_$"; }
40
0
StringRef SymbolExtent::getKindStr() const { return "extent_$"; }
41
0
StringRef SymbolMetadata::getKindStr() const { return "meta_$"; }
42
88
StringRef SymbolRegionValue::getKindStr() const { return "reg_$"; }
43
44
0
LLVM_DUMP_METHOD void SymExpr::dump() const { dumpToStream(llvm::errs()); }
45
46
1
void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS, const SymExpr *Sym) {
47
1
  OS << '(';
48
1
  Sym->dumpToStream(OS);
49
1
  OS << ')';
50
1
}
51
52
void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS,
53
1
                                     const llvm::APSInt &Value) {
54
1
  if (Value.isUnsigned())
55
0
    OS << Value.getZExtValue();
56
1
  else
57
1
    OS << Value.getSExtValue();
58
1
  if (Value.isUnsigned())
59
0
    OS << 'U';
60
1
}
61
62
void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS,
63
1
                                     BinaryOperator::Opcode Op) {
64
1
  OS << ' ' << BinaryOperator::getOpcodeStr(Op) << ' ';
65
1
}
66
67
0
void SymbolCast::dumpToStream(raw_ostream &os) const {
68
0
  os << '(' << ToTy.getAsString() << ") (";
69
0
  Operand->dumpToStream(os);
70
0
  os << ')';
71
0
}
72
73
202
void SymbolConjured::dumpToStream(raw_ostream &os) const {
74
202
  os << getKindStr() << getSymbolID() << '{' << T.getAsString() << ", LC"
75
202
     << LCtx->getID();
76
202
  if (S)
77
194
    os << ", S" << S->getID(LCtx->getDecl()->getASTContext());
78
8
  else
79
8
    os << ", no stmt";
80
202
  os << ", #" << Count << '}';
81
202
}
82
83
0
void SymbolDerived::dumpToStream(raw_ostream &os) const {
84
0
  os << getKindStr() << getSymbolID() << '{' << getParentSymbol() << ','
85
0
     << getRegion() << '}';
86
0
}
87
88
0
void SymbolExtent::dumpToStream(raw_ostream &os) const {
89
0
  os << getKindStr() << getSymbolID() << '{' << getRegion() << '}';
90
0
}
91
92
0
void SymbolMetadata::dumpToStream(raw_ostream &os) const {
93
0
  os << getKindStr() << getSymbolID() << '{' << getRegion() << ','
94
0
     << T.getAsString() << '}';
95
0
}
96
97
0
void SymbolData::anchor() {}
98
99
88
void SymbolRegionValue::dumpToStream(raw_ostream &os) const {
100
88
  os << getKindStr() << getSymbolID() << '<' << getType().getAsString() << ' '
101
88
     << R << '>';
102
88
}
103
104
0
bool SymExpr::symbol_iterator::operator==(const symbol_iterator &X) const {
105
0
  return itr == X.itr;
106
0
}
107
108
4.09M
bool SymExpr::symbol_iterator::operator!=(const symbol_iterator &X) const {
109
4.09M
  return itr != X.itr;
110
4.09M
}
111
112
1.17M
SymExpr::symbol_iterator::symbol_iterator(const SymExpr *SE) {
113
1.17M
  itr.push_back(SE);
114
1.17M
}
115
116
2.12M
SymExpr::symbol_iterator &SymExpr::symbol_iterator::operator++() {
117
2.12M
  assert(!itr.empty() && "attempting to iterate on an 'end' iterator");
118
0
  expand();
119
2.12M
  return *this;
120
2.12M
}
121
122
2.59M
SymbolRef SymExpr::symbol_iterator::operator*() {
123
2.59M
  assert(!itr.empty() && "attempting to dereference an 'end' iterator");
124
0
  return itr.back();
125
2.59M
}
126
127
2.12M
void SymExpr::symbol_iterator::expand() {
128
2.12M
  const SymExpr *SE = itr.pop_back_val();
129
130
2.12M
  switch (SE->getKind()) {
131
190k
    case SymExpr::SymbolRegionValueKind:
132
1.49M
    case SymExpr::SymbolConjuredKind:
133
1.56M
    case SymExpr::SymbolDerivedKind:
134
1.56M
    case SymExpr::SymbolExtentKind:
135
1.57M
    case SymExpr::SymbolMetadataKind:
136
1.57M
      return;
137
235
    case SymExpr::SymbolCastKind:
138
235
      itr.push_back(cast<SymbolCast>(SE)->getOperand());
139
235
      return;
140
137k
    case SymExpr::SymIntExprKind:
141
137k
      itr.push_back(cast<SymIntExpr>(SE)->getLHS());
142
137k
      return;
143
3.61k
    case SymExpr::IntSymExprKind:
144
3.61k
      itr.push_back(cast<IntSymExpr>(SE)->getRHS());
145
3.61k
      return;
146
411k
    case SymExpr::SymSymExprKind: {
147
411k
      const auto *x = cast<SymSymExpr>(SE);
148
411k
      itr.push_back(x->getLHS());
149
411k
      itr.push_back(x->getRHS());
150
411k
      return;
151
1.56M
    }
152
2.12M
  }
153
2.12M
  
llvm_unreachable0
("unhandled expansion case");
154
2.12M
}
155
156
const SymbolRegionValue*
157
108k
SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) {
158
108k
  llvm::FoldingSetNodeID profile;
159
108k
  SymbolRegionValue::Profile(profile, R);
160
108k
  void *InsertPos;
161
108k
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
162
108k
  if (!SD) {
163
13.3k
    SD = (SymExpr*) BPAlloc.Allocate<SymbolRegionValue>();
164
13.3k
    new (SD) SymbolRegionValue(SymbolCounter, R);
165
13.3k
    DataSet.InsertNode(SD, InsertPos);
166
13.3k
    ++SymbolCounter;
167
13.3k
  }
168
169
108k
  return cast<SymbolRegionValue>(SD);
170
108k
}
171
172
const SymbolConjured* SymbolManager::conjureSymbol(const Stmt *E,
173
                                                   const LocationContext *LCtx,
174
                                                   QualType T,
175
                                                   unsigned Count,
176
120k
                                                   const void *SymbolTag) {
177
120k
  llvm::FoldingSetNodeID profile;
178
120k
  SymbolConjured::Profile(profile, E, T, Count, LCtx, SymbolTag);
179
120k
  void *InsertPos;
180
120k
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
181
120k
  if (!SD) {
182
62.2k
    SD = (SymExpr*) BPAlloc.Allocate<SymbolConjured>();
183
62.2k
    new (SD) SymbolConjured(SymbolCounter, E, LCtx, T, Count, SymbolTag);
184
62.2k
    DataSet.InsertNode(SD, InsertPos);
185
62.2k
    ++SymbolCounter;
186
62.2k
  }
187
188
120k
  return cast<SymbolConjured>(SD);
189
120k
}
190
191
const SymbolDerived*
192
SymbolManager::getDerivedSymbol(SymbolRef parentSymbol,
193
12.4k
                                const TypedValueRegion *R) {
194
12.4k
  llvm::FoldingSetNodeID profile;
195
12.4k
  SymbolDerived::Profile(profile, parentSymbol, R);
196
12.4k
  void *InsertPos;
197
12.4k
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
198
12.4k
  if (!SD) {
199
2.43k
    SD = (SymExpr*) BPAlloc.Allocate<SymbolDerived>();
200
2.43k
    new (SD) SymbolDerived(SymbolCounter, parentSymbol, R);
201
2.43k
    DataSet.InsertNode(SD, InsertPos);
202
2.43k
    ++SymbolCounter;
203
2.43k
  }
204
205
12.4k
  return cast<SymbolDerived>(SD);
206
12.4k
}
207
208
const SymbolExtent*
209
2.02k
SymbolManager::getExtentSymbol(const SubRegion *R) {
210
2.02k
  llvm::FoldingSetNodeID profile;
211
2.02k
  SymbolExtent::Profile(profile, R);
212
2.02k
  void *InsertPos;
213
2.02k
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
214
2.02k
  if (!SD) {
215
1.47k
    SD = (SymExpr*) BPAlloc.Allocate<SymbolExtent>();
216
1.47k
    new (SD) SymbolExtent(SymbolCounter, R);
217
1.47k
    DataSet.InsertNode(SD, InsertPos);
218
1.47k
    ++SymbolCounter;
219
1.47k
  }
220
221
2.02k
  return cast<SymbolExtent>(SD);
222
2.02k
}
223
224
const SymbolMetadata *
225
SymbolManager::getMetadataSymbol(const MemRegion* R, const Stmt *S, QualType T,
226
                                 const LocationContext *LCtx,
227
597
                                 unsigned Count, const void *SymbolTag) {
228
597
  llvm::FoldingSetNodeID profile;
229
597
  SymbolMetadata::Profile(profile, R, S, T, LCtx, Count, SymbolTag);
230
597
  void *InsertPos;
231
597
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
232
597
  if (!SD) {
233
573
    SD = (SymExpr*) BPAlloc.Allocate<SymbolMetadata>();
234
573
    new (SD) SymbolMetadata(SymbolCounter, R, S, T, LCtx, Count, SymbolTag);
235
573
    DataSet.InsertNode(SD, InsertPos);
236
573
    ++SymbolCounter;
237
573
  }
238
239
597
  return cast<SymbolMetadata>(SD);
240
597
}
241
242
const SymbolCast*
243
SymbolManager::getCastSymbol(const SymExpr *Op,
244
44
                             QualType From, QualType To) {
245
44
  llvm::FoldingSetNodeID ID;
246
44
  SymbolCast::Profile(ID, Op, From, To);
247
44
  void *InsertPos;
248
44
  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
249
44
  if (!data) {
250
35
    data = (SymbolCast*) BPAlloc.Allocate<SymbolCast>();
251
35
    new (data) SymbolCast(Op, From, To);
252
35
    DataSet.InsertNode(data, InsertPos);
253
35
  }
254
255
44
  return cast<SymbolCast>(data);
256
44
}
257
258
const SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs,
259
                                               BinaryOperator::Opcode op,
260
                                               const llvm::APSInt& v,
261
177k
                                               QualType t) {
262
177k
  llvm::FoldingSetNodeID ID;
263
177k
  SymIntExpr::Profile(ID, lhs, op, v, t);
264
177k
  void *InsertPos;
265
177k
  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
266
267
177k
  if (!data) {
268
30.6k
    data = (SymIntExpr*) BPAlloc.Allocate<SymIntExpr>();
269
30.6k
    new (data) SymIntExpr(lhs, op, v, t);
270
30.6k
    DataSet.InsertNode(data, InsertPos);
271
30.6k
  }
272
273
177k
  return cast<SymIntExpr>(data);
274
177k
}
275
276
const IntSymExpr *SymbolManager::getIntSymExpr(const llvm::APSInt& lhs,
277
                                               BinaryOperator::Opcode op,
278
                                               const SymExpr *rhs,
279
188
                                               QualType t) {
280
188
  llvm::FoldingSetNodeID ID;
281
188
  IntSymExpr::Profile(ID, lhs, op, rhs, t);
282
188
  void *InsertPos;
283
188
  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
284
285
188
  if (!data) {
286
140
    data = (IntSymExpr*) BPAlloc.Allocate<IntSymExpr>();
287
140
    new (data) IntSymExpr(lhs, op, rhs, t);
288
140
    DataSet.InsertNode(data, InsertPos);
289
140
  }
290
291
188
  return cast<IntSymExpr>(data);
292
188
}
293
294
const SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs,
295
                                               BinaryOperator::Opcode op,
296
                                               const SymExpr *rhs,
297
47.4k
                                               QualType t) {
298
47.4k
  llvm::FoldingSetNodeID ID;
299
47.4k
  SymSymExpr::Profile(ID, lhs, op, rhs, t);
300
47.4k
  void *InsertPos;
301
47.4k
  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
302
303
47.4k
  if (!data) {
304
6.62k
    data = (SymSymExpr*) BPAlloc.Allocate<SymSymExpr>();
305
6.62k
    new (data) SymSymExpr(lhs, op, rhs, t);
306
6.62k
    DataSet.InsertNode(data, InsertPos);
307
6.62k
  }
308
309
47.4k
  return cast<SymSymExpr>(data);
310
47.4k
}
311
312
710k
QualType SymbolConjured::getType() const {
313
710k
  return T;
314
710k
}
315
316
95.4k
QualType SymbolDerived::getType() const {
317
95.4k
  return R->getValueType();
318
95.4k
}
319
320
16.7k
QualType SymbolExtent::getType() const {
321
16.7k
  ASTContext &Ctx = R->getMemRegionManager().getContext();
322
16.7k
  return Ctx.getSizeType();
323
16.7k
}
324
325
11.3k
QualType SymbolMetadata::getType() const {
326
11.3k
  return T;
327
11.3k
}
328
329
455k
QualType SymbolRegionValue::getType() const {
330
455k
  return R->getValueType();
331
455k
}
332
333
250k
bool SymbolManager::canSymbolicate(QualType T) {
334
250k
  T = T.getCanonicalType();
335
336
250k
  if (Loc::isLocType(T))
337
66.9k
    return true;
338
339
183k
  if (T->isIntegralOrEnumerationType())
340
173k
    return true;
341
342
10.2k
  if (T->isRecordType() && 
!T->isUnionType()913
)
343
913
    return true;
344
345
9.34k
  return false;
346
10.2k
}
347
348
void SymbolManager::addSymbolDependency(const SymbolRef Primary,
349
128
                                        const SymbolRef Dependent) {
350
128
  auto &dependencies = SymbolDependencies[Primary];
351
128
  if (!dependencies) {
352
118
    dependencies = std::make_unique<SymbolRefSmallVectorTy>();
353
118
  }
354
128
  dependencies->push_back(Dependent);
355
128
}
356
357
const SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols(
358
4.81M
                                                     const SymbolRef Primary) {
359
4.81M
  SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary);
360
4.81M
  if (I == SymbolDependencies.end())
361
4.80M
    return nullptr;
362
1.78k
  return I->second.get();
363
4.81M
}
364
365
6.37M
void SymbolReaper::markDependentsLive(SymbolRef sym) {
366
  // Do not mark dependents more then once.
367
6.37M
  SymbolMapTy::iterator LI = TheLiving.find(sym);
368
6.37M
  assert(LI != TheLiving.end() && "The primary symbol is not live.");
369
6.37M
  if (LI->second == HaveMarkedDependents)
370
1.56M
    return;
371
4.81M
  LI->second = HaveMarkedDependents;
372
373
4.81M
  if (const SymbolRefSmallVectorTy *Deps = SymMgr.getDependentSymbols(sym)) {
374
1.95k
    for (const auto I : *Deps) {
375
1.95k
      if (TheLiving.find(I) != TheLiving.end())
376
1.01k
        continue;
377
939
      markLive(I);
378
939
    }
379
1.78k
  }
380
4.81M
}
381
382
4.81M
void SymbolReaper::markLive(SymbolRef sym) {
383
4.81M
  TheLiving[sym] = NotProcessed;
384
4.81M
  markDependentsLive(sym);
385
4.81M
}
386
387
1.39M
void SymbolReaper::markLive(const MemRegion *region) {
388
1.39M
  RegionRoots.insert(region->getBaseRegion());
389
1.39M
  markElementIndicesLive(region);
390
1.39M
}
391
392
2.90M
void SymbolReaper::markElementIndicesLive(const MemRegion *region) {
393
5.68M
  for (auto SR = dyn_cast<SubRegion>(region); SR;
394
2.77M
       SR = dyn_cast<SubRegion>(SR->getSuperRegion())) {
395
2.77M
    if (const auto ER = dyn_cast<ElementRegion>(SR)) {
396
178k
      SVal Idx = ER->getIndex();
397
974k
      for (auto SI = Idx.symbol_begin(), SE = Idx.symbol_end(); SI != SE; 
++SI795k
)
398
795k
        markLive(*SI);
399
178k
    }
400
2.77M
  }
401
2.90M
}
402
403
1.66k
void SymbolReaper::markInUse(SymbolRef sym) {
404
1.66k
  if (isa<SymbolMetadata>(sym))
405
1.61k
    MetadataInUse.insert(sym);
406
1.66k
}
407
408
1.22M
bool SymbolReaper::isLiveRegion(const MemRegion *MR) {
409
  // TODO: For now, liveness of a memory region is equivalent to liveness of its
410
  // base region. In fact we can do a bit better: say, if a particular FieldDecl
411
  // is not used later in the path, we can diagnose a leak of a value within
412
  // that field earlier than, say, the variable that contains the field dies.
413
1.22M
  MR = MR->getBaseRegion();
414
415
1.22M
  if (RegionRoots.count(MR))
416
341k
    return true;
417
418
884k
  if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
419
649k
    return isLive(SR->getSymbol());
420
421
234k
  if (const auto *VR = dyn_cast<VarRegion>(MR))
422
222k
    return isLive(VR, true);
423
424
  // FIXME: This is a gross over-approximation. What we really need is a way to
425
  // tell if anything still refers to this region. Unlike SymbolicRegions,
426
  // AllocaRegions don't have associated symbols, though, so we don't actually
427
  // have a way to track their liveness.
428
12.2k
  if (isa<AllocaRegion>(MR))
429
4.84k
    return true;
430
431
7.39k
  if (isa<CXXThisRegion>(MR))
432
5.99k
    return true;
433
434
1.40k
  if (isa<MemSpaceRegion>(MR))
435
0
    return true;
436
437
1.40k
  if (isa<CodeTextRegion>(MR))
438
31
    return true;
439
440
1.37k
  return false;
441
1.40k
}
442
443
4.29M
bool SymbolReaper::isLive(SymbolRef sym) {
444
4.29M
  if (TheLiving.count(sym)) {
445
1.56M
    markDependentsLive(sym);
446
1.56M
    return true;
447
1.56M
  }
448
449
2.73M
  bool KnownLive;
450
451
2.73M
  switch (sym->getKind()) {
452
1.07M
  case SymExpr::SymbolRegionValueKind:
453
1.07M
    KnownLive = isLiveRegion(cast<SymbolRegionValue>(sym)->getRegion());
454
1.07M
    break;
455
62.2k
  case SymExpr::SymbolConjuredKind:
456
62.2k
    KnownLive = false;
457
62.2k
    break;
458
61.4k
  case SymExpr::SymbolDerivedKind:
459
61.4k
    KnownLive = isLive(cast<SymbolDerived>(sym)->getParentSymbol());
460
61.4k
    break;
461
14.5k
  case SymExpr::SymbolExtentKind:
462
14.5k
    KnownLive = isLiveRegion(cast<SymbolExtent>(sym)->getRegion());
463
14.5k
    break;
464
1.68k
  case SymExpr::SymbolMetadataKind:
465
1.68k
    KnownLive = MetadataInUse.count(sym) &&
466
1.45k
                isLiveRegion(cast<SymbolMetadata>(sym)->getRegion());
467
1.68k
    if (KnownLive)
468
581
      MetadataInUse.erase(sym);
469
1.68k
    break;
470
1.41M
  case SymExpr::SymIntExprKind:
471
1.41M
    KnownLive = isLive(cast<SymIntExpr>(sym)->getLHS());
472
1.41M
    break;
473
268
  case SymExpr::IntSymExprKind:
474
268
    KnownLive = isLive(cast<IntSymExpr>(sym)->getRHS());
475
268
    break;
476
99.2k
  case SymExpr::SymSymExprKind:
477
99.2k
    KnownLive = isLive(cast<SymSymExpr>(sym)->getLHS()) &&
478
90.8k
                isLive(cast<SymSymExpr>(sym)->getRHS());
479
99.2k
    break;
480
22
  case SymExpr::SymbolCastKind:
481
22
    KnownLive = isLive(cast<SymbolCast>(sym)->getOperand());
482
22
    break;
483
2.73M
  }
484
485
2.73M
  if (KnownLive)
486
2.57M
    markLive(sym);
487
488
2.73M
  return KnownLive;
489
2.73M
}
490
491
bool
492
2.00M
SymbolReaper::isLive(const Expr *ExprVal, const LocationContext *ELCtx) const {
493
2.00M
  if (LCtx == nullptr)
494
38.1k
    return false;
495
496
1.96M
  if (LCtx != ELCtx) {
497
    // If the reaper's location context is a parent of the expression's
498
    // location context, then the expression value is now "out of scope".
499
754k
    if (LCtx->isParentOf(ELCtx))
500
102k
      return false;
501
652k
    return true;
502
754k
  }
503
504
  // If no statement is provided, everything in this and parent contexts is
505
  // live.
506
1.20M
  if (!Loc)
507
92.3k
    return true;
508
509
1.11M
  return LCtx->getAnalysis<RelaxedLiveVariables>()->isLive(Loc, ExprVal);
510
1.20M
}
511
512
874k
bool SymbolReaper::isLive(const VarRegion *VR, bool includeStoreBindings) const{
513
874k
  const StackFrameContext *VarContext = VR->getStackFrame();
514
515
874k
  if (!VarContext)
516
87.6k
    return true;
517
518
787k
  if (!LCtx)
519
16.6k
    return false;
520
770k
  const StackFrameContext *CurrentContext = LCtx->getStackFrame();
521
522
770k
  if (VarContext == CurrentContext) {
523
    // If no statement is provided, everything is live.
524
412k
    if (!Loc)
525
35.3k
      return true;
526
527
    // Anonymous parameters of an inheriting constructor are live for the entire
528
    // duration of the constructor.
529
377k
    if (isa<CXXInheritedCtorInitExpr>(Loc))
530
6
      return true;
531
532
377k
    if (LCtx->getAnalysis<RelaxedLiveVariables>()->isLive(Loc, VR->getDecl()))
533
277k
      return true;
534
535
100k
    if (!includeStoreBindings)
536
75.6k
      return false;
537
538
24.7k
    unsigned &cachedQuery =
539
24.7k
      const_cast<SymbolReaper *>(this)->includedRegionCache[VR];
540
541
24.7k
    if (cachedQuery) {
542
1.05k
      return cachedQuery == 1;
543
1.05k
    }
544
545
    // Query the store to see if the region occurs in any live bindings.
546
23.7k
    if (Store store = reapedStore.getStore()) {
547
14.5k
      bool hasRegion =
548
14.5k
        reapedStore.getStoreManager().includedInBindings(store, VR);
549
14.5k
      cachedQuery = hasRegion ? 
10
: 2;
550
14.5k
      return hasRegion;
551
14.5k
    }
552
553
9.19k
    return false;
554
23.7k
  }
555
556
357k
  return VarContext->isParentOf(CurrentContext);
557
770k
}