Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
Line
Count
Source (jump to first uncovered line)
1
//==- MemRegion.h - Abstract memory regions for static analysis -*- C++ -*--==//
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 MemRegion and its subclasses.  MemRegion defines a
10
//  partially-typed abstraction of memory useful for path-sensitive dataflow
11
//  analyses.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
16
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
17
18
#include "clang/AST/ASTContext.h"
19
#include "clang/AST/CharUnits.h"
20
#include "clang/AST/Decl.h"
21
#include "clang/AST/DeclObjC.h"
22
#include "clang/AST/DeclarationName.h"
23
#include "clang/AST/Expr.h"
24
#include "clang/AST/ExprObjC.h"
25
#include "clang/AST/Type.h"
26
#include "clang/Analysis/AnalysisDeclContext.h"
27
#include "clang/Basic/LLVM.h"
28
#include "clang/Basic/SourceLocation.h"
29
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
30
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
31
#include "llvm/ADT/DenseMap.h"
32
#include "llvm/ADT/FoldingSet.h"
33
#include "llvm/ADT/PointerIntPair.h"
34
#include "llvm/ADT/iterator_range.h"
35
#include "llvm/Support/Allocator.h"
36
#include "llvm/Support/Casting.h"
37
#include <cassert>
38
#include <cstdint>
39
#include <limits>
40
#include <optional>
41
#include <string>
42
#include <utility>
43
44
namespace clang {
45
46
class AnalysisDeclContext;
47
class CXXRecordDecl;
48
class Decl;
49
class LocationContext;
50
class StackFrameContext;
51
52
namespace ento {
53
54
class CodeTextRegion;
55
class MemRegion;
56
class MemRegionManager;
57
class MemSpaceRegion;
58
class SValBuilder;
59
class SymbolicRegion;
60
class VarRegion;
61
62
/// Represent a region's offset within the top level base region.
63
class RegionOffset {
64
  /// The base region.
65
  const MemRegion *R = nullptr;
66
67
  /// The bit offset within the base region. Can be negative.
68
  int64_t Offset;
69
70
public:
71
  // We're using a const instead of an enumeration due to the size required;
72
  // Visual Studio will only create enumerations of size int, not long long.
73
  static const int64_t Symbolic = std::numeric_limits<int64_t>::max();
74
75
  RegionOffset() = default;
76
131k
  RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
77
78
  /// It might return null.
79
1.96M
  const MemRegion *getRegion() const { return R; }
80
81
3.82M
  bool hasSymbolicOffset() const { return Offset == Symbolic; }
82
83
1.86M
  int64_t getOffset() const {
84
1.86M
    assert(!hasSymbolicOffset());
85
1.86M
    return Offset;
86
1.86M
  }
87
88
812
  bool isValid() const { return R; }
89
};
90
91
//===----------------------------------------------------------------------===//
92
// Base region classes.
93
//===----------------------------------------------------------------------===//
94
95
/// MemRegion - The root abstract class for all memory regions.
96
class MemRegion : public llvm::FoldingSetNode {
97
public:
98
  enum Kind {
99
#define REGION(Id, Parent) Id ## Kind,
100
#define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
101
#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
102
  };
103
104
private:
105
  const Kind kind;
106
  mutable std::optional<RegionOffset> cachedOffset;
107
108
protected:
109
255k
  MemRegion(Kind k) : kind(k) {}
110
  virtual ~MemRegion();
111
112
public:
113
  ASTContext &getContext() const;
114
115
  virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
116
117
  virtual MemRegionManager &getMemRegionManager() const = 0;
118
119
  LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion *getMemorySpace() const;
120
121
  LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion *getBaseRegion() const;
122
123
  /// Recursively retrieve the region of the most derived class instance of
124
  /// regions of C++ base class instances.
125
  LLVM_ATTRIBUTE_RETURNS_NONNULL
126
  const MemRegion *getMostDerivedObjectRegion() const;
127
128
  /// Check if the region is a subregion of the given region.
129
  /// Each region is a subregion of itself.
130
  virtual bool isSubRegionOf(const MemRegion *R) const;
131
132
  LLVM_ATTRIBUTE_RETURNS_NONNULL
133
  const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const;
134
135
  /// If this is a symbolic region, returns the region. Otherwise,
136
  /// goes up the base chain looking for the first symbolic base region.
137
  /// It might return null.
138
  const SymbolicRegion *getSymbolicBase() const;
139
140
  bool hasStackStorage() const;
141
142
  bool hasStackNonParametersStorage() const;
143
144
  bool hasStackParametersStorage() const;
145
146
  /// Compute the offset within the top level memory object.
147
  RegionOffset getAsOffset() const;
148
149
  /// Get a string representation of a region for debug use.
150
  std::string getString() const;
151
152
  virtual void dumpToStream(raw_ostream &os) const;
153
154
  void dump() const;
155
156
  /// Returns true if this region can be printed in a user-friendly way.
157
  virtual bool canPrintPretty() const;
158
159
  /// Print the region for use in diagnostics.
160
  virtual void printPretty(raw_ostream &os) const;
161
162
  /// Returns true if this region's textual representation can be used
163
  /// as part of a larger expression.
164
  virtual bool canPrintPrettyAsExpr() const;
165
166
  /// Print the region as expression.
167
  ///
168
  /// When this region represents a subexpression, the method is for printing
169
  /// an expression containing it.
170
  virtual void printPrettyAsExpr(raw_ostream &os) const;
171
172
72.1M
  Kind getKind() const { return kind; }
173
174
  template<typename RegionTy> const RegionTy* getAs() const;
175
  template <typename RegionTy>
176
  LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *castAs() const;
177
178
0
  virtual bool isBoundable() const { return false; }
179
180
  /// Get descriptive name for memory region. The name is obtained from
181
  /// the variable/field declaration retrieved from the memory region.
182
  /// Regions that point to an element of an array are returned as: "arr[0]".
183
  /// Regions that point to a struct are returned as: "st.var".
184
  //
185
  /// \param UseQuotes Set if the name should be quoted.
186
  ///
187
  /// \returns variable name for memory region
188
  std::string getDescriptiveName(bool UseQuotes = true) const;
189
190
  /// Retrieve source range from memory region. The range retrieval
191
  /// is based on the decl obtained from the memory region.
192
  /// For a VarRegion the range of the base region is returned.
193
  /// For a FieldRegion the range of the field is returned.
194
  /// If no declaration is found, an empty source range is returned.
195
  /// The client is responsible for checking if the returned range is valid.
196
  ///
197
  /// \returns source range for declaration retrieved from memory region
198
  SourceRange sourceRange() const;
199
};
200
201
/// MemSpaceRegion - A memory region that represents a "memory space";
202
///  for example, the set of global variables, the stack frame, etc.
203
class MemSpaceRegion : public MemRegion {
204
protected:
205
  MemRegionManager &Mgr;
206
207
84.4k
  MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) {
208
84.4k
    assert(classof(this));
209
84.4k
  }
210
211
1.71M
  MemRegionManager &getMemRegionManager() const override { return Mgr; }
212
213
public:
214
53.5k
  bool isBoundable() const override { return false; }
215
216
  void Profile(llvm::FoldingSetNodeID &ID) const override;
217
218
6.02M
  static bool classof(const MemRegion *R) {
219
6.02M
    Kind k = R->getKind();
220
6.02M
    return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
221
6.02M
  }
222
};
223
224
/// CodeSpaceRegion - The memory space that holds the executable code of
225
/// functions and blocks.
226
class CodeSpaceRegion : public MemSpaceRegion {
227
  friend class MemRegionManager;
228
229
  CodeSpaceRegion(MemRegionManager &mgr)
230
11.4k
      : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
231
232
public:
233
  void dumpToStream(raw_ostream &os) const override;
234
235
0
  static bool classof(const MemRegion *R) {
236
0
    return R->getKind() == CodeSpaceRegionKind;
237
0
  }
238
};
239
240
class GlobalsSpaceRegion : public MemSpaceRegion {
241
  virtual void anchor();
242
243
protected:
244
17.2k
  GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) {
245
17.2k
    assert(classof(this));
246
17.2k
  }
247
248
public:
249
280k
  static bool classof(const MemRegion *R) {
250
280k
    Kind k = R->getKind();
251
280k
    return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
252
280k
  }
253
};
254
255
/// The region of the static variables within the current CodeTextRegion
256
/// scope.
257
///
258
/// Currently, only the static locals are placed there, so we know that these
259
/// variables do not get invalidated by calls to other functions.
260
class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
261
  friend class MemRegionManager;
262
263
  const CodeTextRegion *CR;
264
265
  StaticGlobalSpaceRegion(MemRegionManager &mgr, const CodeTextRegion *cr)
266
181
      : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
267
181
    assert(cr);
268
181
  }
269
270
public:
271
  void Profile(llvm::FoldingSetNodeID &ID) const override;
272
273
  void dumpToStream(raw_ostream &os) const override;
274
275
  LLVM_ATTRIBUTE_RETURNS_NONNULL
276
0
  const CodeTextRegion *getCodeRegion() const { return CR; }
277
278
16.7k
  static bool classof(const MemRegion *R) {
279
16.7k
    return R->getKind() == StaticGlobalSpaceRegionKind;
280
16.7k
  }
281
};
282
283
/// The region for all the non-static global variables.
284
///
285
/// This class is further split into subclasses for efficient implementation of
286
/// invalidating a set of related global values as is done in
287
/// RegionStoreManager::invalidateRegions (instead of finding all the dependent
288
/// globals, we invalidate the whole parent region).
289
class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
290
  void anchor() override;
291
292
protected:
293
  NonStaticGlobalSpaceRegion(MemRegionManager &mgr, Kind k)
294
17.1k
      : GlobalsSpaceRegion(mgr, k) {
295
17.1k
    assert(classof(this));
296
17.1k
  }
297
298
public:
299
774k
  static bool classof(const MemRegion *R) {
300
774k
    Kind k = R->getKind();
301
774k
    return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
302
774k
           k <= END_NON_STATIC_GLOBAL_MEMSPACES;
303
774k
  }
304
};
305
306
/// The region containing globals which are defined in system/external
307
/// headers and are considered modifiable by system calls (ex: errno).
308
class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
309
  friend class MemRegionManager;
310
311
  GlobalSystemSpaceRegion(MemRegionManager &mgr)
312
8.29k
      : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
313
314
public:
315
  void dumpToStream(raw_ostream &os) const override;
316
317
24.0k
  static bool classof(const MemRegion *R) {
318
24.0k
    return R->getKind() == GlobalSystemSpaceRegionKind;
319
24.0k
  }
320
};
321
322
/// The region containing globals which are considered not to be modified
323
/// or point to data which could be modified as a result of a function call
324
/// (system or internal). Ex: Const global scalars would be modeled as part of
325
/// this region. This region also includes most system globals since they have
326
/// low chance of being modified.
327
class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
328
  friend class MemRegionManager;
329
330
  GlobalImmutableSpaceRegion(MemRegionManager &mgr)
331
470
      : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
332
333
public:
334
  void dumpToStream(raw_ostream &os) const override;
335
336
384
  static bool classof(const MemRegion *R) {
337
384
    return R->getKind() == GlobalImmutableSpaceRegionKind;
338
384
  }
339
};
340
341
/// The region containing globals which can be modified by calls to
342
/// "internally" defined functions - (for now just) functions other then system
343
/// calls.
344
class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
345
  friend class MemRegionManager;
346
347
  GlobalInternalSpaceRegion(MemRegionManager &mgr)
348
8.33k
      : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
349
350
public:
351
  void dumpToStream(raw_ostream &os) const override;
352
353
13.3k
  static bool classof(const MemRegion *R) {
354
13.3k
    return R->getKind() == GlobalInternalSpaceRegionKind;
355
13.3k
  }
356
};
357
358
class HeapSpaceRegion : public MemSpaceRegion {
359
  friend class MemRegionManager;
360
361
  HeapSpaceRegion(MemRegionManager &mgr)
362
1.37k
      : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
363
364
public:
365
  void dumpToStream(raw_ostream &os) const override;
366
367
4.32k
  static bool classof(const MemRegion *R) {
368
4.32k
    return R->getKind() == HeapSpaceRegionKind;
369
4.32k
  }
370
};
371
372
class UnknownSpaceRegion : public MemSpaceRegion {
373
  friend class MemRegionManager;
374
375
  UnknownSpaceRegion(MemRegionManager &mgr)
376
9.74k
      : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
377
378
public:
379
  void dumpToStream(raw_ostream &os) const override;
380
381
117k
  static bool classof(const MemRegion *R) {
382
117k
    return R->getKind() == UnknownSpaceRegionKind;
383
117k
  }
384
};
385
386
class StackSpaceRegion : public MemSpaceRegion {
387
  virtual void anchor();
388
389
  const StackFrameContext *SFC;
390
391
protected:
392
  StackSpaceRegion(MemRegionManager &mgr, Kind k, const StackFrameContext *sfc)
393
44.6k
      : MemSpaceRegion(mgr, k), SFC(sfc) {
394
44.6k
    assert(classof(this));
395
44.6k
    assert(sfc);
396
44.6k
  }
397
398
public:
399
  LLVM_ATTRIBUTE_RETURNS_NONNULL
400
2.28M
  const StackFrameContext *getStackFrame() const { return SFC; }
401
402
  void Profile(llvm::FoldingSetNodeID &ID) const override;
403
404
2.54M
  static bool classof(const MemRegion *R) {
405
2.54M
    Kind k = R->getKind();
406
2.54M
    return k >= BEGIN_STACK_MEMSPACES && 
k <= END_STACK_MEMSPACES2.44M
;
407
2.54M
  }
408
};
409
410
class StackLocalsSpaceRegion : public StackSpaceRegion {
411
  friend class MemRegionManager;
412
413
  StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
414
13.6k
      : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
415
416
public:
417
  void dumpToStream(raw_ostream &os) const override;
418
419
78.9k
  static bool classof(const MemRegion *R) {
420
78.9k
    return R->getKind() == StackLocalsSpaceRegionKind;
421
78.9k
  }
422
};
423
424
class StackArgumentsSpaceRegion : public StackSpaceRegion {
425
private:
426
  friend class MemRegionManager;
427
428
  StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
429
31.0k
      : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
430
431
public:
432
  void dumpToStream(raw_ostream &os) const override;
433
434
414k
  static bool classof(const MemRegion *R) {
435
414k
    return R->getKind() == StackArgumentsSpaceRegionKind;
436
414k
  }
437
};
438
439
/// SubRegion - A region that subsets another larger region.  Most regions
440
///  are subclasses of SubRegion.
441
class SubRegion : public MemRegion {
442
  virtual void anchor();
443
444
protected:
445
  const MemRegion* superRegion;
446
447
171k
  SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
448
171k
    assert(classof(this));
449
171k
    assert(sReg);
450
171k
  }
451
452
public:
453
  LLVM_ATTRIBUTE_RETURNS_NONNULL
454
14.6M
  const MemRegion* getSuperRegion() const {
455
14.6M
    return superRegion;
456
14.6M
  }
457
458
  MemRegionManager &getMemRegionManager() const override;
459
460
  bool isSubRegionOf(const MemRegion* R) const override;
461
462
22.4M
  static bool classof(const MemRegion* R) {
463
22.4M
    return R->getKind() > END_MEMSPACES;
464
22.4M
  }
465
};
466
467
//===----------------------------------------------------------------------===//
468
// MemRegion subclasses.
469
//===----------------------------------------------------------------------===//
470
471
/// AllocaRegion - A region that represents an untyped blob of bytes created
472
///  by a call to 'alloca'.
473
class AllocaRegion : public SubRegion {
474
  friend class MemRegionManager;
475
476
  // Block counter. Used to distinguish different pieces of memory allocated by
477
  // alloca at the same call site.
478
  unsigned Cnt;
479
480
  const Expr *Ex;
481
482
  AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
483
93
      : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
484
93
    assert(Ex);
485
93
  }
486
487
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
488
                            unsigned Cnt, const MemRegion *superRegion);
489
490
public:
491
  LLVM_ATTRIBUTE_RETURNS_NONNULL
492
10
  const Expr *getExpr() const { return Ex; }
493
494
23
  bool isBoundable() const override { return true; }
495
496
  void Profile(llvm::FoldingSetNodeID& ID) const override;
497
498
  void dumpToStream(raw_ostream &os) const override;
499
500
93.0k
  static bool classof(const MemRegion* R) {
501
93.0k
    return R->getKind() == AllocaRegionKind;
502
93.0k
  }
503
};
504
505
/// TypedRegion - An abstract class representing regions that are typed.
506
class TypedRegion : public SubRegion {
507
  void anchor() override;
508
509
protected:
510
150k
  TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
511
150k
    assert(classof(this));
512
150k
  }
513
514
public:
515
  virtual QualType getLocationType() const = 0;
516
517
0
  QualType getDesugaredLocationType(ASTContext &Context) const {
518
0
    return getLocationType().getDesugaredType(Context);
519
0
  }
520
521
81.7k
  bool isBoundable() const override { return true; }
522
523
967k
  static bool classof(const MemRegion* R) {
524
967k
    unsigned k = R->getKind();
525
967k
    return k >= BEGIN_TYPED_REGIONS && 
k <= END_TYPED_REGIONS919k
;
526
967k
  }
527
};
528
529
/// TypedValueRegion - An abstract class representing regions having a typed value.
530
class TypedValueRegion : public TypedRegion {
531
  void anchor() override;
532
533
protected:
534
119k
  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
535
119k
    assert(classof(this));
536
119k
  }
537
538
public:
539
  virtual QualType getValueType() const = 0;
540
541
649k
  QualType getLocationType() const override {
542
    // FIXME: We can possibly optimize this later to cache this value.
543
649k
    QualType T = getValueType();
544
649k
    ASTContext &ctx = getContext();
545
649k
    if (T->getAs<ObjCObjectType>())
546
0
      return ctx.getObjCObjectPointerType(T);
547
649k
    return ctx.getPointerType(getValueType());
548
649k
  }
549
550
30.0k
  QualType getDesugaredValueType(ASTContext &Context) const {
551
30.0k
    QualType T = getValueType();
552
30.0k
    return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : 
T0
;
553
30.0k
  }
554
555
2.62M
  static bool classof(const MemRegion* R) {
556
2.62M
    unsigned k = R->getKind();
557
2.62M
    return k >= BEGIN_TYPED_VALUE_REGIONS && 
k <= END_TYPED_VALUE_REGIONS2.47M
;
558
2.62M
  }
559
};
560
561
class CodeTextRegion : public TypedRegion {
562
  void anchor() override;
563
564
protected:
565
30.9k
  CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
566
30.9k
    assert(classof(this));
567
30.9k
  }
568
569
public:
570
45
  bool isBoundable() const override { return false; }
571
572
59.2k
  static bool classof(const MemRegion* R) {
573
59.2k
    Kind k = R->getKind();
574
59.2k
    return k >= BEGIN_CODE_TEXT_REGIONS && 
k <= END_CODE_TEXT_REGIONS41.3k
;
575
59.2k
  }
576
};
577
578
/// FunctionCodeRegion - A region that represents code texts of function.
579
class FunctionCodeRegion : public CodeTextRegion {
580
  friend class MemRegionManager;
581
582
  const NamedDecl *FD;
583
584
  FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
585
30.5k
      : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
586
30.5k
    assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
587
30.5k
  }
588
589
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
590
                            const MemRegion*);
591
592
public:
593
145k
  QualType getLocationType() const override {
594
145k
    const ASTContext &Ctx = getContext();
595
145k
    if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
596
145k
      return Ctx.getPointerType(D->getType());
597
145k
    }
598
599
0
    assert(isa<ObjCMethodDecl>(FD));
600
0
    assert(false && "Getting the type of ObjCMethod is not supported yet");
601
602
    // TODO: We might want to return a different type here (ex: id (*ty)(...))
603
    //       depending on how it is used.
604
0
    return {};
605
0
  }
606
607
170k
  const NamedDecl *getDecl() const {
608
170k
    return FD;
609
170k
  }
610
611
  void dumpToStream(raw_ostream &os) const override;
612
613
  void Profile(llvm::FoldingSetNodeID& ID) const override;
614
615
938k
  static bool classof(const MemRegion* R) {
616
938k
    return R->getKind() == FunctionCodeRegionKind;
617
938k
  }
618
};
619
620
/// BlockCodeRegion - A region that represents code texts of blocks (closures).
621
///  Blocks are represented with two kinds of regions.  BlockCodeRegions
622
///  represent the "code", while BlockDataRegions represent instances of blocks,
623
///  which correspond to "code+data".  The distinction is important, because
624
///  like a closure a block captures the values of externally referenced
625
///  variables.
626
class BlockCodeRegion : public CodeTextRegion {
627
  friend class MemRegionManager;
628
629
  const BlockDecl *BD;
630
  AnalysisDeclContext *AC;
631
  CanQualType locTy;
632
633
  BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
634
                  AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
635
377
      : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
636
377
    assert(bd);
637
377
    assert(ac);
638
377
    assert(lTy->getTypePtr()->isBlockPointerType());
639
377
  }
640
641
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
642
                            CanQualType, const AnalysisDeclContext*,
643
                            const MemRegion*);
644
645
public:
646
436
  QualType getLocationType() const override {
647
436
    return locTy;
648
436
  }
649
650
  LLVM_ATTRIBUTE_RETURNS_NONNULL
651
4.59k
  const BlockDecl *getDecl() const {
652
4.59k
    return BD;
653
4.59k
  }
654
655
  LLVM_ATTRIBUTE_RETURNS_NONNULL
656
384
  AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
657
658
  void dumpToStream(raw_ostream &os) const override;
659
660
  void Profile(llvm::FoldingSetNodeID& ID) const override;
661
662
68
  static bool classof(const MemRegion* R) {
663
68
    return R->getKind() == BlockCodeRegionKind;
664
68
  }
665
};
666
667
/// BlockDataRegion - A region that represents a block instance.
668
///  Blocks are represented with two kinds of regions.  BlockCodeRegions
669
///  represent the "code", while BlockDataRegions represent instances of blocks,
670
///  which correspond to "code+data".  The distinction is important, because
671
///  like a closure a block captures the values of externally referenced
672
///  variables.
673
class BlockDataRegion : public TypedRegion {
674
  friend class MemRegionManager;
675
676
  const BlockCodeRegion *BC;
677
  const LocationContext *LC; // Can be null
678
  unsigned BlockCount;
679
  void *ReferencedVars = nullptr;
680
  void *OriginalVars = nullptr;
681
682
  BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
683
                  unsigned count, const MemSpaceRegion *sreg)
684
384
      : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
685
384
        BlockCount(count) {
686
384
    assert(bc);
687
384
    assert(bc->getDecl());
688
384
    assert(lc);
689
384
    assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
690
384
           isa<StackLocalsSpaceRegion>(sreg) ||
691
384
           isa<UnknownSpaceRegion>(sreg));
692
384
  }
693
694
  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
695
                            const LocationContext *, unsigned,
696
                            const MemRegion *);
697
698
public:
699
  LLVM_ATTRIBUTE_RETURNS_NONNULL
700
388
  const BlockCodeRegion *getCodeRegion() const { return BC; }
701
702
  LLVM_ATTRIBUTE_RETURNS_NONNULL
703
3.42k
  const BlockDecl *getDecl() const { return BC->getDecl(); }
704
705
436
  QualType getLocationType() const override { return BC->getLocationType(); }
706
707
  class referenced_vars_iterator {
708
    const MemRegion * const *R;
709
    const MemRegion * const *OriginalR;
710
711
  public:
712
    explicit referenced_vars_iterator(const MemRegion * const *r,
713
                                      const MemRegion * const *originalR)
714
6.30k
        : R(r), OriginalR(originalR) {}
715
716
    LLVM_ATTRIBUTE_RETURNS_NONNULL
717
3.08k
    const VarRegion *getCapturedRegion() const {
718
3.08k
      return cast<VarRegion>(*R);
719
3.08k
    }
720
721
    LLVM_ATTRIBUTE_RETURNS_NONNULL
722
753
    const VarRegion *getOriginalRegion() const {
723
753
      return cast<VarRegion>(*OriginalR);
724
753
    }
725
726
45
    bool operator==(const referenced_vars_iterator &I) const {
727
45
      assert((R == nullptr) == (I.R == nullptr));
728
45
      return I.R == R;
729
45
    }
730
731
6.06k
    bool operator!=(const referenced_vars_iterator &I) const {
732
6.06k
      assert((R == nullptr) == (I.R == nullptr));
733
6.06k
      return I.R != R;
734
6.06k
    }
735
736
2.93k
    referenced_vars_iterator &operator++() {
737
2.93k
      ++R;
738
2.93k
      ++OriginalR;
739
2.93k
      return *this;
740
2.93k
    }
741
742
    // This isn't really a conventional iterator.
743
    // We just implement the deref as a no-op for now to make range-based for
744
    // loops work.
745
3.10k
    const referenced_vars_iterator &operator*() const { return *this; }
746
  };
747
748
  /// Return the original region for a captured region, if
749
  /// one exists. It might return null.
750
  const VarRegion *getOriginalRegion(const VarRegion *VR) const;
751
752
  referenced_vars_iterator referenced_vars_begin() const;
753
  referenced_vars_iterator referenced_vars_end() const;
754
  llvm::iterator_range<referenced_vars_iterator> referenced_vars() const;
755
756
  void dumpToStream(raw_ostream &os) const override;
757
758
  void Profile(llvm::FoldingSetNodeID& ID) const override;
759
760
2.15M
  static bool classof(const MemRegion* R) {
761
2.15M
    return R->getKind() == BlockDataRegionKind;
762
2.15M
  }
763
764
private:
765
  void LazyInitializeReferencedVars();
766
  std::pair<const VarRegion *, const VarRegion *>
767
  getCaptureRegions(const VarDecl *VD);
768
};
769
770
/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
771
///  classes, SymbolicRegion represents a region that serves as an alias for
772
///  either a real region, a NULL pointer, etc.  It essentially is used to
773
///  map the concept of symbolic values into the domain of regions.  Symbolic
774
///  regions do not need to be typed.
775
class SymbolicRegion : public SubRegion {
776
  friend class MemRegionManager;
777
778
  const SymbolRef sym;
779
780
  SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
781
20.5k
      : SubRegion(sreg, SymbolicRegionKind), sym(s) {
782
    // Because pointer arithmetic is represented by ElementRegion layers,
783
    // the base symbol here should not contain any arithmetic.
784
20.5k
    assert(s && isa<SymbolData>(s));
785
20.5k
    assert(s->getType()->isAnyPointerType() ||
786
20.5k
           s->getType()->isReferenceType() ||
787
20.5k
           s->getType()->isBlockPointerType());
788
20.5k
    assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg) ||
789
20.5k
           isa<GlobalSystemSpaceRegion>(sreg));
790
20.5k
  }
791
792
public:
793
  /// It might return null.
794
2.03M
  SymbolRef getSymbol() const { return sym; }
795
796
  /// Gets the type of the wrapped symbol.
797
  /// This type might not be accurate at all times - it's just our best guess.
798
  /// Consider these cases:
799
  ///   void foo(void *data, char *str, base *obj) {...}
800
  /// The type of the pointee of `data` is of course not `void`, yet that's our
801
  /// best guess. `str` might point to any object and `obj` might point to some
802
  /// derived instance. `TypedRegions` other hand are representing the cases
803
  /// when we actually know their types.
804
12.1k
  QualType getPointeeStaticType() const {
805
12.1k
    return sym->getType()->getPointeeType();
806
12.1k
  }
807
808
5.83k
  bool isBoundable() const override { return true; }
809
810
  void Profile(llvm::FoldingSetNodeID& ID) const override;
811
812
  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
813
                            SymbolRef sym,
814
                            const MemRegion* superRegion);
815
816
  void dumpToStream(raw_ostream &os) const override;
817
818
8.30M
  static bool classof(const MemRegion* R) {
819
8.30M
    return R->getKind() == SymbolicRegionKind;
820
8.30M
  }
821
};
822
823
/// StringRegion - Region associated with a StringLiteral.
824
class StringRegion : public TypedValueRegion {
825
  friend class MemRegionManager;
826
827
  const StringLiteral *Str;
828
829
  StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
830
5.35k
      : TypedValueRegion(sreg, StringRegionKind), Str(str) {
831
5.35k
    assert(str);
832
5.35k
  }
833
834
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
835
                            const StringLiteral *Str,
836
                            const MemRegion *superRegion);
837
838
public:
839
  LLVM_ATTRIBUTE_RETURNS_NONNULL
840
3.41k
  const StringLiteral *getStringLiteral() const { return Str; }
841
842
6.76k
  QualType getValueType() const override { return Str->getType(); }
843
844
577
  bool isBoundable() const override { return false; }
845
846
8.60k
  void Profile(llvm::FoldingSetNodeID& ID) const override {
847
8.60k
    ProfileRegion(ID, Str, superRegion);
848
8.60k
  }
849
850
  void dumpToStream(raw_ostream &os) const override;
851
852
45.0k
  static bool classof(const MemRegion* R) {
853
45.0k
    return R->getKind() == StringRegionKind;
854
45.0k
  }
855
};
856
857
/// The region associated with an ObjCStringLiteral.
858
class ObjCStringRegion : public TypedValueRegion {
859
  friend class MemRegionManager;
860
861
  const ObjCStringLiteral *Str;
862
863
  ObjCStringRegion(const ObjCStringLiteral *str,
864
                   const GlobalInternalSpaceRegion *sreg)
865
288
      : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
866
288
    assert(str);
867
288
  }
868
869
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
870
                            const ObjCStringLiteral *Str,
871
                            const MemRegion *superRegion);
872
873
public:
874
  LLVM_ATTRIBUTE_RETURNS_NONNULL
875
17
  const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
876
877
1.57k
  QualType getValueType() const override { return Str->getType(); }
878
879
299
  bool isBoundable() const override { return false; }
880
881
919
  void Profile(llvm::FoldingSetNodeID& ID) const override {
882
919
    ProfileRegion(ID, Str, superRegion);
883
919
  }
884
885
  void dumpToStream(raw_ostream &os) const override;
886
887
1.69k
  static bool classof(const MemRegion* R) {
888
1.69k
    return R->getKind() == ObjCStringRegionKind;
889
1.69k
  }
890
};
891
892
/// CompoundLiteralRegion - A memory region representing a compound literal.
893
///   Compound literals are essentially temporaries that are stack allocated
894
///   or in the global constant pool.
895
class CompoundLiteralRegion : public TypedValueRegion {
896
  friend class MemRegionManager;
897
898
  const CompoundLiteralExpr *CL;
899
900
  CompoundLiteralRegion(const CompoundLiteralExpr *cl,
901
                        const MemSpaceRegion *sReg)
902
59
      : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
903
59
    assert(cl);
904
59
    assert(isa<GlobalInternalSpaceRegion>(sReg) ||
905
59
           isa<StackLocalsSpaceRegion>(sReg));
906
59
  }
907
908
  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
909
                            const CompoundLiteralExpr *CL,
910
                            const MemRegion* superRegion);
911
912
public:
913
224
  QualType getValueType() const override { return CL->getType(); }
914
915
0
  bool isBoundable() const override { return !CL->isFileScope(); }
916
917
  void Profile(llvm::FoldingSetNodeID& ID) const override;
918
919
  void dumpToStream(raw_ostream &os) const override;
920
921
  LLVM_ATTRIBUTE_RETURNS_NONNULL
922
3
  const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
923
924
124
  static bool classof(const MemRegion* R) {
925
124
    return R->getKind() == CompoundLiteralRegionKind;
926
124
  }
927
};
928
929
class DeclRegion : public TypedValueRegion {
930
protected:
931
73.6k
  DeclRegion(const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k) {
932
73.6k
    assert(classof(this));
933
73.6k
  }
934
935
public:
936
  // TODO what does this return?
937
  virtual const ValueDecl *getDecl() const = 0;
938
939
75.8k
  static bool classof(const MemRegion* R) {
940
75.8k
    unsigned k = R->getKind();
941
75.8k
    return k >= BEGIN_DECL_REGIONS && 
k <= END_DECL_REGIONS75.6k
;
942
75.8k
  }
943
};
944
945
class VarRegion : public DeclRegion {
946
  friend class MemRegionManager;
947
948
protected:
949
  // Constructors and protected methods.
950
54.3k
  VarRegion(const MemRegion *sReg, Kind k) : DeclRegion(sReg, k) {
951
    // VarRegion appears in unknown space when it's a block variable as seen
952
    // from a block using it, when this block is analyzed at top-level.
953
    // Other block variables appear within block data regions,
954
    // which, unlike everything else on this list, are not memory spaces.
955
54.3k
    assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
956
54.3k
           isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
957
54.3k
  }
958
959
public:
960
  // TODO what does this return?
961
  const VarDecl *getDecl() const override = 0;
962
963
  /// It might return null.
964
  const StackFrameContext *getStackFrame() const;
965
966
0
  QualType getValueType() const override {
967
    // FIXME: We can cache this if needed.
968
0
    return getDecl()->getType();
969
0
  }
970
971
3.07M
  static bool classof(const MemRegion *R) {
972
3.07M
    unsigned k = R->getKind();
973
3.07M
    return k >= BEGIN_VAR_REGIONS && 
k <= END_VAR_REGIONS2.19M
;
974
3.07M
  }
975
};
976
977
class NonParamVarRegion : public VarRegion {
978
  friend class MemRegionManager;
979
980
  const VarDecl *VD;
981
982
  // Constructors and private methods.
983
  NonParamVarRegion(const VarDecl *vd, const MemRegion *sReg)
984
34.9k
      : VarRegion(sReg, NonParamVarRegionKind), VD(vd) {
985
    // VarRegion appears in unknown space when it's a block variable as seen
986
    // from a block using it, when this block is analyzed at top-level.
987
    // Other block variables appear within block data regions,
988
    // which, unlike everything else on this list, are not memory spaces.
989
34.9k
    assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
990
34.9k
           isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
991
34.9k
    assert(vd);
992
34.9k
  }
993
994
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const VarDecl *VD,
995
                            const MemRegion *superRegion);
996
997
public:
998
  void Profile(llvm::FoldingSetNodeID &ID) const override;
999
1000
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1001
9.95M
  const VarDecl *getDecl() const override { return VD; }
1002
1003
8.68M
  QualType getValueType() const override {
1004
    // FIXME: We can cache this if needed.
1005
8.68M
    return getDecl()->getType();
1006
8.68M
  }
1007
1008
  void dumpToStream(raw_ostream &os) const override;
1009
1010
  bool canPrintPrettyAsExpr() const override;
1011
1012
  void printPrettyAsExpr(raw_ostream &os) const override;
1013
1014
489k
  static bool classof(const MemRegion* R) {
1015
489k
    return R->getKind() == NonParamVarRegionKind;
1016
489k
  }
1017
};
1018
1019
/// ParamVarRegion - Represents a region for paremters. Only parameters of the
1020
/// function in the current stack frame are represented as `ParamVarRegion`s.
1021
/// Parameters of top-level analyzed functions as well as captured paremeters
1022
/// by lambdas and blocks are repesented as `VarRegion`s.
1023
1024
// FIXME: `ParamVarRegion` only supports parameters of functions, C++
1025
// constructors, blocks and Objective-C methods with existing `Decl`. Upon
1026
// implementing stack frame creations for functions without decl (functions
1027
// passed by unknown function pointer) methods of `ParamVarRegion` must be
1028
// updated.
1029
class ParamVarRegion : public VarRegion {
1030
  friend class MemRegionManager;
1031
1032
  const Expr *OriginExpr;
1033
  unsigned Index;
1034
1035
  ParamVarRegion(const Expr *OE, unsigned Idx, const MemRegion *SReg)
1036
19.3k
      : VarRegion(SReg, ParamVarRegionKind), OriginExpr(OE), Index(Idx) {
1037
19.3k
    assert(!cast<StackSpaceRegion>(SReg)->getStackFrame()->inTopFrame());
1038
19.3k
    assert(OriginExpr);
1039
19.3k
  }
1040
1041
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
1042
                            unsigned Idx, const MemRegion *SReg);
1043
1044
public:
1045
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1046
127k
  const Expr *getOriginExpr() const { return OriginExpr; }
1047
127k
  unsigned getIndex() const { return Index; }
1048
1049
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1050
1051
  void dumpToStream(raw_ostream &os) const override;
1052
1053
  QualType getValueType() const override;
1054
1055
  /// TODO: What does this return?
1056
  const ParmVarDecl *getDecl() const override;
1057
1058
  bool canPrintPrettyAsExpr() const override;
1059
  void printPrettyAsExpr(raw_ostream &os) const override;
1060
1061
131k
  static bool classof(const MemRegion *R) {
1062
131k
    return R->getKind() == ParamVarRegionKind;
1063
131k
  }
1064
};
1065
1066
/// CXXThisRegion - Represents the region for the implicit 'this' parameter
1067
///  in a call to a C++ method.  This region doesn't represent the object
1068
///  referred to by 'this', but rather 'this' itself.
1069
class CXXThisRegion : public TypedValueRegion {
1070
  friend class MemRegionManager;
1071
1072
  CXXThisRegion(const PointerType *thisPointerTy,
1073
                const StackArgumentsSpaceRegion *sReg)
1074
14.5k
      : TypedValueRegion(sReg, CXXThisRegionKind),
1075
14.5k
        ThisPointerTy(thisPointerTy) {
1076
14.5k
    assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
1077
14.5k
           "Invalid region type!");
1078
14.5k
  }
1079
1080
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1081
                            const PointerType *PT,
1082
                            const MemRegion *sReg);
1083
1084
public:
1085
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1086
1087
186k
  QualType getValueType() const override {
1088
186k
    return QualType(ThisPointerTy, 0);
1089
186k
  }
1090
1091
  void dumpToStream(raw_ostream &os) const override;
1092
1093
505k
  static bool classof(const MemRegion* R) {
1094
505k
    return R->getKind() == CXXThisRegionKind;
1095
505k
  }
1096
1097
private:
1098
  const PointerType *ThisPointerTy;
1099
};
1100
1101
class FieldRegion : public DeclRegion {
1102
  friend class MemRegionManager;
1103
1104
  const FieldDecl *FD;
1105
1106
  FieldRegion(const FieldDecl *fd, const SubRegion *sReg)
1107
18.6k
      : DeclRegion(sReg, FieldRegionKind), FD(fd) {
1108
18.6k
    assert(FD);
1109
18.6k
  }
1110
1111
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD,
1112
273k
                            const MemRegion* superRegion) {
1113
273k
    ID.AddInteger(static_cast<unsigned>(FieldRegionKind));
1114
273k
    ID.AddPointer(FD);
1115
273k
    ID.AddPointer(superRegion);
1116
273k
  }
1117
1118
public:
1119
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1120
2.06M
  const FieldDecl *getDecl() const override { return FD; }
1121
1122
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1123
1124
1.76M
  QualType getValueType() const override {
1125
    // FIXME: We can cache this if needed.
1126
1.76M
    return getDecl()->getType();
1127
1.76M
  }
1128
1129
  void dumpToStream(raw_ostream &os) const override;
1130
1131
  bool canPrintPretty() const override;
1132
  void printPretty(raw_ostream &os) const override;
1133
  bool canPrintPrettyAsExpr() const override;
1134
  void printPrettyAsExpr(raw_ostream &os) const override;
1135
1136
1.02M
  static bool classof(const MemRegion* R) {
1137
1.02M
    return R->getKind() == FieldRegionKind;
1138
1.02M
  }
1139
};
1140
1141
class ObjCIvarRegion : public DeclRegion {
1142
  friend class MemRegionManager;
1143
1144
  const ObjCIvarDecl *IVD;
1145
1146
  ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1147
1148
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1149
                            const MemRegion* superRegion);
1150
1151
public:
1152
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1153
  const ObjCIvarDecl *getDecl() const override;
1154
1155
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1156
1157
  QualType getValueType() const override;
1158
1159
  bool canPrintPrettyAsExpr() const override;
1160
  void printPrettyAsExpr(raw_ostream &os) const override;
1161
1162
  void dumpToStream(raw_ostream &os) const override;
1163
1164
532k
  static bool classof(const MemRegion* R) {
1165
532k
    return R->getKind() == ObjCIvarRegionKind;
1166
532k
  }
1167
};
1168
1169
//===----------------------------------------------------------------------===//
1170
// Auxiliary data classes for use with MemRegions.
1171
//===----------------------------------------------------------------------===//
1172
1173
class RegionRawOffset {
1174
  friend class ElementRegion;
1175
1176
  const MemRegion *Region;
1177
  CharUnits Offset;
1178
1179
  RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
1180
27.5k
      : Region(reg), Offset(offset) {}
1181
1182
public:
1183
  // FIXME: Eventually support symbolic offsets.
1184
511
  CharUnits getOffset() const { return Offset; }
1185
1186
  // It might return null.
1187
45.3k
  const MemRegion *getRegion() const { return Region; }
1188
1189
  void dumpToStream(raw_ostream &os) const;
1190
  void dump() const;
1191
};
1192
1193
/// ElementRegion is used to represent both array elements and casts.
1194
class ElementRegion : public TypedValueRegion {
1195
  friend class MemRegionManager;
1196
1197
  QualType ElementType;
1198
  NonLoc Index;
1199
1200
  ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1201
21.0k
      : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1202
21.0k
        Index(Idx) {
1203
21.0k
    assert((!isa<nonloc::ConcreteInt>(Idx) ||
1204
21.0k
            Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
1205
21.0k
           "The index must be signed");
1206
21.0k
    assert(!elementType.isNull() && !elementType->isVoidType() &&
1207
21.0k
           "Invalid region type!");
1208
21.0k
  }
1209
1210
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1211
                            SVal Idx, const MemRegion* superRegion);
1212
1213
public:
1214
436k
  NonLoc getIndex() const { return Index; }
1215
1216
720k
  QualType getValueType() const override { return ElementType; }
1217
1218
54.4k
  QualType getElementType() const { return ElementType; }
1219
1220
  /// Compute the offset within the array. The array might also be a subobject.
1221
  RegionRawOffset getAsArrayOffset() const;
1222
1223
  void dumpToStream(raw_ostream &os) const override;
1224
1225
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1226
1227
4.75M
  static bool classof(const MemRegion* R) {
1228
4.75M
    return R->getKind() == ElementRegionKind;
1229
4.75M
  }
1230
};
1231
1232
// C++ temporary object associated with an expression.
1233
class CXXTempObjectRegion : public TypedValueRegion {
1234
  friend class MemRegionManager;
1235
1236
  Expr const *Ex;
1237
1238
  CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1239
2.75k
      : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1240
2.75k
    assert(E);
1241
2.75k
    assert(isa<StackLocalsSpaceRegion>(sReg));
1242
2.75k
  }
1243
1244
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1245
                            Expr const *E, const MemRegion *sReg);
1246
1247
public:
1248
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1249
38
  const Expr *getExpr() const { return Ex; }
1250
1251
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1252
  const StackFrameContext *getStackFrame() const;
1253
1254
40.1k
  QualType getValueType() const override { return Ex->getType(); }
1255
1256
  void dumpToStream(raw_ostream &os) const override;
1257
1258
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1259
1260
7.10k
  static bool classof(const MemRegion* R) {
1261
7.10k
    return R->getKind() == CXXTempObjectRegionKind;
1262
7.10k
  }
1263
};
1264
1265
// C++ temporary object that have lifetime extended to lifetime of the
1266
// variable. Usually they represent temporary bounds to reference variables.
1267
class CXXLifetimeExtendedObjectRegion : public TypedValueRegion {
1268
  friend class MemRegionManager;
1269
1270
  Expr const *Ex;
1271
  ValueDecl const *ExD;
1272
1273
  CXXLifetimeExtendedObjectRegion(Expr const *E, ValueDecl const *D,
1274
                                  MemSpaceRegion const *sReg)
1275
336
      : TypedValueRegion(sReg, CXXLifetimeExtendedObjectRegionKind), Ex(E),
1276
336
        ExD(D) {
1277
336
    assert(E);
1278
336
    assert(D);
1279
336
    assert((isa<StackLocalsSpaceRegion, GlobalInternalSpaceRegion>(sReg)));
1280
336
  }
1281
1282
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, Expr const *E,
1283
                            ValueDecl const *D, const MemRegion *sReg);
1284
1285
public:
1286
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1287
3
  const Expr *getExpr() const { return Ex; }
1288
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1289
3
  const ValueDecl *getExtendingDecl() const { return ExD; }
1290
  /// It might return null.
1291
  const StackFrameContext *getStackFrame() const;
1292
1293
7.08k
  QualType getValueType() const override { return Ex->getType(); }
1294
1295
  void dumpToStream(raw_ostream &os) const override;
1296
1297
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1298
1299
13.1k
  static bool classof(const MemRegion *R) {
1300
13.1k
    return R->getKind() == CXXLifetimeExtendedObjectRegionKind;
1301
13.1k
  }
1302
};
1303
1304
// CXXBaseObjectRegion represents a base object within a C++ object. It is
1305
// identified by the base class declaration and the region of its parent object.
1306
class CXXBaseObjectRegion : public TypedValueRegion {
1307
  friend class MemRegionManager;
1308
1309
  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1310
1311
  CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1312
                      const SubRegion *SReg)
1313
1.12k
      : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1314
1.12k
    assert(RD);
1315
1.12k
  }
1316
1317
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1318
                            bool IsVirtual, const MemRegion *SReg);
1319
1320
public:
1321
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1322
10.4k
  const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1323
3.18k
  bool isVirtual() const { return Data.getInt(); }
1324
1325
  QualType getValueType() const override;
1326
1327
  void dumpToStream(raw_ostream &os) const override;
1328
1329
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1330
1331
  bool canPrintPrettyAsExpr() const override;
1332
1333
  void printPrettyAsExpr(raw_ostream &os) const override;
1334
1335
135k
  static bool classof(const MemRegion *region) {
1336
135k
    return region->getKind() == CXXBaseObjectRegionKind;
1337
135k
  }
1338
};
1339
1340
// CXXDerivedObjectRegion represents a derived-class object that surrounds
1341
// a C++ object. It is identified by the derived class declaration and the
1342
// region of its parent object. It is a bit counter-intuitive (but not otherwise
1343
// unseen) that this region represents a larger segment of memory that its
1344
// super-region.
1345
class CXXDerivedObjectRegion : public TypedValueRegion {
1346
  friend class MemRegionManager;
1347
1348
  const CXXRecordDecl *DerivedD;
1349
1350
  CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1351
24
      : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1352
24
    assert(DerivedD);
1353
    // In case of a concrete region, it should always be possible to model
1354
    // the base-to-derived cast by undoing a previous derived-to-base cast,
1355
    // otherwise the cast is most likely ill-formed.
1356
24
    assert(SReg->getSymbolicBase() &&
1357
24
           "Should have unwrapped a base region instead!");
1358
24
  }
1359
1360
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1361
                            const MemRegion *SReg);
1362
1363
public:
1364
  LLVM_ATTRIBUTE_RETURNS_NONNULL
1365
527
  const CXXRecordDecl *getDecl() const { return DerivedD; }
1366
1367
  QualType getValueType() const override;
1368
1369
  void dumpToStream(raw_ostream &os) const override;
1370
1371
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1372
1373
  bool canPrintPrettyAsExpr() const override;
1374
1375
  void printPrettyAsExpr(raw_ostream &os) const override;
1376
1377
2.16k
  static bool classof(const MemRegion *region) {
1378
2.16k
    return region->getKind() == CXXDerivedObjectRegionKind;
1379
2.16k
  }
1380
};
1381
1382
template<typename RegionTy>
1383
254k
const RegionTy* MemRegion::getAs() const {
1384
254k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
194k
    return RT;
1386
1387
59.3k
  return nullptr;
1388
254k
}
clang::ento::VarRegion const* clang::ento::MemRegion::getAs<clang::ento::VarRegion>() const
Line
Count
Source
1383
891
const RegionTy* MemRegion::getAs() const {
1384
891
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
851
    return RT;
1386
1387
40
  return nullptr;
1388
891
}
clang::ento::CXXTempObjectRegion const* clang::ento::MemRegion::getAs<clang::ento::CXXTempObjectRegion>() const
Line
Count
Source
1383
3.46k
const RegionTy* MemRegion::getAs() const {
1384
3.46k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
300
    return RT;
1386
1387
3.16k
  return nullptr;
1388
3.46k
}
clang::ento::MemRegion const* clang::ento::MemRegion::getAs<clang::ento::MemRegion>() const
Line
Count
Source
1383
18
const RegionTy* MemRegion::getAs() const {
1384
18
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
18
    return RT;
1386
1387
0
  return nullptr;
1388
18
}
clang::ento::FieldRegion const* clang::ento::MemRegion::getAs<clang::ento::FieldRegion>() const
Line
Count
Source
1383
87
const RegionTy* MemRegion::getAs() const {
1384
87
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
25
    return RT;
1386
1387
62
  return nullptr;
1388
87
}
clang::ento::StackSpaceRegion const* clang::ento::MemRegion::getAs<clang::ento::StackSpaceRegion>() const
Line
Count
Source
1383
174k
const RegionTy* MemRegion::getAs() const {
1384
174k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
144k
    return RT;
1386
1387
30.5k
  return nullptr;
1388
174k
}
clang::ento::DeclRegion const* clang::ento::MemRegion::getAs<clang::ento::DeclRegion>() const
Line
Count
Source
1383
340
const RegionTy* MemRegion::getAs() const {
1384
340
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
137
    return RT;
1386
1387
203
  return nullptr;
1388
340
}
clang::ento::SubRegion const* clang::ento::MemRegion::getAs<clang::ento::SubRegion>() const
Line
Count
Source
1383
9.53k
const RegionTy* MemRegion::getAs() const {
1384
9.53k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
9.53k
    return RT;
1386
1387
0
  return nullptr;
1388
9.53k
}
clang::ento::TypedValueRegion const* clang::ento::MemRegion::getAs<clang::ento::TypedValueRegion>() const
Line
Count
Source
1383
946
const RegionTy* MemRegion::getAs() const {
1384
946
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
851
    return RT;
1386
1387
95
  return nullptr;
1388
946
}
clang::ento::SymbolicRegion const* clang::ento::MemRegion::getAs<clang::ento::SymbolicRegion>() const
Line
Count
Source
1383
36.9k
const RegionTy* MemRegion::getAs() const {
1384
36.9k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
13.4k
    return RT;
1386
1387
23.4k
  return nullptr;
1388
36.9k
}
clang::ento::ElementRegion const* clang::ento::MemRegion::getAs<clang::ento::ElementRegion>() const
Line
Count
Source
1383
776
const RegionTy* MemRegion::getAs() const {
1384
776
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
71
    return RT;
1386
1387
705
  return nullptr;
1388
776
}
clang::ento::FunctionCodeRegion const* clang::ento::MemRegion::getAs<clang::ento::FunctionCodeRegion>() const
Line
Count
Source
1383
26.4k
const RegionTy* MemRegion::getAs() const {
1384
26.4k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1385
25.3k
    return RT;
1386
1387
1.04k
  return nullptr;
1388
26.4k
}
1389
1390
template <typename RegionTy>
1391
2
LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *MemRegion::castAs() const {
1392
2
  return cast<RegionTy>(this);
1393
2
}
1394
1395
//===----------------------------------------------------------------------===//
1396
// MemRegionManager - Factory object for creating regions.
1397
//===----------------------------------------------------------------------===//
1398
1399
class MemRegionManager {
1400
  ASTContext &Ctx;
1401
  llvm::BumpPtrAllocator& A;
1402
1403
  llvm::FoldingSet<MemRegion> Regions;
1404
1405
  GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1406
  GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1407
  GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1408
1409
  llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1410
    StackLocalsSpaceRegions;
1411
  llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1412
    StackArgumentsSpaceRegions;
1413
  llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1414
    StaticsGlobalSpaceRegions;
1415
1416
  HeapSpaceRegion *heap = nullptr;
1417
  UnknownSpaceRegion *unknown = nullptr;
1418
  CodeSpaceRegion *code = nullptr;
1419
1420
public:
1421
16.2k
  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {}
1422
  ~MemRegionManager();
1423
1424
1.68M
  ASTContext &getContext() { return Ctx; }
1425
0
  const ASTContext &getContext() const { return Ctx; }
1426
1427
245
  llvm::BumpPtrAllocator &getAllocator() { return A; }
1428
1429
  /// \returns The static size in bytes of the region \p MR.
1430
  /// \note The region \p MR must be a 'SubRegion'.
1431
  DefinedOrUnknownSVal getStaticSize(const MemRegion *MR,
1432
                                     SValBuilder &SVB) const;
1433
1434
  /// getStackLocalsRegion - Retrieve the memory region associated with the
1435
  ///  specified stack frame.
1436
  const StackLocalsSpaceRegion *
1437
  getStackLocalsRegion(const StackFrameContext *STC);
1438
1439
  /// getStackArgumentsRegion - Retrieve the memory region associated with
1440
  ///  function/method arguments of the specified stack frame.
1441
  const StackArgumentsSpaceRegion *
1442
  getStackArgumentsRegion(const StackFrameContext *STC);
1443
1444
  /// getGlobalsRegion - Retrieve the memory region associated with
1445
  ///  global variables.
1446
  const GlobalsSpaceRegion *getGlobalsRegion(
1447
      MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1448
      const CodeTextRegion *R = nullptr);
1449
1450
  /// getHeapRegion - Retrieve the memory region associated with the
1451
  ///  generic "heap".
1452
  const HeapSpaceRegion *getHeapRegion();
1453
1454
  /// getUnknownRegion - Retrieve the memory region associated with unknown
1455
  /// memory space.
1456
  const UnknownSpaceRegion *getUnknownRegion();
1457
1458
  const CodeSpaceRegion *getCodeRegion();
1459
1460
  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1461
  const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1462
                                      const LocationContext *LC);
1463
1464
  /// getCompoundLiteralRegion - Retrieve the region associated with a
1465
  ///  given CompoundLiteral.
1466
  const CompoundLiteralRegion*
1467
  getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1468
                           const LocationContext *LC);
1469
1470
  /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1471
  ///  parameter 'this'.
1472
  const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1473
                                        const LocationContext *LC);
1474
1475
  /// Retrieve or create a "symbolic" memory region.
1476
  /// If no memory space is specified, `UnknownSpaceRegion` will be used.
1477
  const SymbolicRegion *
1478
  getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace = nullptr);
1479
1480
  /// Return a unique symbolic region belonging to heap memory space.
1481
  const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1482
1483
  const StringRegion *getStringRegion(const StringLiteral *Str);
1484
1485
  const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1486
1487
  /// getVarRegion - Retrieve or create the memory region associated with
1488
  ///  a specified VarDecl and LocationContext.
1489
  const VarRegion *getVarRegion(const VarDecl *VD, const LocationContext *LC);
1490
1491
  /// getVarRegion - Retrieve or create the memory region associated with
1492
  ///  a specified VarDecl and LocationContext.
1493
  const NonParamVarRegion *getNonParamVarRegion(const VarDecl *VD,
1494
                                                const MemRegion *superR);
1495
1496
  /// getParamVarRegion - Retrieve or create the memory region
1497
  /// associated with a specified CallExpr, Index and LocationContext.
1498
  const ParamVarRegion *getParamVarRegion(const Expr *OriginExpr,
1499
                                          unsigned Index,
1500
                                          const LocationContext *LC);
1501
1502
  /// getElementRegion - Retrieve the memory region associated with the
1503
  ///  associated element type, index, and super region.
1504
  const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1505
                                        const SubRegion *superRegion,
1506
                                        ASTContext &Ctx);
1507
1508
  const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1509
471
                                                 const SubRegion *superRegion) {
1510
471
    return getElementRegion(ER->getElementType(), ER->getIndex(),
1511
471
                            superRegion, ER->getContext());
1512
471
  }
1513
1514
  /// getFieldRegion - Retrieve or create the memory region associated with
1515
  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1516
  ///  memory region (which typically represents the memory representing
1517
  ///  a structure or class).
1518
  const FieldRegion *getFieldRegion(const FieldDecl *fd,
1519
                                    const SubRegion* superRegion);
1520
1521
  const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1522
949
                                             const SubRegion *superRegion) {
1523
949
    return getFieldRegion(FR->getDecl(), superRegion);
1524
949
  }
1525
1526
  /// getObjCIvarRegion - Retrieve or create the memory region associated with
1527
  ///   a specified Objective-c instance variable.  'superRegion' corresponds
1528
  ///   to the containing region (which typically represents the Objective-C
1529
  ///   object).
1530
  const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1531
                                          const SubRegion* superRegion);
1532
1533
  const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1534
                                                    LocationContext const *LC);
1535
1536
  /// Create a CXXLifetimeExtendedObjectRegion for temporaries which are
1537
  /// lifetime-extended by local references.
1538
  const CXXLifetimeExtendedObjectRegion *
1539
  getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD,
1540
                                     LocationContext const *LC);
1541
1542
  /// Create a CXXLifetimeExtendedObjectRegion for temporaries which are
1543
  /// lifetime-extended by *static* references.
1544
  /// This differs from \ref getCXXLifetimeExtendedObjectRegion(Expr const *,
1545
  /// ValueDecl const *, LocationContext const *) in the super-region used.
1546
  const CXXLifetimeExtendedObjectRegion *
1547
  getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD);
1548
1549
  /// Create a CXXBaseObjectRegion with the given base class for region
1550
  /// \p Super.
1551
  ///
1552
  /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1553
  const CXXBaseObjectRegion *
1554
  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1555
                         bool IsVirtual);
1556
1557
  /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1558
  /// super region.
1559
  const CXXBaseObjectRegion *
1560
  getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1561
46
                                  const SubRegion *superRegion) {
1562
46
    return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1563
46
                                  baseReg->isVirtual());
1564
46
  }
1565
1566
  /// Create a CXXDerivedObjectRegion with the given derived class for region
1567
  /// \p Super. This should not be used for casting an existing
1568
  /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
1569
  /// should be removed.
1570
  const CXXDerivedObjectRegion *
1571
  getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1572
                            const SubRegion *Super);
1573
1574
  const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1575
  const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1576
                                            CanQualType locTy,
1577
                                            AnalysisDeclContext *AC);
1578
1579
  /// getBlockDataRegion - Get the memory region associated with an instance
1580
  ///  of a block.  Unlike many other MemRegions, the LocationContext*
1581
  ///  argument is allowed to be NULL for cases where we have no known
1582
  ///  context.
1583
  const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1584
                                            const LocationContext *lc,
1585
                                            unsigned blockCount);
1586
1587
private:
1588
  template <typename RegionTy, typename SuperTy,
1589
            typename Arg1Ty>
1590
  RegionTy* getSubRegion(const Arg1Ty arg1,
1591
                         const SuperTy* superRegion);
1592
1593
  template <typename RegionTy, typename SuperTy,
1594
            typename Arg1Ty, typename Arg2Ty>
1595
  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1596
                         const SuperTy* superRegion);
1597
1598
  template <typename RegionTy, typename SuperTy,
1599
            typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1600
  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1601
                         const Arg3Ty arg3,
1602
                         const SuperTy* superRegion);
1603
1604
  template <typename REG>
1605
  const REG* LazyAllocate(REG*& region);
1606
1607
  template <typename REG, typename ARG>
1608
  const REG* LazyAllocate(REG*& region, ARG a);
1609
};
1610
1611
//===----------------------------------------------------------------------===//
1612
// Out-of-line member definitions.
1613
//===----------------------------------------------------------------------===//
1614
1615
863k
inline ASTContext &MemRegion::getContext() const {
1616
863k
  return getMemRegionManager().getContext();
1617
863k
}
1618
1619
//===----------------------------------------------------------------------===//
1620
// Means for storing region/symbol handling traits.
1621
//===----------------------------------------------------------------------===//
1622
1623
/// Information about invalidation for a particular region/symbol.
1624
class RegionAndSymbolInvalidationTraits {
1625
  using StorageTypeForKinds = unsigned char;
1626
1627
  llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1628
  llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1629
1630
  using const_region_iterator =
1631
      llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1632
  using const_symbol_iterator =
1633
      llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1634
1635
public:
1636
  /// Describes different invalidation traits.
1637
  enum InvalidationKinds {
1638
    /// Tells that a region's contents is not changed.
1639
    TK_PreserveContents = 0x1,
1640
1641
    /// Suppress pointer-escaping of a region.
1642
    TK_SuppressEscape = 0x2,
1643
1644
    // Do not invalidate super region.
1645
    TK_DoNotInvalidateSuperRegion = 0x4,
1646
1647
    /// When applied to a MemSpaceRegion, indicates the entire memory space
1648
    /// should be invalidated.
1649
    TK_EntireMemSpace = 0x8
1650
1651
    // Do not forget to extend StorageTypeForKinds if number of traits exceed
1652
    // the number of bits StorageTypeForKinds can store.
1653
  };
1654
1655
  void setTrait(SymbolRef Sym, InvalidationKinds IK);
1656
  void setTrait(const MemRegion *MR, InvalidationKinds IK);
1657
  bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1658
  bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1659
};
1660
1661
//===----------------------------------------------------------------------===//
1662
// Pretty-printing regions.
1663
//===----------------------------------------------------------------------===//
1664
3.79k
inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1665
3.79k
  R->dumpToStream(os);
1666
3.79k
  return os;
1667
3.79k
}
1668
1669
} // namespace ento
1670
1671
} // namespace clang
1672
1673
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H