Coverage Report

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