Coverage Report

Created: 2023-09-30 09:22

/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
265
StringRef SymbolConjured::getKindStr() const { return "conj_$"; }
39
3
StringRef SymbolDerived::getKindStr() const { return "derived_$"; }
40
8
StringRef SymbolExtent::getKindStr() const { return "extent_$"; }
41
0
StringRef SymbolMetadata::getKindStr() const { return "meta_$"; }
42
3.29k
StringRef SymbolRegionValue::getKindStr() const { return "reg_$"; }
43
44
0
LLVM_DUMP_METHOD void SymExpr::dump() const { dumpToStream(llvm::errs()); }
45
46
128
void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS, const SymExpr *Sym) {
47
128
  OS << '(';
48
128
  Sym->dumpToStream(OS);
49
128
  OS << ')';
50
128
}
51
52
void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS,
53
52
                                     const llvm::APSInt &Value) {
54
52
  if (Value.isUnsigned())
55
18
    OS << Value.getZExtValue();
56
34
  else
57
34
    OS << Value.getSExtValue();
58
52
  if (Value.isUnsigned())
59
18
    OS << 'U';
60
52
}
61
62
void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS,
63
90
                                     BinaryOperator::Opcode Op) {
64
90
  OS << ' ' << BinaryOperator::getOpcodeStr(Op) << ' ';
65
90
}
66
67
3.47k
void SymbolCast::dumpToStream(raw_ostream &os) const {
68
3.47k
  os << '(' << ToTy << ") (";
69
3.47k
  Operand->dumpToStream(os);
70
3.47k
  os << ')';
71
3.47k
}
72
73
5
void UnarySymExpr::dumpToStream(raw_ostream &os) const {
74
5
  os << UnaryOperator::getOpcodeStr(Op);
75
5
  bool Binary = isa<BinarySymExpr>(Operand);
76
5
  if (Binary)
77
2
    os << '(';
78
5
  Operand->dumpToStream(os);
79
5
  if (Binary)
80
2
    os << ')';
81
5
}
82
83
265
void SymbolConjured::dumpToStream(raw_ostream &os) const {
84
265
  os << getKindStr() << getSymbolID() << '{' << T << ", LC" << LCtx->getID();
85
265
  if (S)
86
257
    os << ", S" << S->getID(LCtx->getDecl()->getASTContext());
87
8
  else
88
8
    os << ", no stmt";
89
265
  os << ", #" << Count << '}';
90
265
}
91
92
3
void SymbolDerived::dumpToStream(raw_ostream &os) const {
93
3
  os << getKindStr() << getSymbolID() << '{' << getParentSymbol() << ','
94
3
     << getRegion() << '}';
95
3
}
96
97
8
void SymbolExtent::dumpToStream(raw_ostream &os) const {
98
8
  os << getKindStr() << getSymbolID() << '{' << getRegion() << '}';
99
8
}
100
101
0
void SymbolMetadata::dumpToStream(raw_ostream &os) const {
102
0
  os << getKindStr() << getSymbolID() << '{' << getRegion() << ',' << T << '}';
103
0
}
104
105
0
void SymbolData::anchor() {}
106
107
3.29k
void SymbolRegionValue::dumpToStream(raw_ostream &os) const {
108
3.29k
  os << getKindStr() << getSymbolID() << '<' << getType() << ' ' << R << '>';
109
3.29k
}
110
111
0
bool SymExpr::symbol_iterator::operator==(const symbol_iterator &X) const {
112
0
  return itr == X.itr;
113
0
}
114
115
5.76M
bool SymExpr::symbol_iterator::operator!=(const symbol_iterator &X) const {
116
5.76M
  return itr != X.itr;
117
5.76M
}
118
119
1.42M
SymExpr::symbol_iterator::symbol_iterator(const SymExpr *SE) {
120
1.42M
  itr.push_back(SE);
121
1.42M
}
122
123
3.43M
SymExpr::symbol_iterator &SymExpr::symbol_iterator::operator++() {
124
3.43M
  assert(!itr.empty() && "attempting to iterate on an 'end' iterator");
125
3.43M
  expand();
126
3.43M
  return *this;
127
3.43M
}
128
129
3.44M
SymbolRef SymExpr::symbol_iterator::operator*() {
130
3.44M
  assert(!itr.empty() && "attempting to dereference an 'end' iterator");
131
3.44M
  return itr.back();
132
3.44M
}
133
134
3.43M
void SymExpr::symbol_iterator::expand() {
135
3.43M
  const SymExpr *SE = itr.pop_back_val();
136
137
3.43M
  switch (SE->getKind()) {
138
850k
    case SymExpr::SymbolRegionValueKind:
139
2.20M
    case SymExpr::SymbolConjuredKind:
140
2.27M
    case SymExpr::SymbolDerivedKind:
141
2.27M
    case SymExpr::SymbolExtentKind:
142
2.27M
    case SymExpr::SymbolMetadataKind:
143
2.27M
      return;
144
3.92k
    case SymExpr::SymbolCastKind:
145
3.92k
      itr.push_back(cast<SymbolCast>(SE)->getOperand());
146
3.92k
      return;
147
394
    case SymExpr::UnarySymExprKind:
148
394
      itr.push_back(cast<UnarySymExpr>(SE)->getOperand());
149
394
      return;
150
272k
    case SymExpr::SymIntExprKind:
151
272k
      itr.push_back(cast<SymIntExpr>(SE)->getLHS());
152
272k
      return;
153
25.5k
    case SymExpr::IntSymExprKind:
154
25.5k
      itr.push_back(cast<IntSymExpr>(SE)->getRHS());
155
25.5k
      return;
156
858k
    case SymExpr::SymSymExprKind: {
157
858k
      const auto *x = cast<SymSymExpr>(SE);
158
858k
      itr.push_back(x->getLHS());
159
858k
      itr.push_back(x->getRHS());
160
858k
      return;
161
2.27M
    }
162
3.43M
  }
163
0
  llvm_unreachable("unhandled expansion case");
164
0
}
165
166
const SymbolRegionValue*
167
164k
SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) {
168
164k
  llvm::FoldingSetNodeID profile;
169
164k
  SymbolRegionValue::Profile(profile, R);
170
164k
  void *InsertPos;
171
164k
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
172
164k
  if (!SD) {
173
16.0k
    SD = new (BPAlloc) SymbolRegionValue(SymbolCounter, R);
174
16.0k
    DataSet.InsertNode(SD, InsertPos);
175
16.0k
    ++SymbolCounter;
176
16.0k
  }
177
178
164k
  return cast<SymbolRegionValue>(SD);
179
164k
}
180
181
const SymbolConjured* SymbolManager::conjureSymbol(const Stmt *E,
182
                                                   const LocationContext *LCtx,
183
                                                   QualType T,
184
                                                   unsigned Count,
185
136k
                                                   const void *SymbolTag) {
186
136k
  llvm::FoldingSetNodeID profile;
187
136k
  SymbolConjured::Profile(profile, E, T, Count, LCtx, SymbolTag);
188
136k
  void *InsertPos;
189
136k
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
190
136k
  if (!SD) {
191
73.4k
    SD = new (BPAlloc) SymbolConjured(SymbolCounter, E, LCtx, T, Count, SymbolTag);
192
73.4k
    DataSet.InsertNode(SD, InsertPos);
193
73.4k
    ++SymbolCounter;
194
73.4k
  }
195
196
136k
  return cast<SymbolConjured>(SD);
197
136k
}
198
199
const SymbolDerived*
200
SymbolManager::getDerivedSymbol(SymbolRef parentSymbol,
201
15.8k
                                const TypedValueRegion *R) {
202
15.8k
  llvm::FoldingSetNodeID profile;
203
15.8k
  SymbolDerived::Profile(profile, parentSymbol, R);
204
15.8k
  void *InsertPos;
205
15.8k
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
206
15.8k
  if (!SD) {
207
3.10k
    SD = new (BPAlloc) SymbolDerived(SymbolCounter, parentSymbol, R);
208
3.10k
    DataSet.InsertNode(SD, InsertPos);
209
3.10k
    ++SymbolCounter;
210
3.10k
  }
211
212
15.8k
  return cast<SymbolDerived>(SD);
213
15.8k
}
214
215
const SymbolExtent*
216
9.57k
SymbolManager::getExtentSymbol(const SubRegion *R) {
217
9.57k
  llvm::FoldingSetNodeID profile;
218
9.57k
  SymbolExtent::Profile(profile, R);
219
9.57k
  void *InsertPos;
220
9.57k
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
221
9.57k
  if (!SD) {
222
285
    SD = new (BPAlloc) SymbolExtent(SymbolCounter, R);
223
285
    DataSet.InsertNode(SD, InsertPos);
224
285
    ++SymbolCounter;
225
285
  }
226
227
9.57k
  return cast<SymbolExtent>(SD);
228
9.57k
}
229
230
const SymbolMetadata *
231
SymbolManager::getMetadataSymbol(const MemRegion* R, const Stmt *S, QualType T,
232
                                 const LocationContext *LCtx,
233
694
                                 unsigned Count, const void *SymbolTag) {
234
694
  llvm::FoldingSetNodeID profile;
235
694
  SymbolMetadata::Profile(profile, R, S, T, LCtx, Count, SymbolTag);
236
694
  void *InsertPos;
237
694
  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
238
694
  if (!SD) {
239
662
    SD = new (BPAlloc) SymbolMetadata(SymbolCounter, R, S, T, LCtx, Count, SymbolTag);
240
662
    DataSet.InsertNode(SD, InsertPos);
241
662
    ++SymbolCounter;
242
662
  }
243
244
694
  return cast<SymbolMetadata>(SD);
245
694
}
246
247
const SymbolCast*
248
SymbolManager::getCastSymbol(const SymExpr *Op,
249
5.02k
                             QualType From, QualType To) {
250
5.02k
  llvm::FoldingSetNodeID ID;
251
5.02k
  SymbolCast::Profile(ID, Op, From, To);
252
5.02k
  void *InsertPos;
253
5.02k
  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
254
5.02k
  if (!data) {
255
1.04k
    data = new (BPAlloc) SymbolCast(Op, From, To);
256
1.04k
    DataSet.InsertNode(data, InsertPos);
257
1.04k
  }
258
259
5.02k
  return cast<SymbolCast>(data);
260
5.02k
}
261
262
const SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs,
263
                                               BinaryOperator::Opcode op,
264
                                               const llvm::APSInt& v,
265
223k
                                               QualType t) {
266
223k
  llvm::FoldingSetNodeID ID;
267
223k
  SymIntExpr::Profile(ID, lhs, op, v, t);
268
223k
  void *InsertPos;
269
223k
  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
270
271
223k
  if (!data) {
272
31.8k
    data = new (BPAlloc) SymIntExpr(lhs, op, v, t);
273
31.8k
    DataSet.InsertNode(data, InsertPos);
274
31.8k
  }
275
276
223k
  return cast<SymIntExpr>(data);
277
223k
}
278
279
const IntSymExpr *SymbolManager::getIntSymExpr(const llvm::APSInt& lhs,
280
                                               BinaryOperator::Opcode op,
281
                                               const SymExpr *rhs,
282
1.41k
                                               QualType t) {
283
1.41k
  llvm::FoldingSetNodeID ID;
284
1.41k
  IntSymExpr::Profile(ID, lhs, op, rhs, t);
285
1.41k
  void *InsertPos;
286
1.41k
  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
287
288
1.41k
  if (!data) {
289
281
    data = new (BPAlloc) IntSymExpr(lhs, op, rhs, t);
290
281
    DataSet.InsertNode(data, InsertPos);
291
281
  }
292
293
1.41k
  return cast<IntSymExpr>(data);
294
1.41k
}
295
296
const SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs,
297
                                               BinaryOperator::Opcode op,
298
                                               const SymExpr *rhs,
299
305k
                                               QualType t) {
300
305k
  llvm::FoldingSetNodeID ID;
301
305k
  SymSymExpr::Profile(ID, lhs, op, rhs, t);
302
305k
  void *InsertPos;
303
305k
  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
304
305
305k
  if (!data) {
306
11.4k
    data = new (BPAlloc) SymSymExpr(lhs, op, rhs, t);
307
11.4k
    DataSet.InsertNode(data, InsertPos);
308
11.4k
  }
309
310
305k
  return cast<SymSymExpr>(data);
311
305k
}
312
313
const UnarySymExpr *SymbolManager::getUnarySymExpr(const SymExpr *Operand,
314
                                                   UnaryOperator::Opcode Opc,
315
356k
                                                   QualType T) {
316
356k
  llvm::FoldingSetNodeID ID;
317
356k
  UnarySymExpr::Profile(ID, Operand, Opc, T);
318
356k
  void *InsertPos;
319
356k
  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
320
356k
  if (!data) {
321
10.1k
    data = new (BPAlloc) UnarySymExpr(Operand, Opc, T);
322
10.1k
    DataSet.InsertNode(data, InsertPos);
323
10.1k
  }
324
325
356k
  return cast<UnarySymExpr>(data);
326
356k
}
327
328
1.22M
QualType SymbolConjured::getType() const {
329
1.22M
  return T;
330
1.22M
}
331
332
289k
QualType SymbolDerived::getType() const {
333
289k
  return R->getValueType();
334
289k
}
335
336
853k
QualType SymbolExtent::getType() const {
337
853k
  ASTContext &Ctx = R->getMemRegionManager().getContext();
338
853k
  return Ctx.getSizeType();
339
853k
}
340
341
25.1k
QualType SymbolMetadata::getType() const {
342
25.1k
  return T;
343
25.1k
}
344
345
8.26M
QualType SymbolRegionValue::getType() const {
346
8.26M
  return R->getValueType();
347
8.26M
}
348
349
327k
bool SymbolManager::canSymbolicate(QualType T) {
350
327k
  T = T.getCanonicalType();
351
352
327k
  if (Loc::isLocType(T))
353
84.0k
    return true;
354
355
243k
  if (T->isIntegralOrEnumerationType())
356
231k
    return true;
357
358
11.6k
  if (T->isRecordType() && 
!T->isUnionType()955
)
359
953
    return true;
360
361
10.6k
  return false;
362
11.6k
}
363
364
void SymbolManager::addSymbolDependency(const SymbolRef Primary,
365
129
                                        const SymbolRef Dependent) {
366
129
  auto &dependencies = SymbolDependencies[Primary];
367
129
  if (!dependencies) {
368
119
    dependencies = std::make_unique<SymbolRefSmallVectorTy>();
369
119
  }
370
129
  dependencies->push_back(Dependent);
371
129
}
372
373
const SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols(
374
7.25M
                                                     const SymbolRef Primary) {
375
7.25M
  SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary);
376
7.25M
  if (I == SymbolDependencies.end())
377
7.24M
    return nullptr;
378
1.79k
  return I->second.get();
379
7.25M
}
380
381
10.3M
void SymbolReaper::markDependentsLive(SymbolRef sym) {
382
  // Do not mark dependents more then once.
383
10.3M
  SymbolMapTy::iterator LI = TheLiving.find(sym);
384
10.3M
  assert(LI != TheLiving.end() && "The primary symbol is not live.");
385
10.3M
  if (LI->second == HaveMarkedDependents)
386
3.07M
    return;
387
7.25M
  LI->second = HaveMarkedDependents;
388
389
7.25M
  if (const SymbolRefSmallVectorTy *Deps = SymMgr.getDependentSymbols(sym)) {
390
1.96k
    for (const auto I : *Deps) {
391
1.96k
      if (TheLiving.contains(I))
392
1.02k
        continue;
393
942
      markLive(I);
394
942
    }
395
1.79k
  }
396
7.25M
}
397
398
7.25M
void SymbolReaper::markLive(SymbolRef sym) {
399
7.25M
  TheLiving[sym] = NotProcessed;
400
7.25M
  markDependentsLive(sym);
401
7.25M
}
402
403
1.42M
void SymbolReaper::markLive(const MemRegion *region) {
404
1.42M
  LiveRegionRoots.insert(region->getBaseRegion());
405
1.42M
  markElementIndicesLive(region);
406
1.42M
}
407
408
4.86k
void SymbolReaper::markLazilyCopied(const clang::ento::MemRegion *region) {
409
4.86k
  LazilyCopiedRegionRoots.insert(region->getBaseRegion());
410
4.86k
}
411
412
3.13M
void SymbolReaper::markElementIndicesLive(const MemRegion *region) {
413
6.19M
  for (auto SR = dyn_cast<SubRegion>(region); SR;
414
3.13M
       
SR = dyn_cast<SubRegion>(SR->getSuperRegion())3.05M
) {
415
3.05M
    if (const auto ER = dyn_cast<ElementRegion>(SR)) {
416
232k
      SVal Idx = ER->getIndex();
417
232k
      for (SymbolRef Sym : Idx.symbols())
418
937k
        markLive(Sym);
419
232k
    }
420
3.05M
  }
421
3.13M
}
422
423
1.89k
void SymbolReaper::markInUse(SymbolRef sym) {
424
1.89k
  if (isa<SymbolMetadata>(sym))
425
1.84k
    MetadataInUse.insert(sym);
426
1.89k
}
427
428
1.74M
bool SymbolReaper::isLiveRegion(const MemRegion *MR) {
429
  // TODO: For now, liveness of a memory region is equivalent to liveness of its
430
  // base region. In fact we can do a bit better: say, if a particular FieldDecl
431
  // is not used later in the path, we can diagnose a leak of a value within
432
  // that field earlier than, say, the variable that contains the field dies.
433
1.74M
  MR = MR->getBaseRegion();
434
1.74M
  if (LiveRegionRoots.count(MR))
435
334k
    return true;
436
437
1.41M
  if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
438
915k
    return isLive(SR->getSymbol());
439
440
498k
  if (const auto *VR = dyn_cast<VarRegion>(MR))
441
490k
    return isLive(VR, true);
442
443
  // FIXME: This is a gross over-approximation. What we really need is a way to
444
  // tell if anything still refers to this region. Unlike SymbolicRegions,
445
  // AllocaRegions don't have associated symbols, though, so we don't actually
446
  // have a way to track their liveness.
447
8.10k
  return isa<AllocaRegion, CXXThisRegion, MemSpaceRegion, CodeTextRegion>(MR);
448
498k
}
449
450
254k
bool SymbolReaper::isLazilyCopiedRegion(const MemRegion *MR) const {
451
  // TODO: See comment in isLiveRegion.
452
254k
  return LazilyCopiedRegionRoots.count(MR->getBaseRegion());
453
254k
}
454
455
1.54M
bool SymbolReaper::isReadableRegion(const MemRegion *MR) {
456
1.54M
  return isLiveRegion(MR) || 
isLazilyCopiedRegion(MR)254k
;
457
1.54M
}
458
459
7.44M
bool SymbolReaper::isLive(SymbolRef sym) {
460
7.44M
  if (TheLiving.count(sym)) {
461
3.07M
    markDependentsLive(sym);
462
3.07M
    return true;
463
3.07M
  }
464
465
4.37M
  bool KnownLive;
466
467
4.37M
  switch (sym->getKind()) {
468
1.54M
  case SymExpr::SymbolRegionValueKind:
469
1.54M
    KnownLive = isReadableRegion(cast<SymbolRegionValue>(sym)->getRegion());
470
1.54M
    break;
471
68.7k
  case SymExpr::SymbolConjuredKind:
472
68.7k
    KnownLive = false;
473
68.7k
    break;
474
62.0k
  case SymExpr::SymbolDerivedKind:
475
62.0k
    KnownLive = isLive(cast<SymbolDerived>(sym)->getParentSymbol());
476
62.0k
    break;
477
70.1k
  case SymExpr::SymbolExtentKind:
478
70.1k
    KnownLive = isLiveRegion(cast<SymbolExtent>(sym)->getRegion());
479
70.1k
    break;
480
1.88k
  case SymExpr::SymbolMetadataKind:
481
1.88k
    KnownLive = MetadataInUse.count(sym) &&
482
1.88k
                
isLiveRegion(cast<SymbolMetadata>(sym)->getRegion())1.58k
;
483
1.88k
    if (KnownLive)
484
619
      MetadataInUse.erase(sym);
485
1.88k
    break;
486
1.76M
  case SymExpr::SymIntExprKind:
487
1.76M
    KnownLive = isLive(cast<SymIntExpr>(sym)->getLHS());
488
1.76M
    break;
489
47.0k
  case SymExpr::IntSymExprKind:
490
47.0k
    KnownLive = isLive(cast<IntSymExpr>(sym)->getRHS());
491
47.0k
    break;
492
814k
  case SymExpr::SymSymExprKind:
493
814k
    KnownLive = isLive(cast<SymSymExpr>(sym)->getLHS()) &&
494
814k
                
isLive(cast<SymSymExpr>(sym)->getRHS())783k
;
495
814k
    break;
496
79
  case SymExpr::SymbolCastKind:
497
79
    KnownLive = isLive(cast<SymbolCast>(sym)->getOperand());
498
79
    break;
499
43
  case SymExpr::UnarySymExprKind:
500
43
    KnownLive = isLive(cast<UnarySymExpr>(sym)->getOperand());
501
43
    break;
502
4.37M
  }
503
504
4.37M
  if (KnownLive)
505
3.95M
    markLive(sym);
506
507
4.37M
  return KnownLive;
508
4.37M
}
509
510
bool
511
2.46M
SymbolReaper::isLive(const Expr *ExprVal, const LocationContext *ELCtx) const {
512
2.46M
  if (LCtx == nullptr)
513
47.7k
    return false;
514
515
2.42M
  if (LCtx != ELCtx) {
516
    // If the reaper's location context is a parent of the expression's
517
    // location context, then the expression value is now "out of scope".
518
750k
    if (LCtx->isParentOf(ELCtx))
519
102k
      return false;
520
647k
    return true;
521
750k
  }
522
523
  // If no statement is provided, everything in this and parent contexts is
524
  // live.
525
1.67M
  if (!Loc)
526
94.6k
    return true;
527
528
1.57M
  return LCtx->getAnalysis<RelaxedLiveVariables>()->isLive(Loc, ExprVal);
529
1.67M
}
530
531
1.28M
bool SymbolReaper::isLive(const VarRegion *VR, bool includeStoreBindings) const{
532
1.28M
  const StackFrameContext *VarContext = VR->getStackFrame();
533
534
1.28M
  if (!VarContext)
535
93.4k
    return true;
536
537
1.19M
  if (!LCtx)
538
117k
    return false;
539
1.07M
  const StackFrameContext *CurrentContext = LCtx->getStackFrame();
540
541
1.07M
  if (VarContext == CurrentContext) {
542
    // If no statement is provided, everything is live.
543
717k
    if (!Loc)
544
35.8k
      return true;
545
546
    // Anonymous parameters of an inheriting constructor are live for the entire
547
    // duration of the constructor.
548
681k
    if (isa<CXXInheritedCtorInitExpr>(Loc))
549
6
      return true;
550
551
681k
    if (LCtx->getAnalysis<RelaxedLiveVariables>()->isLive(Loc, VR->getDecl()))
552
552k
      return true;
553
554
128k
    if (!includeStoreBindings)
555
90.1k
      return false;
556
557
38.8k
    unsigned &cachedQuery =
558
38.8k
      const_cast<SymbolReaper *>(this)->includedRegionCache[VR];
559
560
38.8k
    if (cachedQuery) {
561
1.16k
      return cachedQuery == 1;
562
1.16k
    }
563
564
    // Query the store to see if the region occurs in any live bindings.
565
37.6k
    if (Store store = reapedStore.getStore()) {
566
14.8k
      bool hasRegion =
567
14.8k
        reapedStore.getStoreManager().includedInBindings(store, VR);
568
14.8k
      cachedQuery = hasRegion ? 
10
: 2;
569
14.8k
      return hasRegion;
570
14.8k
    }
571
572
22.8k
    return false;
573
37.6k
  }
574
575
357k
  return VarContext->isParentOf(CurrentContext);
576
1.07M
}