Coverage Report

Created: 2019-02-21 13:17

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