Coverage Report

Created: 2018-11-16 02:38

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