Coverage Report

Created: 2022-05-17 06:19

/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
119k
  RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
76
77
1.68M
  const MemRegion *getRegion() const { return R; }
78
79
3.26M
  bool hasSymbolicOffset() const { return Offset == Symbolic; }
80
81
1.58M
  int64_t getOffset() const {
82
1.58M
    assert(!hasSymbolicOffset());
83
0
    return Offset;
84
1.58M
  }
85
86
772
  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
236k
  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
56.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
80.3k
  MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) {
204
80.3k
    assert(classof(this));
205
80.3k
  }
206
207
695k
  MemRegionManager &getMemRegionManager() const override { return Mgr; }
208
209
public:
210
50.9k
  bool isBoundable() const override { return false; }
211
212
  void Profile(llvm::FoldingSetNodeID &ID) const override;
213
214
5.59M
  static bool classof(const MemRegion *R) {
215
5.59M
    Kind k = R->getKind();
216
5.59M
    return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
217
5.59M
  }
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
10.4k
      : 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
16.0k
  GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) {
241
16.0k
    assert(classof(this));
242
16.0k
  }
243
244
public:
245
268k
  static bool classof(const MemRegion *R) {
246
268k
    Kind k = R->getKind();
247
268k
    return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
248
268k
  }
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
174
      : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
263
174
    assert(cr);
264
174
  }
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
7.84k
  static bool classof(const MemRegion *R) {
274
7.84k
    return R->getKind() == StaticGlobalSpaceRegionKind;
275
7.84k
  }
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
15.9k
      : GlobalsSpaceRegion(mgr, k) {
290
15.9k
    assert(classof(this));
291
15.9k
  }
292
293
public:
294
773k
  static bool classof(const MemRegion *R) {
295
773k
    Kind k = R->getKind();
296
773k
    return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
297
773k
           k <= END_NON_STATIC_GLOBAL_MEMSPACES;
298
773k
  }
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
7.79k
      : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
308
309
public:
310
  void dumpToStream(raw_ostream &os) const override;
311
312
22.9k
  static bool classof(const MemRegion *R) {
313
22.9k
    return R->getKind() == GlobalSystemSpaceRegionKind;
314
22.9k
  }
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
235
      : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
327
328
public:
329
  void dumpToStream(raw_ostream &os) const override;
330
331
373
  static bool classof(const MemRegion *R) {
332
373
    return R->getKind() == GlobalImmutableSpaceRegionKind;
333
373
  }
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.90k
      : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
344
345
public:
346
  void dumpToStream(raw_ostream &os) const override;
347
348
68
  static bool classof(const MemRegion *R) {
349
68
    return R->getKind() == GlobalInternalSpaceRegionKind;
350
68
  }
351
};
352
353
class HeapSpaceRegion : public MemSpaceRegion {
354
  friend class MemRegionManager;
355
356
  HeapSpaceRegion(MemRegionManager &mgr)
357
1.29k
      : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
358
359
public:
360
  void dumpToStream(raw_ostream &os) const override;
361
362
4.03k
  static bool classof(const MemRegion *R) {
363
4.03k
    return R->getKind() == HeapSpaceRegionKind;
364
4.03k
  }
365
};
366
367
class UnknownSpaceRegion : public MemSpaceRegion {
368
  friend class MemRegionManager;
369
370
  UnknownSpaceRegion(MemRegionManager &mgr)
371
9.53k
      : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
372
373
public:
374
  void dumpToStream(raw_ostream &os) const override;
375
376
100k
  static bool classof(const MemRegion *R) {
377
100k
    return R->getKind() == UnknownSpaceRegionKind;
378
100k
  }
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
42.9k
      : MemSpaceRegion(mgr, k), SFC(sfc) {
389
42.9k
    assert(classof(this));
390
0
    assert(sfc);
391
42.9k
  }
392
393
public:
394
1.97M
  const StackFrameContext *getStackFrame() const { return SFC; }
395
396
  void Profile(llvm::FoldingSetNodeID &ID) const override;
397
398
2.18M
  static bool classof(const MemRegion *R) {
399
2.18M
    Kind k = R->getKind();
400
2.18M
    return k >= BEGIN_STACK_MEMSPACES && 
k <= END_STACK_MEMSPACES2.08M
;
401
2.18M
  }
402
};
403
404
class StackLocalsSpaceRegion : public StackSpaceRegion {
405
  friend class MemRegionManager;
406
407
  StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
408
12.6k
      : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
409
410
public:
411
  void dumpToStream(raw_ostream &os) const override;
412
413
71.5k
  static bool classof(const MemRegion *R) {
414
71.5k
    return R->getKind() == StackLocalsSpaceRegionKind;
415
71.5k
  }
416
};
417
418
class StackArgumentsSpaceRegion : public StackSpaceRegion {
419
private:
420
  friend class MemRegionManager;
421
422
  StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
423
30.3k
      : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
424
425
public:
426
  void dumpToStream(raw_ostream &os) const override;
427
428
219k
  static bool classof(const MemRegion *R) {
429
219k
    return R->getKind() == StackArgumentsSpaceRegionKind;
430
219k
  }
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
156k
  SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
442
156k
    assert(classof(this));
443
0
    assert(sReg);
444
156k
  }
445
446
public:
447
12.0M
  const MemRegion* getSuperRegion() const {
448
12.0M
    return superRegion;
449
12.0M
  }
450
451
  MemRegionManager &getMemRegionManager() const override;
452
453
  bool isSubRegionOf(const MemRegion* R) const override;
454
455
16.0M
  static bool classof(const MemRegion* R) {
456
16.0M
    return R->getKind() > END_MEMSPACES;
457
16.0M
  }
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
91
      : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
477
91
    assert(Ex);
478
91
  }
479
480
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
481
                            unsigned Cnt, const MemRegion *superRegion);
482
483
public:
484
10
  const Expr *getExpr() const { return Ex; }
485
486
21
  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.4k
  static bool classof(const MemRegion* R) {
493
88.4k
    return R->getKind() == AllocaRegionKind;
494
88.4k
  }
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
136k
  TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
503
136k
    assert(classof(this));
504
136k
  }
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
80.9k
  bool isBoundable() const override { return true; }
514
515
770k
  static bool classof(const MemRegion* R) {
516
770k
    unsigned k = R->getKind();
517
770k
    return k >= BEGIN_TYPED_REGIONS && 
k <= END_TYPED_REGIONS726k
;
518
770k
  }
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
107k
  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
527
107k
    assert(classof(this));
528
107k
  }
529
530
public:
531
  virtual QualType getValueType() const = 0;
532
533
471k
  QualType getLocationType() const override {
534
    // FIXME: We can possibly optimize this later to cache this value.
535
471k
    QualType T = getValueType();
536
471k
    ASTContext &ctx = getContext();
537
471k
    if (T->getAs<ObjCObjectType>())
538
0
      return ctx.getObjCObjectPointerType(T);
539
471k
    return ctx.getPointerType(getValueType());
540
471k
  }
541
542
27.9k
  QualType getDesugaredValueType(ASTContext &Context) const {
543
27.9k
    QualType T = getValueType();
544
27.9k
    return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : 
T0
;
545
27.9k
  }
546
547
1.16M
  static bool classof(const MemRegion* R) {
548
1.16M
    unsigned k = R->getKind();
549
1.16M
    return k >= BEGIN_TYPED_VALUE_REGIONS && 
k <= END_TYPED_VALUE_REGIONS1.06M
;
550
1.16M
  }
551
};
552
553
class CodeTextRegion : public TypedRegion {
554
  void anchor() override;
555
556
protected:
557
28.4k
  CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
558
28.4k
    assert(classof(this));
559
28.4k
  }
560
561
public:
562
45
  bool isBoundable() const override { return false; }
563
564
44.6k
  static bool classof(const MemRegion* R) {
565
44.6k
    Kind k = R->getKind();
566
44.6k
    return k >= BEGIN_CODE_TEXT_REGIONS && 
k <= END_CODE_TEXT_REGIONS35.8k
;
567
44.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
28.0k
      : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
578
28.0k
    assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
579
28.0k
  }
580
581
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
582
                            const MemRegion*);
583
584
public:
585
138k
  QualType getLocationType() const override {
586
138k
    const ASTContext &Ctx = getContext();
587
138k
    if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
588
138k
      return Ctx.getPointerType(D->getType());
589
138k
    }
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
138k
  }
598
599
162k
  const NamedDecl *getDecl() const {
600
162k
    return FD;
601
162k
  }
602
603
  void dumpToStream(raw_ostream &os) const override;
604
605
  void Profile(llvm::FoldingSetNodeID& ID) const override;
606
607
700k
  static bool classof(const MemRegion* R) {
608
700k
    return R->getKind() == FunctionCodeRegionKind;
609
700k
  }
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
366
      : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
628
366
    assert(bd);
629
0
    assert(ac);
630
0
    assert(lTy->getTypePtr()->isBlockPointerType());
631
366
  }
632
633
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
634
                            CanQualType, const AnalysisDeclContext*,
635
                            const MemRegion*);
636
637
public:
638
418
  QualType getLocationType() const override {
639
418
    return locTy;
640
418
  }
641
642
3.67k
  const BlockDecl *getDecl() const {
643
3.67k
    return BD;
644
3.67k
  }
645
646
373
  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
34
  static bool classof(const MemRegion* R) {
653
34
    return R->getKind() == BlockCodeRegionKind;
654
34
  }
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
373
        BlockCount(count) {
676
373
    assert(bc);
677
0
    assert(lc);
678
0
    assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
679
373
           isa<StackLocalsSpaceRegion>(sreg) ||
680
373
           isa<UnknownSpaceRegion>(sreg));
681
373
  }
682
683
  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
684
                            const LocationContext *, unsigned,
685
                            const MemRegion *);
686
687
public:
688
375
  const BlockCodeRegion *getCodeRegion() const { return BC; }
689
690
2.90k
  const BlockDecl *getDecl() const { return BC->getDecl(); }
691
692
418
  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.05k
        : 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
0
      return I.R == R;
714
30
    }
715
716
5.85k
    bool operator!=(const referenced_vars_iterator &I) const {
717
5.85k
      assert((R == nullptr) == (I.R == nullptr));
718
0
      return I.R != R;
719
5.85k
    }
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
2.01M
  static bool classof(const MemRegion* R) {
740
2.01M
    return R->getKind() == BlockDataRegionKind;
741
2.01M
  }
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
19.7k
      : 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
19.7k
    assert(s && isa<SymbolData>(s));
764
0
    assert(s->getType()->isAnyPointerType() ||
765
19.7k
           s->getType()->isReferenceType() ||
766
19.7k
           s->getType()->isBlockPointerType());
767
0
    assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg) ||
768
19.7k
           isa<GlobalSystemSpaceRegion>(sreg));
769
19.7k
  }
770
771
public:
772
1.71M
  SymbolRef getSymbol() const { return sym; }
773
774
5.75k
  bool isBoundable() const override { return true; }
775
776
  void Profile(llvm::FoldingSetNodeID& ID) const override;
777
778
  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
779
                            SymbolRef sym,
780
                            const MemRegion* superRegion);
781
782
  void dumpToStream(raw_ostream &os) const override;
783
784
6.89M
  static bool classof(const MemRegion* R) {
785
6.89M
    return R->getKind() == SymbolicRegionKind;
786
6.89M
  }
787
};
788
789
/// StringRegion - Region associated with a StringLiteral.
790
class StringRegion : public TypedValueRegion {
791
  friend class MemRegionManager;
792
793
  const StringLiteral *Str;
794
795
  StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
796
4.34k
      : TypedValueRegion(sreg, StringRegionKind), Str(str) {
797
4.34k
    assert(str);
798
4.34k
  }
799
800
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
801
                            const StringLiteral *Str,
802
                            const MemRegion *superRegion);
803
804
public:
805
2.12k
  const StringLiteral *getStringLiteral() const { return Str; }
806
807
4.33k
  QualType getValueType() const override { return Str->getType(); }
808
809
72
  bool isBoundable() const override { return false; }
810
811
6.55k
  void Profile(llvm::FoldingSetNodeID& ID) const override {
812
6.55k
    ProfileRegion(ID, Str, superRegion);
813
6.55k
  }
814
815
  void dumpToStream(raw_ostream &os) const override;
816
817
22.3k
  static bool classof(const MemRegion* R) {
818
22.3k
    return R->getKind() == StringRegionKind;
819
22.3k
  }
820
};
821
822
/// The region associated with an ObjCStringLiteral.
823
class ObjCStringRegion : public TypedValueRegion {
824
  friend class MemRegionManager;
825
826
  const ObjCStringLiteral *Str;
827
828
  ObjCStringRegion(const ObjCStringLiteral *str,
829
                   const GlobalInternalSpaceRegion *sreg)
830
285
      : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
831
285
    assert(str);
832
285
  }
833
834
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
835
                            const ObjCStringLiteral *Str,
836
                            const MemRegion *superRegion);
837
838
public:
839
17
  const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
840
841
1.44k
  QualType getValueType() const override { return Str->getType(); }
842
843
299
  bool isBoundable() const override { return false; }
844
845
930
  void Profile(llvm::FoldingSetNodeID& ID) const override {
846
930
    ProfileRegion(ID, Str, superRegion);
847
930
  }
848
849
  void dumpToStream(raw_ostream &os) const override;
850
851
863
  static bool classof(const MemRegion* R) {
852
863
    return R->getKind() == ObjCStringRegionKind;
853
863
  }
854
};
855
856
/// CompoundLiteralRegion - A memory region representing a compound literal.
857
///   Compound literals are essentially temporaries that are stack allocated
858
///   or in the global constant pool.
859
class CompoundLiteralRegion : public TypedValueRegion {
860
  friend class MemRegionManager;
861
862
  const CompoundLiteralExpr *CL;
863
864
  CompoundLiteralRegion(const CompoundLiteralExpr *cl,
865
                        const MemSpaceRegion *sReg)
866
53
      : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
867
53
    assert(cl);
868
0
    assert(isa<GlobalInternalSpaceRegion>(sReg) ||
869
53
           isa<StackLocalsSpaceRegion>(sReg));
870
53
  }
871
872
  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
873
                            const CompoundLiteralExpr *CL,
874
                            const MemRegion* superRegion);
875
876
public:
877
227
  QualType getValueType() const override { return CL->getType(); }
878
879
0
  bool isBoundable() const override { return !CL->isFileScope(); }
880
881
  void Profile(llvm::FoldingSetNodeID& ID) const override;
882
883
  void dumpToStream(raw_ostream &os) const override;
884
885
3
  const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
886
887
115
  static bool classof(const MemRegion* R) {
888
115
    return R->getKind() == CompoundLiteralRegionKind;
889
115
  }
890
};
891
892
class DeclRegion : public TypedValueRegion {
893
protected:
894
69.2k
  DeclRegion(const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k) {
895
69.2k
    assert(classof(this));
896
69.2k
  }
897
898
public:
899
  virtual const ValueDecl *getDecl() const = 0;
900
901
70.9k
  static bool classof(const MemRegion* R) {
902
70.9k
    unsigned k = R->getKind();
903
70.9k
    return k >= BEGIN_DECL_REGIONS && 
k <= END_DECL_REGIONS70.7k
;
904
70.9k
  }
905
};
906
907
class VarRegion : public DeclRegion {
908
  friend class MemRegionManager;
909
910
protected:
911
  // Constructors and protected methods.
912
51.4k
  VarRegion(const MemRegion *sReg, Kind k) : DeclRegion(sReg, k) {
913
    // VarRegion appears in unknown space when it's a block variable as seen
914
    // from a block using it, when this block is analyzed at top-level.
915
    // Other block variables appear within block data regions,
916
    // which, unlike everything else on this list, are not memory spaces.
917
51.4k
    assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
918
51.4k
           isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
919
51.4k
  }
920
921
public:
922
  const VarDecl *getDecl() const override = 0;
923
924
  const StackFrameContext *getStackFrame() const;
925
926
0
  QualType getValueType() const override {
927
    // FIXME: We can cache this if needed.
928
0
    return getDecl()->getType();
929
0
  }
930
931
2.43M
  static bool classof(const MemRegion *R) {
932
2.43M
    unsigned k = R->getKind();
933
2.43M
    return k >= BEGIN_VAR_REGIONS && 
k <= END_VAR_REGIONS1.58M
;
934
2.43M
  }
935
};
936
937
class NonParamVarRegion : public VarRegion {
938
  friend class MemRegionManager;
939
940
  const VarDecl *VD;
941
942
  // Constructors and private methods.
943
  NonParamVarRegion(const VarDecl *vd, const MemRegion *sReg)
944
32.3k
      : VarRegion(sReg, NonParamVarRegionKind), VD(vd) {
945
    // VarRegion appears in unknown space when it's a block variable as seen
946
    // from a block using it, when this block is analyzed at top-level.
947
    // Other block variables appear within block data regions,
948
    // which, unlike everything else on this list, are not memory spaces.
949
32.3k
    assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
950
32.3k
           isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
951
32.3k
  }
952
953
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const VarDecl *VD,
954
                            const MemRegion *superRegion);
955
956
public:
957
  void Profile(llvm::FoldingSetNodeID &ID) const override;
958
959
2.94M
  const VarDecl *getDecl() const override { return VD; }
960
961
2.19M
  QualType getValueType() const override {
962
    // FIXME: We can cache this if needed.
963
2.19M
    return getDecl()->getType();
964
2.19M
  }
965
966
  void dumpToStream(raw_ostream &os) const override;
967
968
  bool canPrintPrettyAsExpr() const override;
969
970
  void printPrettyAsExpr(raw_ostream &os) const override;
971
972
153k
  static bool classof(const MemRegion* R) {
973
153k
    return R->getKind() == NonParamVarRegionKind;
974
153k
  }
975
};
976
977
/// ParamVarRegion - Represents a region for paremters. Only parameters of the
978
/// function in the current stack frame are represented as `ParamVarRegion`s.
979
/// Parameters of top-level analyzed functions as well as captured paremeters
980
/// by lambdas and blocks are repesented as `VarRegion`s.
981
982
// FIXME: `ParamVarRegion` only supports parameters of functions, C++
983
// constructors, blocks and Objective-C methods with existing `Decl`. Upon
984
// implementing stack frame creations for functions without decl (functions
985
// passed by unknown function pointer) methods of `ParamVarRegion` must be
986
// updated.
987
class ParamVarRegion : public VarRegion {
988
  friend class MemRegionManager;
989
990
  const Expr *OriginExpr;
991
  unsigned Index;
992
993
  ParamVarRegion(const Expr *OE, unsigned Idx, const MemRegion *SReg)
994
19.1k
      : VarRegion(SReg, ParamVarRegionKind), OriginExpr(OE), Index(Idx) {
995
19.1k
    assert(!cast<StackSpaceRegion>(SReg)->getStackFrame()->inTopFrame());
996
19.1k
  }
997
998
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
999
                            unsigned Idx, const MemRegion *SReg);
1000
1001
public:
1002
144k
  const Expr *getOriginExpr() const { return OriginExpr; }
1003
144k
  unsigned getIndex() const { return Index; }
1004
1005
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1006
1007
  void dumpToStream(raw_ostream &os) const override;
1008
1009
  QualType getValueType() const override;
1010
  const ParmVarDecl *getDecl() const override;
1011
1012
  bool canPrintPrettyAsExpr() const override;
1013
  void printPrettyAsExpr(raw_ostream &os) const override;
1014
1015
67.3k
  static bool classof(const MemRegion *R) {
1016
67.3k
    return R->getKind() == ParamVarRegionKind;
1017
67.3k
  }
1018
};
1019
1020
/// CXXThisRegion - Represents the region for the implicit 'this' parameter
1021
///  in a call to a C++ method.  This region doesn't represent the object
1022
///  referred to by 'this', but rather 'this' itself.
1023
class CXXThisRegion : public TypedValueRegion {
1024
  friend class MemRegionManager;
1025
1026
  CXXThisRegion(const PointerType *thisPointerTy,
1027
                const StackArgumentsSpaceRegion *sReg)
1028
      : TypedValueRegion(sReg, CXXThisRegionKind),
1029
14.2k
        ThisPointerTy(thisPointerTy) {
1030
14.2k
    assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
1031
14.2k
           "Invalid region type!");
1032
14.2k
  }
1033
1034
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1035
                            const PointerType *PT,
1036
                            const MemRegion *sReg);
1037
1038
public:
1039
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1040
1041
183k
  QualType getValueType() const override {
1042
183k
    return QualType(ThisPointerTy, 0);
1043
183k
  }
1044
1045
  void dumpToStream(raw_ostream &os) const override;
1046
1047
414k
  static bool classof(const MemRegion* R) {
1048
414k
    return R->getKind() == CXXThisRegionKind;
1049
414k
  }
1050
1051
private:
1052
  const PointerType *ThisPointerTy;
1053
};
1054
1055
class FieldRegion : public DeclRegion {
1056
  friend class MemRegionManager;
1057
1058
  const FieldDecl *FD;
1059
1060
  FieldRegion(const FieldDecl *fd, const SubRegion *sReg)
1061
17.2k
      : DeclRegion(sReg, FieldRegionKind), FD(fd) {}
1062
1063
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD,
1064
321k
                            const MemRegion* superRegion) {
1065
321k
    ID.AddInteger(static_cast<unsigned>(FieldRegionKind));
1066
321k
    ID.AddPointer(FD);
1067
321k
    ID.AddPointer(superRegion);
1068
321k
  }
1069
1070
public:
1071
2.89M
  const FieldDecl *getDecl() const override { return FD; }
1072
1073
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1074
1075
2.55M
  QualType getValueType() const override {
1076
    // FIXME: We can cache this if needed.
1077
2.55M
    return getDecl()->getType();
1078
2.55M
  }
1079
1080
  void dumpToStream(raw_ostream &os) const override;
1081
1082
  bool canPrintPretty() const override;
1083
  void printPretty(raw_ostream &os) const override;
1084
  bool canPrintPrettyAsExpr() const override;
1085
  void printPrettyAsExpr(raw_ostream &os) const override;
1086
1087
762k
  static bool classof(const MemRegion* R) {
1088
762k
    return R->getKind() == FieldRegionKind;
1089
762k
  }
1090
};
1091
1092
class ObjCIvarRegion : public DeclRegion {
1093
  friend class MemRegionManager;
1094
1095
  const ObjCIvarDecl *IVD;
1096
1097
  ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1098
1099
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1100
                            const MemRegion* superRegion);
1101
1102
public:
1103
  const ObjCIvarDecl *getDecl() const override;
1104
1105
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1106
1107
  QualType getValueType() const override;
1108
1109
  bool canPrintPrettyAsExpr() const override;
1110
  void printPrettyAsExpr(raw_ostream &os) const override;
1111
1112
  void dumpToStream(raw_ostream &os) const override;
1113
1114
436k
  static bool classof(const MemRegion* R) {
1115
436k
    return R->getKind() == ObjCIvarRegionKind;
1116
436k
  }
1117
};
1118
1119
//===----------------------------------------------------------------------===//
1120
// Auxiliary data classes for use with MemRegions.
1121
//===----------------------------------------------------------------------===//
1122
1123
class RegionRawOffset {
1124
  friend class ElementRegion;
1125
1126
  const MemRegion *Region;
1127
  CharUnits Offset;
1128
1129
  RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
1130
15.2k
      : Region(reg), Offset(offset) {}
1131
1132
public:
1133
  // FIXME: Eventually support symbolic offsets.
1134
484
  CharUnits getOffset() const { return Offset; }
1135
28.0k
  const MemRegion *getRegion() const { return Region; }
1136
1137
  void dumpToStream(raw_ostream &os) const;
1138
  void dump() const;
1139
};
1140
1141
/// ElementRegion is used to represent both array elements and casts.
1142
class ElementRegion : public TypedValueRegion {
1143
  friend class MemRegionManager;
1144
1145
  QualType ElementType;
1146
  NonLoc Index;
1147
1148
  ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1149
      : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1150
15.4k
        Index(Idx) {
1151
15.4k
    assert((!Idx.getAs<nonloc::ConcreteInt>() ||
1152
15.4k
            Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
1153
15.4k
           "The index must be signed");
1154
0
    assert(!elementType.isNull() && !elementType->isVoidType() &&
1155
15.4k
           "Invalid region type!");
1156
15.4k
  }
1157
1158
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1159
                            SVal Idx, const MemRegion* superRegion);
1160
1161
public:
1162
335k
  NonLoc getIndex() const { return Index; }
1163
1164
341k
  QualType getValueType() const override { return ElementType; }
1165
1166
34.7k
  QualType getElementType() const { return ElementType; }
1167
1168
  /// Compute the offset within the array. The array might also be a subobject.
1169
  RegionRawOffset getAsArrayOffset() const;
1170
1171
  void dumpToStream(raw_ostream &os) const override;
1172
1173
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1174
1175
3.96M
  static bool classof(const MemRegion* R) {
1176
3.96M
    return R->getKind() == ElementRegionKind;
1177
3.96M
  }
1178
};
1179
1180
// C++ temporary object associated with an expression.
1181
class CXXTempObjectRegion : public TypedValueRegion {
1182
  friend class MemRegionManager;
1183
1184
  Expr const *Ex;
1185
1186
  CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1187
2.89k
      : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1188
2.89k
    assert(E);
1189
0
    assert(isa<StackLocalsSpaceRegion>(sReg) ||
1190
2.89k
           isa<GlobalInternalSpaceRegion>(sReg));
1191
2.89k
  }
1192
1193
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1194
                            Expr const *E, const MemRegion *sReg);
1195
1196
public:
1197
50
  const Expr *getExpr() const { return Ex; }
1198
1199
46.9k
  QualType getValueType() const override { return Ex->getType(); }
1200
1201
  void dumpToStream(raw_ostream &os) const override;
1202
1203
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1204
1205
5.90k
  static bool classof(const MemRegion* R) {
1206
5.90k
    return R->getKind() == CXXTempObjectRegionKind;
1207
5.90k
  }
1208
};
1209
1210
// CXXBaseObjectRegion represents a base object within a C++ object. It is
1211
// identified by the base class declaration and the region of its parent object.
1212
class CXXBaseObjectRegion : public TypedValueRegion {
1213
  friend class MemRegionManager;
1214
1215
  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1216
1217
  CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1218
                      const SubRegion *SReg)
1219
1.08k
      : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1220
1.08k
    assert(RD);
1221
1.08k
  }
1222
1223
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1224
                            bool IsVirtual, const MemRegion *SReg);
1225
1226
public:
1227
10.1k
  const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1228
3.03k
  bool isVirtual() const { return Data.getInt(); }
1229
1230
  QualType getValueType() const override;
1231
1232
  void dumpToStream(raw_ostream &os) const override;
1233
1234
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1235
1236
  bool canPrintPrettyAsExpr() const override;
1237
1238
  void printPrettyAsExpr(raw_ostream &os) const override;
1239
1240
123k
  static bool classof(const MemRegion *region) {
1241
123k
    return region->getKind() == CXXBaseObjectRegionKind;
1242
123k
  }
1243
};
1244
1245
// CXXDerivedObjectRegion represents a derived-class object that surrounds
1246
// a C++ object. It is identified by the derived class declaration and the
1247
// region of its parent object. It is a bit counter-intuitive (but not otherwise
1248
// unseen) that this region represents a larger segment of memory that its
1249
// super-region.
1250
class CXXDerivedObjectRegion : public TypedValueRegion {
1251
  friend class MemRegionManager;
1252
1253
  const CXXRecordDecl *DerivedD;
1254
1255
  CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1256
24
      : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1257
24
    assert(DerivedD);
1258
    // In case of a concrete region, it should always be possible to model
1259
    // the base-to-derived cast by undoing a previous derived-to-base cast,
1260
    // otherwise the cast is most likely ill-formed.
1261
0
    assert(SReg->getSymbolicBase() &&
1262
24
           "Should have unwrapped a base region instead!");
1263
24
  }
1264
1265
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1266
                            const MemRegion *SReg);
1267
1268
public:
1269
525
  const CXXRecordDecl *getDecl() const { return DerivedD; }
1270
1271
  QualType getValueType() const override;
1272
1273
  void dumpToStream(raw_ostream &os) const override;
1274
1275
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1276
1277
  bool canPrintPrettyAsExpr() const override;
1278
1279
  void printPrettyAsExpr(raw_ostream &os) const override;
1280
1281
1.84k
  static bool classof(const MemRegion *region) {
1282
1.84k
    return region->getKind() == CXXDerivedObjectRegionKind;
1283
1.84k
  }
1284
};
1285
1286
template<typename RegionTy>
1287
245k
const RegionTy* MemRegion::getAs() const {
1288
245k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
188k
    return RT;
1290
1291
56.9k
  return nullptr;
1292
245k
}
clang::ento::TypedValueRegion const* clang::ento::MemRegion::getAs<clang::ento::TypedValueRegion>() const
Line
Count
Source
1287
919
const RegionTy* MemRegion::getAs() const {
1288
919
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
820
    return RT;
1290
1291
99
  return nullptr;
1292
919
}
clang::ento::VarRegion const* clang::ento::MemRegion::getAs<clang::ento::VarRegion>() const
Line
Count
Source
1287
756
const RegionTy* MemRegion::getAs() const {
1288
756
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
716
    return RT;
1290
1291
40
  return nullptr;
1292
756
}
clang::ento::CXXTempObjectRegion const* clang::ento::MemRegion::getAs<clang::ento::CXXTempObjectRegion>() const
Line
Count
Source
1287
3.42k
const RegionTy* MemRegion::getAs() const {
1288
3.42k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
300
    return RT;
1290
1291
3.12k
  return nullptr;
1292
3.42k
}
clang::ento::MemRegion const* clang::ento::MemRegion::getAs<clang::ento::MemRegion>() const
Line
Count
Source
1287
18
const RegionTy* MemRegion::getAs() const {
1288
18
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
18
    return RT;
1290
1291
0
  return nullptr;
1292
18
}
clang::ento::FieldRegion const* clang::ento::MemRegion::getAs<clang::ento::FieldRegion>() const
Line
Count
Source
1287
54
const RegionTy* MemRegion::getAs() const {
1288
54
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
23
    return RT;
1290
1291
31
  return nullptr;
1292
54
}
clang::ento::StackSpaceRegion const* clang::ento::MemRegion::getAs<clang::ento::StackSpaceRegion>() const
Line
Count
Source
1287
178k
const RegionTy* MemRegion::getAs() const {
1288
178k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
148k
    return RT;
1290
1291
29.9k
  return nullptr;
1292
178k
}
clang::ento::DeclRegion const* clang::ento::MemRegion::getAs<clang::ento::DeclRegion>() const
Line
Count
Source
1287
340
const RegionTy* MemRegion::getAs() const {
1288
340
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
137
    return RT;
1290
1291
203
  return nullptr;
1292
340
}
clang::ento::SubRegion const* clang::ento::MemRegion::getAs<clang::ento::SubRegion>() const
Line
Count
Source
1287
1.24k
const RegionTy* MemRegion::getAs() const {
1288
1.24k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
1.24k
    return RT;
1290
1291
0
  return nullptr;
1292
1.24k
}
clang::ento::SymbolicRegion const* clang::ento::MemRegion::getAs<clang::ento::SymbolicRegion>() const
Line
Count
Source
1287
34.0k
const RegionTy* MemRegion::getAs() const {
1288
34.0k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
12.2k
    return RT;
1290
1291
21.8k
  return nullptr;
1292
34.0k
}
clang::ento::ElementRegion const* clang::ento::MemRegion::getAs<clang::ento::ElementRegion>() const
Line
Count
Source
1287
650
const RegionTy* MemRegion::getAs() const {
1288
650
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
45
    return RT;
1290
1291
605
  return nullptr;
1292
650
}
clang::ento::FunctionCodeRegion const* clang::ento::MemRegion::getAs<clang::ento::FunctionCodeRegion>() const
Line
Count
Source
1287
25.0k
const RegionTy* MemRegion::getAs() const {
1288
25.0k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1289
24.0k
    return RT;
1290
1291
1.03k
  return nullptr;
1292
25.0k
}
1293
1294
template<typename RegionTy>
1295
2
const RegionTy* MemRegion::castAs() const {
1296
2
  return cast<RegionTy>(this);
1297
2
}
1298
1299
//===----------------------------------------------------------------------===//
1300
// MemRegionManager - Factory object for creating regions.
1301
//===----------------------------------------------------------------------===//
1302
1303
class MemRegionManager {
1304
  ASTContext &Ctx;
1305
  llvm::BumpPtrAllocator& A;
1306
1307
  llvm::FoldingSet<MemRegion> Regions;
1308
1309
  GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1310
  GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1311
  GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1312
1313
  llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1314
    StackLocalsSpaceRegions;
1315
  llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1316
    StackArgumentsSpaceRegions;
1317
  llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1318
    StaticsGlobalSpaceRegions;
1319
1320
  HeapSpaceRegion *heap = nullptr;
1321
  UnknownSpaceRegion *unknown = nullptr;
1322
  CodeSpaceRegion *code = nullptr;
1323
1324
public:
1325
15.3k
  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {}
1326
  ~MemRegionManager();
1327
1328
670k
  ASTContext &getContext() { return Ctx; }
1329
1330
236
  llvm::BumpPtrAllocator &getAllocator() { return A; }
1331
1332
  /// \returns The static size in bytes of the region \p MR.
1333
  /// \note The region \p MR must be a 'SubRegion'.
1334
  DefinedOrUnknownSVal getStaticSize(const MemRegion *MR,
1335
                                     SValBuilder &SVB) const;
1336
1337
  /// getStackLocalsRegion - Retrieve the memory region associated with the
1338
  ///  specified stack frame.
1339
  const StackLocalsSpaceRegion *
1340
  getStackLocalsRegion(const StackFrameContext *STC);
1341
1342
  /// getStackArgumentsRegion - Retrieve the memory region associated with
1343
  ///  function/method arguments of the specified stack frame.
1344
  const StackArgumentsSpaceRegion *
1345
  getStackArgumentsRegion(const StackFrameContext *STC);
1346
1347
  /// getGlobalsRegion - Retrieve the memory region associated with
1348
  ///  global variables.
1349
  const GlobalsSpaceRegion *getGlobalsRegion(
1350
      MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1351
      const CodeTextRegion *R = nullptr);
1352
1353
  /// getHeapRegion - Retrieve the memory region associated with the
1354
  ///  generic "heap".
1355
  const HeapSpaceRegion *getHeapRegion();
1356
1357
  /// getUnknownRegion - Retrieve the memory region associated with unknown
1358
  /// memory space.
1359
  const UnknownSpaceRegion *getUnknownRegion();
1360
1361
  const CodeSpaceRegion *getCodeRegion();
1362
1363
  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1364
  const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1365
                                      const LocationContext *LC);
1366
1367
  /// getCompoundLiteralRegion - Retrieve the region associated with a
1368
  ///  given CompoundLiteral.
1369
  const CompoundLiteralRegion*
1370
  getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1371
                           const LocationContext *LC);
1372
1373
  /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1374
  ///  parameter 'this'.
1375
  const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1376
                                        const LocationContext *LC);
1377
1378
  /// Retrieve or create a "symbolic" memory region.
1379
  /// If no memory space is specified, `UnknownSpaceRegion` will be used.
1380
  const SymbolicRegion *
1381
  getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace = nullptr);
1382
1383
  /// Return a unique symbolic region belonging to heap memory space.
1384
  const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1385
1386
  const StringRegion *getStringRegion(const StringLiteral *Str);
1387
1388
  const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1389
1390
  /// getVarRegion - Retrieve or create the memory region associated with
1391
  ///  a specified VarDecl and LocationContext.
1392
  const VarRegion *getVarRegion(const VarDecl *VD, const LocationContext *LC);
1393
1394
  /// getVarRegion - Retrieve or create the memory region associated with
1395
  ///  a specified VarDecl and LocationContext.
1396
  const NonParamVarRegion *getNonParamVarRegion(const VarDecl *VD,
1397
                                                const MemRegion *superR);
1398
1399
  /// getParamVarRegion - Retrieve or create the memory region
1400
  /// associated with a specified CallExpr, Index and LocationContext.
1401
  const ParamVarRegion *getParamVarRegion(const Expr *OriginExpr,
1402
                                          unsigned Index,
1403
                                          const LocationContext *LC);
1404
1405
  /// getElementRegion - Retrieve the memory region associated with the
1406
  ///  associated element type, index, and super region.
1407
  const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1408
                                        const SubRegion *superRegion,
1409
                                        ASTContext &Ctx);
1410
1411
  const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1412
256
                                                 const SubRegion *superRegion) {
1413
256
    return getElementRegion(ER->getElementType(), ER->getIndex(),
1414
256
                            superRegion, ER->getContext());
1415
256
  }
1416
1417
  /// getFieldRegion - Retrieve or create the memory region associated with
1418
  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1419
  ///  memory region (which typically represents the memory representing
1420
  ///  a structure or class).
1421
  const FieldRegion *getFieldRegion(const FieldDecl *fd,
1422
                                    const SubRegion* superRegion);
1423
1424
  const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1425
447
                                             const SubRegion *superRegion) {
1426
447
    return getFieldRegion(FR->getDecl(), superRegion);
1427
447
  }
1428
1429
  /// getObjCIvarRegion - Retrieve or create the memory region associated with
1430
  ///   a specified Objective-c instance variable.  'superRegion' corresponds
1431
  ///   to the containing region (which typically represents the Objective-C
1432
  ///   object).
1433
  const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1434
                                          const SubRegion* superRegion);
1435
1436
  const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1437
                                                    LocationContext const *LC);
1438
1439
  /// Create a CXXBaseObjectRegion with the given base class for region
1440
  /// \p Super.
1441
  ///
1442
  /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1443
  const CXXBaseObjectRegion *
1444
  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1445
                         bool IsVirtual);
1446
1447
  /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1448
  /// super region.
1449
  const CXXBaseObjectRegion *
1450
  getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1451
38
                                  const SubRegion *superRegion) {
1452
38
    return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1453
38
                                  baseReg->isVirtual());
1454
38
  }
1455
1456
  /// Create a CXXDerivedObjectRegion with the given derived class for region
1457
  /// \p Super. This should not be used for casting an existing
1458
  /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
1459
  /// should be removed.
1460
  const CXXDerivedObjectRegion *
1461
  getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1462
                            const SubRegion *Super);
1463
1464
  const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1465
  const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1466
                                            CanQualType locTy,
1467
                                            AnalysisDeclContext *AC);
1468
1469
  /// getBlockDataRegion - Get the memory region associated with an instance
1470
  ///  of a block.  Unlike many other MemRegions, the LocationContext*
1471
  ///  argument is allowed to be NULL for cases where we have no known
1472
  ///  context.
1473
  const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1474
                                            const LocationContext *lc,
1475
                                            unsigned blockCount);
1476
1477
  /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
1478
  /// by static references. This differs from getCXXTempObjectRegion in the
1479
  /// super-region used.
1480
  const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
1481
1482
private:
1483
  template <typename RegionTy, typename SuperTy,
1484
            typename Arg1Ty>
1485
  RegionTy* getSubRegion(const Arg1Ty arg1,
1486
                         const SuperTy* superRegion);
1487
1488
  template <typename RegionTy, typename SuperTy,
1489
            typename Arg1Ty, typename Arg2Ty>
1490
  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1491
                         const SuperTy* superRegion);
1492
1493
  template <typename RegionTy, typename SuperTy,
1494
            typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1495
  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1496
                         const Arg3Ty arg3,
1497
                         const SuperTy* superRegion);
1498
1499
  template <typename REG>
1500
  const REG* LazyAllocate(REG*& region);
1501
1502
  template <typename REG, typename ARG>
1503
  const REG* LazyAllocate(REG*& region, ARG a);
1504
};
1505
1506
//===----------------------------------------------------------------------===//
1507
// Out-of-line member definitions.
1508
//===----------------------------------------------------------------------===//
1509
1510
655k
inline ASTContext &MemRegion::getContext() const {
1511
655k
  return getMemRegionManager().getContext();
1512
655k
}
1513
1514
//===----------------------------------------------------------------------===//
1515
// Means for storing region/symbol handling traits.
1516
//===----------------------------------------------------------------------===//
1517
1518
/// Information about invalidation for a particular region/symbol.
1519
class RegionAndSymbolInvalidationTraits {
1520
  using StorageTypeForKinds = unsigned char;
1521
1522
  llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1523
  llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1524
1525
  using const_region_iterator =
1526
      llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1527
  using const_symbol_iterator =
1528
      llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1529
1530
public:
1531
  /// Describes different invalidation traits.
1532
  enum InvalidationKinds {
1533
    /// Tells that a region's contents is not changed.
1534
    TK_PreserveContents = 0x1,
1535
1536
    /// Suppress pointer-escaping of a region.
1537
    TK_SuppressEscape = 0x2,
1538
1539
    // Do not invalidate super region.
1540
    TK_DoNotInvalidateSuperRegion = 0x4,
1541
1542
    /// When applied to a MemSpaceRegion, indicates the entire memory space
1543
    /// should be invalidated.
1544
    TK_EntireMemSpace = 0x8
1545
1546
    // Do not forget to extend StorageTypeForKinds if number of traits exceed
1547
    // the number of bits StorageTypeForKinds can store.
1548
  };
1549
1550
  void setTrait(SymbolRef Sym, InvalidationKinds IK);
1551
  void setTrait(const MemRegion *MR, InvalidationKinds IK);
1552
  bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1553
  bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1554
};
1555
1556
//===----------------------------------------------------------------------===//
1557
// Pretty-printing regions.
1558
//===----------------------------------------------------------------------===//
1559
3.58k
inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1560
3.58k
  R->dumpToStream(os);
1561
3.58k
  return os;
1562
3.58k
}
1563
1564
} // namespace ento
1565
1566
} // namespace clang
1567
1568
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H