Coverage Report

Created: 2020-09-22 08:39

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
Line
Count
Source (jump to first uncovered line)
1
//==- MemRegion.h - Abstract memory regions for static analysis -*- C++ -*--==//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file defines MemRegion and its subclasses.  MemRegion defines a
10
//  partially-typed abstraction of memory useful for path-sensitive dataflow
11
//  analyses.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
16
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
17
18
#include "clang/AST/ASTContext.h"
19
#include "clang/AST/CharUnits.h"
20
#include "clang/AST/Decl.h"
21
#include "clang/AST/DeclObjC.h"
22
#include "clang/AST/DeclarationName.h"
23
#include "clang/AST/Expr.h"
24
#include "clang/AST/ExprObjC.h"
25
#include "clang/AST/Type.h"
26
#include "clang/Analysis/AnalysisDeclContext.h"
27
#include "clang/Basic/LLVM.h"
28
#include "clang/Basic/SourceLocation.h"
29
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
30
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
31
#include "llvm/ADT/DenseMap.h"
32
#include "llvm/ADT/FoldingSet.h"
33
#include "llvm/ADT/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
110k
  RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
76
77
1.52M
  const MemRegion *getRegion() const { return R; }
78
79
2.94M
  bool hasSymbolicOffset() const { return Offset == Symbolic; }
80
81
1.42M
  int64_t getOffset() const {
82
1.42M
    assert(!hasSymbolicOffset());
83
1.42M
    return Offset;
84
1.42M
  }
85
86
689
  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
216k
  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
76.9M
  Kind getKind() const { return kind; }
170
171
  template<typename RegionTy> const RegionTy* getAs() const;
172
  template<typename RegionTy> const RegionTy* castAs() const;
173
174
0
  virtual bool isBoundable() const { return false; }
175
176
  /// Get descriptive name for memory region. The name is obtained from
177
  /// the variable/field declaration retrieved from the memory region.
178
  /// Regions that point to an element of an array are returned as: "arr[0]".
179
  /// Regions that point to a struct are returned as: "st.var".
180
  //
181
  /// \param UseQuotes Set if the name should be quoted.
182
  ///
183
  /// \returns variable name for memory region
184
  std::string getDescriptiveName(bool UseQuotes = true) const;
185
186
  /// Retrieve source range from memory region. The range retrieval
187
  /// is based on the decl obtained from the memory region.
188
  /// For a VarRegion the range of the base region is returned.
189
  /// For a FieldRegion the range of the field is returned.
190
  /// If no declaration is found, an empty source range is returned.
191
  /// The client is responsible for checking if the returned range is valid.
192
  ///
193
  /// \returns source range for declaration retrieved from memory region
194
  SourceRange sourceRange() const;
195
};
196
197
/// MemSpaceRegion - A memory region that represents a "memory space";
198
///  for example, the set of global variables, the stack frame, etc.
199
class MemSpaceRegion : public MemRegion {
200
protected:
201
  MemRegionManager &Mgr;
202
203
73.2k
  MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) {
204
73.2k
    assert(classof(this));
205
73.2k
  }
206
207
659k
  MemRegionManager &getMemRegionManager() const override { return Mgr; }
208
209
public:
210
47.9k
  bool isBoundable() const override { return false; }
211
212
  void Profile(llvm::FoldingSetNodeID &ID) const override;
213
214
7.74M
  static bool classof(const MemRegion *R) {
215
7.74M
    Kind k = R->getKind();
216
7.74M
    return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
217
7.74M
  }
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
9.22k
      : 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
14.2k
  GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) {
241
14.2k
    assert(classof(this));
242
14.2k
  }
243
244
public:
245
336k
  static bool classof(const MemRegion *R) {
246
336k
    Kind k = R->getKind();
247
336k
    return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
248
336k
  }
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
167
      : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
263
167
    assert(cr);
264
167
  }
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
6.88k
  static bool classof(const MemRegion *R) {
274
6.88k
    return R->getKind() == StaticGlobalSpaceRegionKind;
275
6.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
14.0k
      : GlobalsSpaceRegion(mgr, k) {
290
14.0k
    assert(classof(this));
291
14.0k
  }
292
293
public:
294
748k
  static bool classof(const MemRegion *R) {
295
748k
    Kind k = R->getKind();
296
748k
    return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
297
748k
           k <= END_NON_STATIC_GLOBAL_MEMSPACES;
298
748k
  }
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
6.84k
      : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
308
309
public:
310
  void dumpToStream(raw_ostream &os) const override;
311
312
21.6k
  static bool classof(const MemRegion *R) {
313
21.6k
    return R->getKind() == GlobalSystemSpaceRegionKind;
314
21.6k
  }
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
213
      : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
327
328
public:
329
  void dumpToStream(raw_ostream &os) const override;
330
331
366
  static bool classof(const MemRegion *R) {
332
366
    return R->getKind() == GlobalImmutableSpaceRegionKind;
333
366
  }
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
7.03k
      : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
344
345
public:
346
  void dumpToStream(raw_ostream &os) const override;
347
348
9.97k
  static bool classof(const MemRegion *R) {
349
9.97k
    return R->getKind() == GlobalInternalSpaceRegionKind;
350
9.97k
  }
351
};
352
353
class HeapSpaceRegion : public MemSpaceRegion {
354
  friend class MemRegionManager;
355
356
  HeapSpaceRegion(MemRegionManager &mgr)
357
1.08k
      : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
358
359
public:
360
  void dumpToStream(raw_ostream &os) const override;
361
362
3.47k
  static bool classof(const MemRegion *R) {
363
3.47k
    return R->getKind() == HeapSpaceRegionKind;
364
3.47k
  }
365
};
366
367
class UnknownSpaceRegion : public MemSpaceRegion {
368
  friend class MemRegionManager;
369
370
  UnknownSpaceRegion(MemRegionManager &mgr)
371
8.18k
      : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
372
373
public:
374
  void dumpToStream(raw_ostream &os) const override;
375
376
83.2k
  static bool classof(const MemRegion *R) {
377
83.2k
    return R->getKind() == UnknownSpaceRegionKind;
378
83.2k
  }
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
40.4k
      : MemSpaceRegion(mgr, k), SFC(sfc) {
389
40.4k
    assert(classof(this));
390
40.4k
    assert(sfc);
391
40.4k
  }
392
393
public:
394
1.78M
  const StackFrameContext *getStackFrame() const { return SFC; }
395
396
  void Profile(llvm::FoldingSetNodeID &ID) const override;
397
398
3.56M
  static bool classof(const MemRegion *R) {
399
3.56M
    Kind k = R->getKind();
400
3.56M
    return k >= BEGIN_STACK_MEMSPACES && 
k <= END_STACK_MEMSPACES3.47M
;
401
3.56M
  }
402
};
403
404
class StackLocalsSpaceRegion : public StackSpaceRegion {
405
  friend class MemRegionManager;
406
407
  StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
408
11.4k
      : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
409
410
public:
411
  void dumpToStream(raw_ostream &os) const override;
412
413
69.6k
  static bool classof(const MemRegion *R) {
414
69.6k
    return R->getKind() == StackLocalsSpaceRegionKind;
415
69.6k
  }
416
};
417
418
class StackArgumentsSpaceRegion : public StackSpaceRegion {
419
private:
420
  friend class MemRegionManager;
421
422
  StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
423
28.9k
      : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
424
425
public:
426
  void dumpToStream(raw_ostream &os) const override;
427
428
326k
  static bool classof(const MemRegion *R) {
429
326k
    return R->getKind() == StackArgumentsSpaceRegionKind;
430
326k
  }
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
142k
  SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
442
142k
    assert(classof(this));
443
142k
    assert(sReg);
444
142k
  }
445
446
public:
447
11.9M
  const MemRegion* getSuperRegion() const {
448
11.9M
    return superRegion;
449
11.9M
  }
450
451
  MemRegionManager &getMemRegionManager() const override;
452
453
  bool isSubRegionOf(const MemRegion* R) const override;
454
455
28.1M
  static bool classof(const MemRegion* R) {
456
28.1M
    return R->getKind() > END_MEMSPACES;
457
28.1M
  }
458
};
459
460
//===----------------------------------------------------------------------===//
461
// MemRegion subclasses.
462
//===----------------------------------------------------------------------===//
463
464
/// AllocaRegion - A region that represents an untyped blob of bytes created
465
///  by a call to 'alloca'.
466
class AllocaRegion : public SubRegion {
467
  friend class MemRegionManager;
468
469
  // Block counter. Used to distinguish different pieces of memory allocated by
470
  // alloca at the same call site.
471
  unsigned Cnt;
472
473
  const Expr *Ex;
474
475
  AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
476
87
      : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
477
87
    assert(Ex);
478
87
  }
479
480
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
481
                            unsigned Cnt, const MemRegion *superRegion);
482
483
public:
484
4
  const Expr *getExpr() const { return Ex; }
485
486
17
  bool isBoundable() const override { return true; }
487
488
  void Profile(llvm::FoldingSetNodeID& ID) const override;
489
490
  void dumpToStream(raw_ostream &os) const override;
491
492
88.1k
  static bool classof(const MemRegion* R) {
493
88.1k
    return R->getKind() == AllocaRegionKind;
494
88.1k
  }
495
};
496
497
/// TypedRegion - An abstract class representing regions that are typed.
498
class TypedRegion : public SubRegion {
499
  void anchor() override;
500
501
protected:
502
125k
  TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
503
125k
    assert(classof(this));
504
125k
  }
505
506
public:
507
  virtual QualType getLocationType() const = 0;
508
509
0
  QualType getDesugaredLocationType(ASTContext &Context) const {
510
0
    return getLocationType().getDesugaredType(Context);
511
0
  }
512
513
22.2k
  bool isBoundable() const override { return true; }
514
515
1.30M
  static bool classof(const MemRegion* R) {
516
1.30M
    unsigned k = R->getKind();
517
1.30M
    return k >= BEGIN_TYPED_REGIONS && 
k <= END_TYPED_REGIONS1.26M
;
518
1.30M
  }
519
};
520
521
/// TypedValueRegion - An abstract class representing regions having a typed value.
522
class TypedValueRegion : public TypedRegion {
523
  void anchor() override;
524
525
protected:
526
99.8k
  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
527
99.8k
    assert(classof(this));
528
99.8k
  }
529
530
public:
531
  virtual QualType getValueType() const = 0;
532
533
438k
  QualType getLocationType() const override {
534
    // FIXME: We can possibly optimize this later to cache this value.
535
438k
    QualType T = getValueType();
536
438k
    ASTContext &ctx = getContext();
537
438k
    if (T->getAs<ObjCObjectType>())
538
0
      return ctx.getObjCObjectPointerType(T);
539
438k
    return ctx.getPointerType(getValueType());
540
438k
  }
541
542
26.8k
  QualType getDesugaredValueType(ASTContext &Context) const {
543
26.8k
    QualType T = getValueType();
544
26.8k
    return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : 
T0
;
545
26.8k
  }
546
547
2.38M
  static bool classof(const MemRegion* R) {
548
2.38M
    unsigned k = R->getKind();
549
2.38M
    return k >= BEGIN_TYPED_VALUE_REGIONS && 
k <= END_TYPED_VALUE_REGIONS2.29M
;
550
2.38M
  }
551
};
552
553
class CodeTextRegion : public TypedRegion {
554
  void anchor() override;
555
556
protected:
557
25.3k
  CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
558
25.3k
    assert(classof(this));
559
25.3k
  }
560
561
public:
562
35
  bool isBoundable() const override { return false; }
563
564
39.6k
  static bool classof(const MemRegion* R) {
565
39.6k
    Kind k = R->getKind();
566
39.6k
    return k >= BEGIN_CODE_TEXT_REGIONS && 
k <= END_CODE_TEXT_REGIONS31.4k
;
567
39.6k
  }
568
};
569
570
/// FunctionCodeRegion - A region that represents code texts of function.
571
class FunctionCodeRegion : public CodeTextRegion {
572
  friend class MemRegionManager;
573
574
  const NamedDecl *FD;
575
576
  FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
577
24.9k
      : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
578
24.9k
    assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
579
24.9k
  }
580
581
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
582
                            const MemRegion*);
583
584
public:
585
131k
  QualType getLocationType() const override {
586
131k
    const ASTContext &Ctx = getContext();
587
131k
    if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
588
131k
      return Ctx.getPointerType(D->getType());
589
131k
    }
590
591
0
    assert(isa<ObjCMethodDecl>(FD));
592
0
    assert(false && "Getting the type of ObjCMethod is not supported yet");
593
594
    // TODO: We might want to return a different type here (ex: id (*ty)(...))
595
    //       depending on how it is used.
596
0
    return {};
597
0
  }
598
599
240k
  const NamedDecl *getDecl() const {
600
240k
    return FD;
601
240k
  }
602
603
  void dumpToStream(raw_ostream &os) const override;
604
605
  void Profile(llvm::FoldingSetNodeID& ID) const override;
606
607
938k
  static bool classof(const MemRegion* R) {
608
938k
    return R->getKind() == FunctionCodeRegionKind;
609
938k
  }
610
};
611
612
/// BlockCodeRegion - A region that represents code texts of blocks (closures).
613
///  Blocks are represented with two kinds of regions.  BlockCodeRegions
614
///  represent the "code", while BlockDataRegions represent instances of blocks,
615
///  which correspond to "code+data".  The distinction is important, because
616
///  like a closure a block captures the values of externally referenced
617
///  variables.
618
class BlockCodeRegion : public CodeTextRegion {
619
  friend class MemRegionManager;
620
621
  const BlockDecl *BD;
622
  AnalysisDeclContext *AC;
623
  CanQualType locTy;
624
625
  BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
626
                  AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
627
359
      : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
628
359
    assert(bd);
629
359
    assert(ac);
630
359
    assert(lTy->getTypePtr()->isBlockPointerType());
631
359
  }
632
633
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
634
                            CanQualType, const AnalysisDeclContext*,
635
                            const MemRegion*);
636
637
public:
638
406
  QualType getLocationType() const override {
639
406
    return locTy;
640
406
  }
641
642
3.60k
  const BlockDecl *getDecl() const {
643
3.60k
    return BD;
644
3.60k
  }
645
646
366
  AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
647
648
  void dumpToStream(raw_ostream &os) const override;
649
650
  void Profile(llvm::FoldingSetNodeID& ID) const override;
651
652
68
  static bool classof(const MemRegion* R) {
653
68
    return R->getKind() == BlockCodeRegionKind;
654
68
  }
655
};
656
657
/// BlockDataRegion - A region that represents a block instance.
658
///  Blocks are represented with two kinds of regions.  BlockCodeRegions
659
///  represent the "code", while BlockDataRegions represent instances of blocks,
660
///  which correspond to "code+data".  The distinction is important, because
661
///  like a closure a block captures the values of externally referenced
662
///  variables.
663
class BlockDataRegion : public TypedRegion {
664
  friend class MemRegionManager;
665
666
  const BlockCodeRegion *BC;
667
  const LocationContext *LC; // Can be null
668
  unsigned BlockCount;
669
  void *ReferencedVars = nullptr;
670
  void *OriginalVars = nullptr;
671
672
  BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
673
                  unsigned count, const MemSpaceRegion *sreg)
674
      : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
675
366
        BlockCount(count) {
676
366
    assert(bc);
677
366
    assert(lc);
678
366
    assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
679
366
           isa<StackLocalsSpaceRegion>(sreg) ||
680
366
           isa<UnknownSpaceRegion>(sreg));
681
366
  }
682
683
  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
684
                            const LocationContext *, unsigned,
685
                            const MemRegion *);
686
687
public:
688
368
  const BlockCodeRegion *getCodeRegion() const { return BC; }
689
690
2.85k
  const BlockDecl *getDecl() const { return BC->getDecl(); }
691
692
406
  QualType getLocationType() const override { return BC->getLocationType(); }
693
694
  class referenced_vars_iterator {
695
    const MemRegion * const *R;
696
    const MemRegion * const *OriginalR;
697
698
  public:
699
    explicit referenced_vars_iterator(const MemRegion * const *r,
700
                                      const MemRegion * const *originalR)
701
6.00k
        : R(r), OriginalR(originalR) {}
702
703
2.96k
    const VarRegion *getCapturedRegion() const {
704
2.96k
      return cast<VarRegion>(*R);
705
2.96k
    }
706
707
725
    const VarRegion *getOriginalRegion() const {
708
725
      return cast<VarRegion>(*OriginalR);
709
725
    }
710
711
30
    bool operator==(const referenced_vars_iterator &I) const {
712
30
      assert((R == nullptr) == (I.R == nullptr));
713
30
      return I.R == R;
714
30
    }
715
716
5.82k
    bool operator!=(const referenced_vars_iterator &I) const {
717
5.82k
      assert((R == nullptr) == (I.R == nullptr));
718
5.82k
      return I.R != R;
719
5.82k
    }
720
721
2.82k
    referenced_vars_iterator &operator++() {
722
2.82k
      ++R;
723
2.82k
      ++OriginalR;
724
2.82k
      return *this;
725
2.82k
    }
726
  };
727
728
  /// Return the original region for a captured region, if
729
  /// one exists.
730
  const VarRegion *getOriginalRegion(const VarRegion *VR) const;
731
732
  referenced_vars_iterator referenced_vars_begin() const;
733
  referenced_vars_iterator referenced_vars_end() const;
734
735
  void dumpToStream(raw_ostream &os) const override;
736
737
  void Profile(llvm::FoldingSetNodeID& ID) const override;
738
739
1.91M
  static bool classof(const MemRegion* R) {
740
1.91M
    return R->getKind() == BlockDataRegionKind;
741
1.91M
  }
742
743
private:
744
  void LazyInitializeReferencedVars();
745
  std::pair<const VarRegion *, const VarRegion *>
746
  getCaptureRegions(const VarDecl *VD);
747
};
748
749
/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
750
///  classes, SymbolicRegion represents a region that serves as an alias for
751
///  either a real region, a NULL pointer, etc.  It essentially is used to
752
///  map the concept of symbolic values into the domain of regions.  Symbolic
753
///  regions do not need to be typed.
754
class SymbolicRegion : public SubRegion {
755
  friend class MemRegionManager;
756
757
  const SymbolRef sym;
758
759
  SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
760
17.1k
      : SubRegion(sreg, SymbolicRegionKind), sym(s) {
761
    // Because pointer arithmetic is represented by ElementRegion layers,
762
    // the base symbol here should not contain any arithmetic.
763
17.1k
    assert(s && isa<SymbolData>(s));
764
17.1k
    assert(s->getType()->isAnyPointerType() ||
765
17.1k
           s->getType()->isReferenceType() ||
766
17.1k
           s->getType()->isBlockPointerType());
767
17.1k
    assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
768
17.1k
  }
769
770
public:
771
1.35M
  SymbolRef getSymbol() const { return sym; }
772
773
5.45k
  bool isBoundable() const override { return true; }
774
775
  void Profile(llvm::FoldingSetNodeID& ID) const override;
776
777
  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
778
                            SymbolRef sym,
779
                            const MemRegion* superRegion);
780
781
  void dumpToStream(raw_ostream &os) const override;
782
783
8.15M
  static bool classof(const MemRegion* R) {
784
8.15M
    return R->getKind() == SymbolicRegionKind;
785
8.15M
  }
786
};
787
788
/// StringRegion - Region associated with a StringLiteral.
789
class StringRegion : public TypedValueRegion {
790
  friend class MemRegionManager;
791
792
  const StringLiteral *Str;
793
794
  StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
795
3.88k
      : TypedValueRegion(sreg, StringRegionKind), Str(str) {
796
3.88k
    assert(str);
797
3.88k
  }
798
799
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
800
                            const StringLiteral *Str,
801
                            const MemRegion *superRegion);
802
803
public:
804
2.03k
  const StringLiteral *getStringLiteral() const { return Str; }
805
806
3.76k
  QualType getValueType() const override { return Str->getType(); }
807
808
53
  bool isBoundable() const override { return false; }
809
810
6.00k
  void Profile(llvm::FoldingSetNodeID& ID) const override {
811
6.00k
    ProfileRegion(ID, Str, superRegion);
812
6.00k
  }
813
814
  void dumpToStream(raw_ostream &os) const override;
815
816
25.6k
  static bool classof(const MemRegion* R) {
817
25.6k
    return R->getKind() == StringRegionKind;
818
25.6k
  }
819
};
820
821
/// The region associated with an ObjCStringLiteral.
822
class ObjCStringRegion : public TypedValueRegion {
823
  friend class MemRegionManager;
824
825
  const ObjCStringLiteral *Str;
826
827
  ObjCStringRegion(const ObjCStringLiteral *str,
828
                   const GlobalInternalSpaceRegion *sreg)
829
285
      : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
830
285
    assert(str);
831
285
  }
832
833
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
834
                            const ObjCStringLiteral *Str,
835
                            const MemRegion *superRegion);
836
837
public:
838
17
  const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
839
840
1.43k
  QualType getValueType() const override { return Str->getType(); }
841
842
299
  bool isBoundable() const override { return false; }
843
844
890
  void Profile(llvm::FoldingSetNodeID& ID) const override {
845
890
    ProfileRegion(ID, Str, superRegion);
846
890
  }
847
848
  void dumpToStream(raw_ostream &os) const override;
849
850
1.71k
  static bool classof(const MemRegion* R) {
851
1.71k
    return R->getKind() == ObjCStringRegionKind;
852
1.71k
  }
853
};
854
855
/// CompoundLiteralRegion - A memory region representing a compound literal.
856
///   Compound literals are essentially temporaries that are stack allocated
857
///   or in the global constant pool.
858
class CompoundLiteralRegion : public TypedValueRegion {
859
  friend class MemRegionManager;
860
861
  const CompoundLiteralExpr *CL;
862
863
  CompoundLiteralRegion(const CompoundLiteralExpr *cl,
864
                        const MemSpaceRegion *sReg)
865
52
      : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
866
52
    assert(cl);
867
52
    assert(isa<GlobalInternalSpaceRegion>(sReg) ||
868
52
           isa<StackLocalsSpaceRegion>(sReg));
869
52
  }
870
871
  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
872
                            const CompoundLiteralExpr *CL,
873
                            const MemRegion* superRegion);
874
875
public:
876
215
  QualType getValueType() const override { return CL->getType(); }
877
878
0
  bool isBoundable() const override { return !CL->isFileScope(); }
879
880
  void Profile(llvm::FoldingSetNodeID& ID) const override;
881
882
  void dumpToStream(raw_ostream &os) const override;
883
884
3
  const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
885
886
70
  static bool classof(const MemRegion* R) {
887
70
    return R->getKind() == CompoundLiteralRegionKind;
888
70
  }
889
};
890
891
class DeclRegion : public TypedValueRegion {
892
protected:
893
64.5k
  DeclRegion(const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k) {
894
64.5k
    assert(classof(this));
895
64.5k
  }
896
897
public:
898
  virtual const ValueDecl *getDecl() const = 0;
899
900
67.2k
  static bool classof(const MemRegion* R) {
901
67.2k
    unsigned k = R->getKind();
902
67.2k
    return k >= BEGIN_DECL_REGIONS && 
k <= END_DECL_REGIONS67.0k
;
903
67.2k
  }
904
};
905
906
class VarRegion : public DeclRegion {
907
  friend class MemRegionManager;
908
909
protected:
910
  // Constructors and protected methods.
911
47.3k
  VarRegion(const MemRegion *sReg, Kind k) : DeclRegion(sReg, k) {
912
    // VarRegion appears in unknown space when it's a block variable as seen
913
    // from a block using it, when this block is analyzed at top-level.
914
    // Other block variables appear within block data regions,
915
    // which, unlike everything else on this list, are not memory spaces.
916
47.3k
    assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
917
47.3k
           isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
918
47.3k
  }
919
920
public:
921
  const VarDecl *getDecl() const override = 0;
922
923
  const StackFrameContext *getStackFrame() const;
924
925
0
  QualType getValueType() const override {
926
    // FIXME: We can cache this if needed.
927
0
    return getDecl()->getType();
928
0
  }
929
930
3.74M
  static bool classof(const MemRegion *R) {
931
3.74M
    unsigned k = R->getKind();
932
3.74M
    return k >= BEGIN_VAR_REGIONS && 
k <= END_VAR_REGIONS2.91M
;
933
3.74M
  }
934
};
935
936
class NonParamVarRegion : public VarRegion {
937
  friend class MemRegionManager;
938
939
  const VarDecl *VD;
940
941
  // Constructors and private methods.
942
  NonParamVarRegion(const VarDecl *vd, const MemRegion *sReg)
943
28.5k
      : VarRegion(sReg, NonParamVarRegionKind), VD(vd) {
944
    // VarRegion appears in unknown space when it's a block variable as seen
945
    // from a block using it, when this block is analyzed at top-level.
946
    // Other block variables appear within block data regions,
947
    // which, unlike everything else on this list, are not memory spaces.
948
28.5k
    assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
949
28.5k
           isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
950
28.5k
  }
951
952
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const VarDecl *VD,
953
                            const MemRegion *superRegion);
954
955
public:
956
  void Profile(llvm::FoldingSetNodeID &ID) const override;
957
958
2.29M
  const VarDecl *getDecl() const override { return VD; }
959
960
1.60M
  QualType getValueType() const override {
961
    // FIXME: We can cache this if needed.
962
1.60M
    return getDecl()->getType();
963
1.60M
  }
964
965
  void dumpToStream(raw_ostream &os) const override;
966
967
  bool canPrintPrettyAsExpr() const override;
968
969
  void printPrettyAsExpr(raw_ostream &os) const override;
970
971
285k
  static bool classof(const MemRegion* R) {
972
285k
    return R->getKind() == NonParamVarRegionKind;
973
285k
  }
974
};
975
976
/// ParamVarRegion - Represents a region for paremters. Only parameters of the
977
/// function in the current stack frame are represented as `ParamVarRegion`s.
978
/// Parameters of top-level analyzed functions as well as captured paremeters
979
/// by lambdas and blocks are repesented as `VarRegion`s.
980
981
// FIXME: `ParamVarRegion` only supports parameters of functions, C++
982
// constructors, blocks and Objective-C methods with existing `Decl`. Upon
983
// implementing stack frame creations for functions without decl (functions
984
// passed by unknown function pointer) methods of `ParamVarRegion` must be
985
// updated.
986
class ParamVarRegion : public VarRegion {
987
  friend class MemRegionManager;
988
989
  const Expr *OriginExpr;
990
  unsigned Index;
991
992
  ParamVarRegion(const Expr *OE, unsigned Idx, const MemRegion *SReg)
993
18.8k
      : VarRegion(SReg, ParamVarRegionKind), OriginExpr(OE), Index(Idx) {
994
18.8k
    assert(!cast<StackSpaceRegion>(SReg)->getStackFrame()->inTopFrame());
995
18.8k
  }
996
997
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
998
                            unsigned Idx, const MemRegion *SReg);
999
1000
public:
1001
130k
  const Expr *getOriginExpr() const { return OriginExpr; }
1002
130k
  unsigned getIndex() const { return Index; }
1003
1004
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1005
1006
  void dumpToStream(raw_ostream &os) const override;
1007
1008
  QualType getValueType() const override;
1009
  const ParmVarDecl *getDecl() const override;
1010
1011
  bool canPrintPrettyAsExpr() const override;
1012
  void printPrettyAsExpr(raw_ostream &os) const override;
1013
1014
129k
  static bool classof(const MemRegion *R) {
1015
129k
    return R->getKind() == ParamVarRegionKind;
1016
129k
  }
1017
};
1018
1019
/// CXXThisRegion - Represents the region for the implicit 'this' parameter
1020
///  in a call to a C++ method.  This region doesn't represent the object
1021
///  referred to by 'this', but rather 'this' itself.
1022
class CXXThisRegion : public TypedValueRegion {
1023
  friend class MemRegionManager;
1024
1025
  CXXThisRegion(const PointerType *thisPointerTy,
1026
                const StackArgumentsSpaceRegion *sReg)
1027
      : TypedValueRegion(sReg, CXXThisRegionKind),
1028
13.9k
        ThisPointerTy(thisPointerTy) {
1029
13.9k
    assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
1030
13.9k
           "Invalid region type!");
1031
13.9k
  }
1032
1033
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1034
                            const PointerType *PT,
1035
                            const MemRegion *sReg);
1036
1037
public:
1038
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1039
1040
155k
  QualType getValueType() const override {
1041
155k
    return QualType(ThisPointerTy, 0);
1042
155k
  }
1043
1044
  void dumpToStream(raw_ostream &os) const override;
1045
1046
604k
  static bool classof(const MemRegion* R) {
1047
604k
    return R->getKind() == CXXThisRegionKind;
1048
604k
  }
1049
1050
private:
1051
  const PointerType *ThisPointerTy;
1052
};
1053
1054
class FieldRegion : public DeclRegion {
1055
  friend class MemRegionManager;
1056
1057
  const FieldDecl *FD;
1058
1059
  FieldRegion(const FieldDecl *fd, const SubRegion *sReg)
1060
16.5k
      : DeclRegion(sReg, FieldRegionKind), FD(fd) {}
1061
1062
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD,
1063
275k
                            const MemRegion* superRegion) {
1064
275k
    ID.AddInteger(static_cast<unsigned>(FieldRegionKind));
1065
275k
    ID.AddPointer(FD);
1066
275k
    ID.AddPointer(superRegion);
1067
275k
  }
1068
1069
public:
1070
1.07M
  const FieldDecl *getDecl() const override { return FD; }
1071
1072
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1073
1074
786k
  QualType getValueType() const override {
1075
    // FIXME: We can cache this if needed.
1076
786k
    return getDecl()->getType();
1077
786k
  }
1078
1079
  void dumpToStream(raw_ostream &os) const override;
1080
1081
  bool canPrintPretty() const override;
1082
  void printPretty(raw_ostream &os) const override;
1083
  bool canPrintPrettyAsExpr() const override;
1084
  void printPrettyAsExpr(raw_ostream &os) const override;
1085
1086
947k
  static bool classof(const MemRegion* R) {
1087
947k
    return R->getKind() == FieldRegionKind;
1088
947k
  }
1089
};
1090
1091
class ObjCIvarRegion : public DeclRegion {
1092
  friend class MemRegionManager;
1093
1094
  const ObjCIvarDecl *IVD;
1095
1096
  ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1097
1098
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1099
                            const MemRegion* superRegion);
1100
1101
public:
1102
  const ObjCIvarDecl *getDecl() const override;
1103
1104
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1105
1106
  QualType getValueType() const override;
1107
1108
  bool canPrintPrettyAsExpr() const override;
1109
  void printPrettyAsExpr(raw_ostream &os) const override;
1110
1111
  void dumpToStream(raw_ostream &os) const override;
1112
1113
378k
  static bool classof(const MemRegion* R) {
1114
378k
    return R->getKind() == ObjCIvarRegionKind;
1115
378k
  }
1116
};
1117
1118
//===----------------------------------------------------------------------===//
1119
// Auxiliary data classes for use with MemRegions.
1120
//===----------------------------------------------------------------------===//
1121
1122
class RegionRawOffset {
1123
  friend class ElementRegion;
1124
1125
  const MemRegion *Region;
1126
  CharUnits Offset;
1127
1128
  RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
1129
13.1k
      : Region(reg), Offset(offset) {}
1130
1131
public:
1132
  // FIXME: Eventually support symbolic offsets.
1133
437
  CharUnits getOffset() const { return Offset; }
1134
23.8k
  const MemRegion *getRegion() const { return Region; }
1135
1136
  void dumpToStream(raw_ostream &os) const;
1137
  void dump() const;
1138
};
1139
1140
/// ElementRegion is used to represent both array elements and casts.
1141
class ElementRegion : public TypedValueRegion {
1142
  friend class MemRegionManager;
1143
1144
  QualType ElementType;
1145
  NonLoc Index;
1146
1147
  ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1148
      : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1149
13.2k
        Index(Idx) {
1150
13.2k
    assert((!Idx.getAs<nonloc::ConcreteInt>() ||
1151
13.2k
            Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
1152
13.2k
           "The index must be signed");
1153
13.2k
    assert(!elementType.isNull() && !elementType->isVoidType() &&
1154
13.2k
           "Invalid region type!");
1155
13.2k
  }
1156
1157
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1158
                            SVal Idx, const MemRegion* superRegion);
1159
1160
public:
1161
318k
  NonLoc getIndex() const { return Index; }
1162
1163
197k
  QualType getValueType() const override { return ElementType; }
1164
1165
30.1k
  QualType getElementType() const { return ElementType; }
1166
1167
  /// Compute the offset within the array. The array might also be a subobject.
1168
  RegionRawOffset getAsArrayOffset() const;
1169
1170
  void dumpToStream(raw_ostream &os) const override;
1171
1172
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1173
1174
4.03M
  static bool classof(const MemRegion* R) {
1175
4.03M
    return R->getKind() == ElementRegionKind;
1176
4.03M
  }
1177
};
1178
1179
// C++ temporary object associated with an expression.
1180
class CXXTempObjectRegion : public TypedValueRegion {
1181
  friend class MemRegionManager;
1182
1183
  Expr const *Ex;
1184
1185
  CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1186
2.85k
      : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1187
2.85k
    assert(E);
1188
2.85k
    assert(isa<StackLocalsSpaceRegion>(sReg) ||
1189
2.85k
           isa<GlobalInternalSpaceRegion>(sReg));
1190
2.85k
  }
1191
1192
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1193
                            Expr const *E, const MemRegion *sReg);
1194
1195
public:
1196
21
  const Expr *getExpr() const { return Ex; }
1197
1198
40.3k
  QualType getValueType() const override { return Ex->getType(); }
1199
1200
  void dumpToStream(raw_ostream &os) const override;
1201
1202
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1203
1204
6.37k
  static bool classof(const MemRegion* R) {
1205
6.37k
    return R->getKind() == CXXTempObjectRegionKind;
1206
6.37k
  }
1207
};
1208
1209
// CXXBaseObjectRegion represents a base object within a C++ object. It is
1210
// identified by the base class declaration and the region of its parent object.
1211
class CXXBaseObjectRegion : public TypedValueRegion {
1212
  friend class MemRegionManager;
1213
1214
  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1215
1216
  CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1217
                      const SubRegion *SReg)
1218
1.06k
      : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1219
1.06k
    assert(RD);
1220
1.06k
  }
1221
1222
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1223
                            bool IsVirtual, const MemRegion *SReg);
1224
1225
public:
1226
9.86k
  const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1227
3.02k
  bool isVirtual() const { return Data.getInt(); }
1228
1229
  QualType getValueType() const override;
1230
1231
  void dumpToStream(raw_ostream &os) const override;
1232
1233
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1234
1235
  bool canPrintPrettyAsExpr() const override;
1236
1237
  void printPrettyAsExpr(raw_ostream &os) const override;
1238
1239
123k
  static bool classof(const MemRegion *region) {
1240
123k
    return region->getKind() == CXXBaseObjectRegionKind;
1241
123k
  }
1242
};
1243
1244
// CXXDerivedObjectRegion represents a derived-class object that surrounds
1245
// a C++ object. It is identified by the derived class declaration and the
1246
// region of its parent object. It is a bit counter-intuitive (but not otherwise
1247
// unseen) that this region represents a larger segment of memory that its
1248
// super-region.
1249
class CXXDerivedObjectRegion : public TypedValueRegion {
1250
  friend class MemRegionManager;
1251
1252
  const CXXRecordDecl *DerivedD;
1253
1254
  CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1255
20
      : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1256
20
    assert(DerivedD);
1257
    // In case of a concrete region, it should always be possible to model
1258
    // the base-to-derived cast by undoing a previous derived-to-base cast,
1259
    // otherwise the cast is most likely ill-formed.
1260
20
    assert(SReg->getSymbolicBase() &&
1261
20
           "Should have unwrapped a base region instead!");
1262
20
  }
1263
1264
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1265
                            const MemRegion *SReg);
1266
1267
public:
1268
45
  const CXXRecordDecl *getDecl() const { return DerivedD; }
1269
1270
  QualType getValueType() const override;
1271
1272
  void dumpToStream(raw_ostream &os) const override;
1273
1274
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1275
1276
  bool canPrintPrettyAsExpr() const override;
1277
1278
  void printPrettyAsExpr(raw_ostream &os) const override;
1279
1280
1.83k
  static bool classof(const MemRegion *region) {
1281
1.83k
    return region->getKind() == CXXDerivedObjectRegionKind;
1282
1.83k
  }
1283
};
1284
1285
template<typename RegionTy>
1286
147k
const RegionTy* MemRegion::getAs() const {
1287
147k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
122k
    return RT;
1289
1290
25.0k
  return nullptr;
1291
25.0k
}
clang::ento::VarRegion const* clang::ento::MemRegion::getAs<clang::ento::VarRegion>() const
Line
Count
Source
1286
682
const RegionTy* MemRegion::getAs() const {
1287
682
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
642
    return RT;
1289
1290
40
  return nullptr;
1291
40
}
clang::ento::CXXTempObjectRegion const* clang::ento::MemRegion::getAs<clang::ento::CXXTempObjectRegion>() const
Line
Count
Source
1286
3.40k
const RegionTy* MemRegion::getAs() const {
1287
3.40k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
300
    return RT;
1289
1290
3.10k
  return nullptr;
1291
3.10k
}
clang::ento::MemRegion const* clang::ento::MemRegion::getAs<clang::ento::MemRegion>() const
Line
Count
Source
1286
18
const RegionTy* MemRegion::getAs() const {
1287
18
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
18
    return RT;
1289
1290
0
  return nullptr;
1291
0
}
clang::ento::FieldRegion const* clang::ento::MemRegion::getAs<clang::ento::FieldRegion>() const
Line
Count
Source
1286
54
const RegionTy* MemRegion::getAs() const {
1287
54
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
23
    return RT;
1289
1290
31
  return nullptr;
1291
31
}
clang::ento::TypedValueRegion const* clang::ento::MemRegion::getAs<clang::ento::TypedValueRegion>() const
Line
Count
Source
1286
901
const RegionTy* MemRegion::getAs() const {
1287
901
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
804
    return RT;
1289
1290
97
  return nullptr;
1291
97
}
clang::ento::DeclRegion const* clang::ento::MemRegion::getAs<clang::ento::DeclRegion>() const
Line
Count
Source
1286
329
const RegionTy* MemRegion::getAs() const {
1287
329
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
130
    return RT;
1289
1290
199
  return nullptr;
1291
199
}
clang::ento::SubRegion const* clang::ento::MemRegion::getAs<clang::ento::SubRegion>() const
Line
Count
Source
1286
1.10k
const RegionTy* MemRegion::getAs() const {
1287
1.10k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
1.10k
    return RT;
1289
1290
0
  return nullptr;
1291
0
}
clang::ento::SymbolicRegion const* clang::ento::MemRegion::getAs<clang::ento::SymbolicRegion>() const
Line
Count
Source
1286
31.8k
const RegionTy* MemRegion::getAs() const {
1287
31.8k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
11.0k
    return RT;
1289
1290
20.7k
  return nullptr;
1291
20.7k
}
clang::ento::ElementRegion const* clang::ento::MemRegion::getAs<clang::ento::ElementRegion>() const
Line
Count
Source
1286
166
const RegionTy* MemRegion::getAs() const {
1287
166
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
44
    return RT;
1289
1290
122
  return nullptr;
1291
122
}
clang::ento::FunctionCodeRegion const* clang::ento::MemRegion::getAs<clang::ento::FunctionCodeRegion>() const
Line
Count
Source
1286
109k
const RegionTy* MemRegion::getAs() const {
1287
109k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1288
108k
    return RT;
1289
1290
747
  return nullptr;
1291
747
}
1292
1293
template<typename RegionTy>
1294
504
const RegionTy* MemRegion::castAs() const {
1295
504
  return cast<RegionTy>(this);
1296
504
}
1297
1298
//===----------------------------------------------------------------------===//
1299
// MemRegionManager - Factory object for creating regions.
1300
//===----------------------------------------------------------------------===//
1301
1302
class MemRegionManager {
1303
  ASTContext &Ctx;
1304
  llvm::BumpPtrAllocator& A;
1305
1306
  llvm::FoldingSet<MemRegion> Regions;
1307
1308
  GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1309
  GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1310
  GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1311
1312
  llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1313
    StackLocalsSpaceRegions;
1314
  llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1315
    StackArgumentsSpaceRegions;
1316
  llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1317
    StaticsGlobalSpaceRegions;
1318
1319
  HeapSpaceRegion *heap = nullptr;
1320
  UnknownSpaceRegion *unknown = nullptr;
1321
  CodeSpaceRegion *code = nullptr;
1322
1323
public:
1324
13.6k
  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {}
1325
  ~MemRegionManager();
1326
1327
633k
  ASTContext &getContext() { return Ctx; }
1328
1329
236
  llvm::BumpPtrAllocator &getAllocator() { return A; }
1330
1331
  /// \returns The static size in bytes of the region \p MR.
1332
  /// \note The region \p MR must be a 'SubRegion'.
1333
  DefinedOrUnknownSVal getStaticSize(const MemRegion *MR,
1334
                                     SValBuilder &SVB) const;
1335
1336
  /// getStackLocalsRegion - Retrieve the memory region associated with the
1337
  ///  specified stack frame.
1338
  const StackLocalsSpaceRegion *
1339
  getStackLocalsRegion(const StackFrameContext *STC);
1340
1341
  /// getStackArgumentsRegion - Retrieve the memory region associated with
1342
  ///  function/method arguments of the specified stack frame.
1343
  const StackArgumentsSpaceRegion *
1344
  getStackArgumentsRegion(const StackFrameContext *STC);
1345
1346
  /// getGlobalsRegion - Retrieve the memory region associated with
1347
  ///  global variables.
1348
  const GlobalsSpaceRegion *getGlobalsRegion(
1349
      MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1350
      const CodeTextRegion *R = nullptr);
1351
1352
  /// getHeapRegion - Retrieve the memory region associated with the
1353
  ///  generic "heap".
1354
  const HeapSpaceRegion *getHeapRegion();
1355
1356
  /// getUnknownRegion - Retrieve the memory region associated with unknown
1357
  /// memory space.
1358
  const UnknownSpaceRegion *getUnknownRegion();
1359
1360
  const CodeSpaceRegion *getCodeRegion();
1361
1362
  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1363
  const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1364
                                      const LocationContext *LC);
1365
1366
  /// getCompoundLiteralRegion - Retrieve the region associated with a
1367
  ///  given CompoundLiteral.
1368
  const CompoundLiteralRegion*
1369
  getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1370
                           const LocationContext *LC);
1371
1372
  /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1373
  ///  parameter 'this'.
1374
  const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1375
                                        const LocationContext *LC);
1376
1377
  /// Retrieve or create a "symbolic" memory region.
1378
  const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
1379
1380
  /// Return a unique symbolic region belonging to heap memory space.
1381
  const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1382
1383
  const StringRegion *getStringRegion(const StringLiteral *Str);
1384
1385
  const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1386
1387
  /// getVarRegion - Retrieve or create the memory region associated with
1388
  ///  a specified VarDecl and LocationContext.
1389
  const VarRegion *getVarRegion(const VarDecl *VD, const LocationContext *LC);
1390
1391
  /// getVarRegion - Retrieve or create the memory region associated with
1392
  ///  a specified VarDecl and LocationContext.
1393
  const NonParamVarRegion *getNonParamVarRegion(const VarDecl *VD,
1394
                                                const MemRegion *superR);
1395
1396
  /// getParamVarRegion - Retrieve or create the memory region
1397
  /// associated with a specified CallExpr, Index and LocationContext.
1398
  const ParamVarRegion *getParamVarRegion(const Expr *OriginExpr,
1399
                                          unsigned Index,
1400
                                          const LocationContext *LC);
1401
1402
  /// getElementRegion - Retrieve the memory region associated with the
1403
  ///  associated element type, index, and super region.
1404
  const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1405
                                        const SubRegion *superRegion,
1406
                                        ASTContext &Ctx);
1407
1408
  const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1409
254
                                                 const SubRegion *superRegion) {
1410
254
    return getElementRegion(ER->getElementType(), ER->getIndex(),
1411
254
                            superRegion, ER->getContext());
1412
254
  }
1413
1414
  /// getFieldRegion - Retrieve or create the memory region associated with
1415
  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1416
  ///  memory region (which typically represents the memory representing
1417
  ///  a structure or class).
1418
  const FieldRegion *getFieldRegion(const FieldDecl *fd,
1419
                                    const SubRegion* superRegion);
1420
1421
  const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1422
449
                                             const SubRegion *superRegion) {
1423
449
    return getFieldRegion(FR->getDecl(), superRegion);
1424
449
  }
1425
1426
  /// getObjCIvarRegion - Retrieve or create the memory region associated with
1427
  ///   a specified Objective-c instance variable.  'superRegion' corresponds
1428
  ///   to the containing region (which typically represents the Objective-C
1429
  ///   object).
1430
  const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1431
                                          const SubRegion* superRegion);
1432
1433
  const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1434
                                                    LocationContext const *LC);
1435
1436
  /// Create a CXXBaseObjectRegion with the given base class for region
1437
  /// \p Super.
1438
  ///
1439
  /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1440
  const CXXBaseObjectRegion *
1441
  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1442
                         bool IsVirtual);
1443
1444
  /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1445
  /// super region.
1446
  const CXXBaseObjectRegion *
1447
  getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1448
40
                                  const SubRegion *superRegion) {
1449
40
    return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1450
40
                                  baseReg->isVirtual());
1451
40
  }
1452
1453
  /// Create a CXXDerivedObjectRegion with the given derived class for region
1454
  /// \p Super. This should not be used for casting an existing
1455
  /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
1456
  /// should be removed.
1457
  const CXXDerivedObjectRegion *
1458
  getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1459
                            const SubRegion *Super);
1460
1461
  const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1462
  const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1463
                                            CanQualType locTy,
1464
                                            AnalysisDeclContext *AC);
1465
1466
  /// getBlockDataRegion - Get the memory region associated with an instance
1467
  ///  of a block.  Unlike many other MemRegions, the LocationContext*
1468
  ///  argument is allowed to be NULL for cases where we have no known
1469
  ///  context.
1470
  const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1471
                                            const LocationContext *lc,
1472
                                            unsigned blockCount);
1473
1474
  /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
1475
  /// by static references. This differs from getCXXTempObjectRegion in the
1476
  /// super-region used.
1477
  const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
1478
1479
private:
1480
  template <typename RegionTy, typename SuperTy,
1481
            typename Arg1Ty>
1482
  RegionTy* getSubRegion(const Arg1Ty arg1,
1483
                         const SuperTy* superRegion);
1484
1485
  template <typename RegionTy, typename SuperTy,
1486
            typename Arg1Ty, typename Arg2Ty>
1487
  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1488
                         const SuperTy* superRegion);
1489
1490
  template <typename RegionTy, typename SuperTy,
1491
            typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1492
  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1493
                         const Arg3Ty arg3,
1494
                         const SuperTy* superRegion);
1495
1496
  template <typename REG>
1497
  const REG* LazyAllocate(REG*& region);
1498
1499
  template <typename REG, typename ARG>
1500
  const REG* LazyAllocate(REG*& region, ARG a);
1501
};
1502
1503
//===----------------------------------------------------------------------===//
1504
// Out-of-line member definitions.
1505
//===----------------------------------------------------------------------===//
1506
1507
611k
inline ASTContext &MemRegion::getContext() const {
1508
611k
  return getMemRegionManager().getContext();
1509
611k
}
1510
1511
//===----------------------------------------------------------------------===//
1512
// Means for storing region/symbol handling traits.
1513
//===----------------------------------------------------------------------===//
1514
1515
/// Information about invalidation for a particular region/symbol.
1516
class RegionAndSymbolInvalidationTraits {
1517
  using StorageTypeForKinds = unsigned char;
1518
1519
  llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1520
  llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1521
1522
  using const_region_iterator =
1523
      llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1524
  using const_symbol_iterator =
1525
      llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1526
1527
public:
1528
  /// Describes different invalidation traits.
1529
  enum InvalidationKinds {
1530
    /// Tells that a region's contents is not changed.
1531
    TK_PreserveContents = 0x1,
1532
1533
    /// Suppress pointer-escaping of a region.
1534
    TK_SuppressEscape = 0x2,
1535
1536
    // Do not invalidate super region.
1537
    TK_DoNotInvalidateSuperRegion = 0x4,
1538
1539
    /// When applied to a MemSpaceRegion, indicates the entire memory space
1540
    /// should be invalidated.
1541
    TK_EntireMemSpace = 0x8
1542
1543
    // Do not forget to extend StorageTypeForKinds if number of traits exceed
1544
    // the number of bits StorageTypeForKinds can store.
1545
  };
1546
1547
  void setTrait(SymbolRef Sym, InvalidationKinds IK);
1548
  void setTrait(const MemRegion *MR, InvalidationKinds IK);
1549
  bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1550
  bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1551
};
1552
1553
//===----------------------------------------------------------------------===//
1554
// Pretty-printing regions.
1555
//===----------------------------------------------------------------------===//
1556
332
inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1557
332
  R->dumpToStream(os);
1558
332
  return os;
1559
332
}
1560
1561
} // namespace ento
1562
1563
} // namespace clang
1564
1565
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H