Coverage Report

Created: 2020-02-15 09:57

/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
97.3k
  RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
76
77
1.79M
  const MemRegion *getRegion() const { return R; }
78
79
3.50M
  bool hasSymbolicOffset() const { return Offset == Symbolic; }
80
81
1.70M
  int64_t getOffset() const {
82
1.70M
    assert(!hasSymbolicOffset());
83
1.70M
    return Offset;
84
1.70M
  }
85
86
726
  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
187k
  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
108M
  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
64.7k
  MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) {
204
64.7k
    assert(classof(this));
205
64.7k
  }
206
207
830k
  MemRegionManager &getMemRegionManager() const override { return Mgr; }
208
209
public:
210
53.3k
  bool isBoundable() const override { return false; }
211
212
  void Profile(llvm::FoldingSetNodeID &ID) const override;
213
214
10.6M
  static bool classof(const MemRegion *R) {
215
10.6M
    Kind k = R->getKind();
216
10.6M
    return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
217
10.6M
  }
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
8.29k
      : 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
13.0k
  GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) {
241
13.0k
    assert(classof(this));
242
13.0k
  }
243
244
public:
245
472k
  static bool classof(const MemRegion *R) {
246
472k
    Kind k = R->getKind();
247
472k
    return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
248
472k
  }
249
};
250
251
/// The region of the static variables within the current CodeTextRegion
252
/// scope.
253
///
254
/// Currently, only the static locals are placed there, so we know that these
255
/// variables do not get invalidated by calls to other functions.
256
class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
257
  friend class MemRegionManager;
258
259
  const CodeTextRegion *CR;
260
261
  StaticGlobalSpaceRegion(MemRegionManager &mgr, const CodeTextRegion *cr)
262
165
      : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
263
165
    assert(cr);
264
165
  }
265
266
public:
267
  void Profile(llvm::FoldingSetNodeID &ID) const override;
268
269
  void dumpToStream(raw_ostream &os) const override;
270
271
0
  const CodeTextRegion *getCodeRegion() const { return CR; }
272
273
6.64k
  static bool classof(const MemRegion *R) {
274
6.64k
    return R->getKind() == StaticGlobalSpaceRegionKind;
275
6.64k
  }
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
12.8k
      : GlobalsSpaceRegion(mgr, k) {
290
12.8k
    assert(classof(this));
291
12.8k
  }
292
293
public:
294
1.26M
  static bool classof(const MemRegion *R) {
295
1.26M
    Kind k = R->getKind();
296
1.26M
    return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
297
1.26M
           k <= END_NON_STATIC_GLOBAL_MEMSPACES;
298
1.26M
  }
299
};
300
301
/// The region containing globals which are defined in system/external
302
/// headers and are considered modifiable by system calls (ex: errno).
303
class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
304
  friend class MemRegionManager;
305
306
  GlobalSystemSpaceRegion(MemRegionManager &mgr)
307
6.21k
      : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
308
309
public:
310
  void dumpToStream(raw_ostream &os) const override;
311
312
15.8k
  static bool classof(const MemRegion *R) {
313
15.8k
    return R->getKind() == GlobalSystemSpaceRegionKind;
314
15.8k
  }
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
220
      : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
327
328
public:
329
  void dumpToStream(raw_ostream &os) const override;
330
331
362
  static bool classof(const MemRegion *R) {
332
362
    return R->getKind() == GlobalImmutableSpaceRegionKind;
333
362
  }
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
6.41k
      : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
344
345
public:
346
  void dumpToStream(raw_ostream &os) const override;
347
348
7.55k
  static bool classof(const MemRegion *R) {
349
7.55k
    return R->getKind() == GlobalInternalSpaceRegionKind;
350
7.55k
  }
351
};
352
353
class HeapSpaceRegion : public MemSpaceRegion {
354
  friend class MemRegionManager;
355
356
  HeapSpaceRegion(MemRegionManager &mgr)
357
1.14k
      : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
358
359
public:
360
  void dumpToStream(raw_ostream &os) const override;
361
362
3.30k
  static bool classof(const MemRegion *R) {
363
3.30k
    return R->getKind() == HeapSpaceRegionKind;
364
3.30k
  }
365
};
366
367
class UnknownSpaceRegion : public MemSpaceRegion {
368
  friend class MemRegionManager;
369
370
  UnknownSpaceRegion(MemRegionManager &mgr)
371
7.37k
      : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
372
373
public:
374
  void dumpToStream(raw_ostream &os) const override;
375
376
84.5k
  static bool classof(const MemRegion *R) {
377
84.5k
    return R->getKind() == UnknownSpaceRegionKind;
378
84.5k
  }
379
};
380
381
class StackSpaceRegion : public MemSpaceRegion {
382
  virtual void anchor();
383
384
  const StackFrameContext *SFC;
385
386
protected:
387
  StackSpaceRegion(MemRegionManager &mgr, Kind k, const StackFrameContext *sfc)
388
34.9k
      : MemSpaceRegion(mgr, k), SFC(sfc) {
389
34.9k
    assert(classof(this));
390
34.9k
    assert(sfc);
391
34.9k
  }
392
393
public:
394
2.31M
  const StackFrameContext *getStackFrame() const { return SFC; }
395
396
  void Profile(llvm::FoldingSetNodeID &ID) const override;
397
398
4.19M
  static bool classof(const MemRegion *R) {
399
4.19M
    Kind k = R->getKind();
400
4.19M
    return k >= BEGIN_STACK_MEMSPACES && 
k <= END_STACK_MEMSPACES4.10M
;
401
4.19M
  }
402
};
403
404
class StackLocalsSpaceRegion : public StackSpaceRegion {
405
  friend class MemRegionManager;
406
407
  StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
408
10.5k
      : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
409
410
public:
411
  void dumpToStream(raw_ostream &os) const override;
412
413
73.9k
  static bool classof(const MemRegion *R) {
414
73.9k
    return R->getKind() == StackLocalsSpaceRegionKind;
415
73.9k
  }
416
};
417
418
class StackArgumentsSpaceRegion : public StackSpaceRegion {
419
private:
420
  friend class MemRegionManager;
421
422
  StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
423
24.3k
      : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
424
425
public:
426
  void dumpToStream(raw_ostream &os) const override;
427
428
536k
  static bool classof(const MemRegion *R) {
429
536k
    return R->getKind() == StackArgumentsSpaceRegionKind;
430
536k
  }
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
122k
  SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
442
122k
    assert(classof(this));
443
122k
    assert(sReg);
444
122k
  }
445
446
public:
447
16.1M
  const MemRegion* getSuperRegion() const {
448
16.1M
    return superRegion;
449
16.1M
  }
450
451
  MemRegionManager &getMemRegionManager() const override;
452
453
  bool isSubRegionOf(const MemRegion* R) const override;
454
455
39.1M
  static bool classof(const MemRegion* R) {
456
39.1M
    return R->getKind() > END_MEMSPACES;
457
39.1M
  }
458
};
459
460
//===----------------------------------------------------------------------===//
461
// MemRegion subclasses.
462
//===----------------------------------------------------------------------===//
463
464
/// AllocaRegion - A region that represents an untyped blob of bytes created
465
///  by a call to 'alloca'.
466
class AllocaRegion : public SubRegion {
467
  friend class MemRegionManager;
468
469
  // Block counter. Used to distinguish different pieces of memory allocated by
470
  // alloca at the same call site.
471
  unsigned Cnt;
472
473
  const Expr *Ex;
474
475
  AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
476
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
4
  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
89.7k
  static bool classof(const MemRegion* R) {
493
89.7k
    return R->getKind() == AllocaRegionKind;
494
89.7k
  }
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
107k
  TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
503
107k
    assert(classof(this));
504
107k
  }
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
35.8k
  bool isBoundable() const override { return true; }
514
515
1.60M
  static bool classof(const MemRegion* R) {
516
1.60M
    unsigned k = R->getKind();
517
1.60M
    return k >= BEGIN_TYPED_REGIONS && 
k <= END_TYPED_REGIONS1.57M
;
518
1.60M
  }
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
87.0k
  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
527
87.0k
    assert(classof(this));
528
87.0k
  }
529
530
public:
531
  virtual QualType getValueType() const = 0;
532
533
576k
  QualType getLocationType() const override {
534
576k
    // FIXME: We can possibly optimize this later to cache this value.
535
576k
    QualType T = getValueType();
536
576k
    ASTContext &ctx = getContext();
537
576k
    if (T->getAs<ObjCObjectType>())
538
0
      return ctx.getObjCObjectPointerType(T);
539
576k
    return ctx.getPointerType(getValueType());
540
576k
  }
541
542
30.9k
  QualType getDesugaredValueType(ASTContext &Context) const {
543
30.9k
    QualType T = getValueType();
544
30.9k
    return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : 
T0
;
545
30.9k
  }
546
547
2.92M
  static bool classof(const MemRegion* R) {
548
2.92M
    unsigned k = R->getKind();
549
2.92M
    return k >= BEGIN_TYPED_VALUE_REGIONS && 
k <= END_TYPED_VALUE_REGIONS2.83M
;
550
2.92M
  }
551
};
552
553
class CodeTextRegion : public TypedRegion {
554
  void anchor() override;
555
556
protected:
557
20.1k
  CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
558
20.1k
    assert(classof(this));
559
20.1k
  }
560
561
public:
562
35
  bool isBoundable() const override { return false; }
563
564
42.7k
  static bool classof(const MemRegion* R) {
565
42.7k
    Kind k = R->getKind();
566
42.7k
    return k >= BEGIN_CODE_TEXT_REGIONS && 
k <= END_CODE_TEXT_REGIONS33.6k
;
567
42.7k
  }
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
19.8k
      : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
578
19.8k
    assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
579
19.8k
  }
580
581
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
582
                            const MemRegion*);
583
584
public:
585
157k
  QualType getLocationType() const override {
586
157k
    const ASTContext &Ctx = getContext();
587
157k
    if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
588
157k
      return Ctx.getPointerType(D->getType());
589
157k
    }
590
0
591
0
    assert(isa<ObjCMethodDecl>(FD));
592
0
    assert(false && "Getting the type of ObjCMethod is not supported yet");
593
0
594
0
    // TODO: We might want to return a different type here (ex: id (*ty)(...))
595
0
    //       depending on how it is used.
596
0
    return {};
597
0
  }
598
599
253k
  const NamedDecl *getDecl() const {
600
253k
    return FD;
601
253k
  }
602
603
  void dumpToStream(raw_ostream &os) const override;
604
605
  void Profile(llvm::FoldingSetNodeID& ID) const override;
606
607
1.13M
  static bool classof(const MemRegion* R) {
608
1.13M
    return R->getKind() == FunctionCodeRegionKind;
609
1.13M
  }
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
355
      : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
628
355
    assert(bd);
629
355
    assert(ac);
630
355
    assert(lTy->getTypePtr()->isBlockPointerType());
631
355
  }
632
633
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
634
                            CanQualType, const AnalysisDeclContext*,
635
                            const MemRegion*);
636
637
public:
638
402
  QualType getLocationType() const override {
639
402
    return locTy;
640
402
  }
641
642
3.13k
  const BlockDecl *getDecl() const {
643
3.13k
    return BD;
644
3.13k
  }
645
646
362
  AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
647
648
  void dumpToStream(raw_ostream &os) const override;
649
650
  void Profile(llvm::FoldingSetNodeID& ID) const override;
651
652
68
  static bool classof(const MemRegion* R) {
653
68
    return R->getKind() == BlockCodeRegionKind;
654
68
  }
655
};
656
657
/// BlockDataRegion - A region that represents a block instance.
658
///  Blocks are represented with two kinds of regions.  BlockCodeRegions
659
///  represent the "code", while BlockDataRegions represent instances of blocks,
660
///  which correspond to "code+data".  The distinction is important, because
661
///  like a closure a block captures the values of externally referenced
662
///  variables.
663
class BlockDataRegion : public TypedRegion {
664
  friend class MemRegionManager;
665
666
  const BlockCodeRegion *BC;
667
  const LocationContext *LC; // Can be null
668
  unsigned BlockCount;
669
  void *ReferencedVars = nullptr;
670
  void *OriginalVars = nullptr;
671
672
  BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
673
                  unsigned count, const MemSpaceRegion *sreg)
674
      : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
675
362
        BlockCount(count) {
676
362
    assert(bc);
677
362
    assert(lc);
678
362
    assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
679
362
           isa<StackLocalsSpaceRegion>(sreg) ||
680
362
           isa<UnknownSpaceRegion>(sreg));
681
362
  }
682
683
  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
684
                            const LocationContext *, unsigned,
685
                            const MemRegion *);
686
687
public:
688
364
  const BlockCodeRegion *getCodeRegion() const { return BC; }
689
690
2.39k
  const BlockDecl *getDecl() const { return BC->getDecl(); }
691
692
402
  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
5.91k
        : R(r), OriginalR(originalR) {}
702
703
2.94k
    const VarRegion *getCapturedRegion() const {
704
2.94k
      return cast<VarRegion>(*R);
705
2.94k
    }
706
707
720
    const VarRegion *getOriginalRegion() const {
708
720
      return cast<VarRegion>(*OriginalR);
709
720
    }
710
711
29
    bool operator==(const referenced_vars_iterator &I) const {
712
29
      assert((R == nullptr) == (I.R == nullptr));
713
29
      return I.R == R;
714
29
    }
715
716
5.76k
    bool operator!=(const referenced_vars_iterator &I) const {
717
5.76k
      assert((R == nullptr) == (I.R == nullptr));
718
5.76k
      return I.R != R;
719
5.76k
    }
720
721
2.80k
    referenced_vars_iterator &operator++() {
722
2.80k
      ++R;
723
2.80k
      ++OriginalR;
724
2.80k
      return *this;
725
2.80k
    }
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.89M
  static bool classof(const MemRegion* R) {
740
2.89M
    return R->getKind() == BlockDataRegionKind;
741
2.89M
  }
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
15.0k
      : SubRegion(sreg, SymbolicRegionKind), sym(s) {
761
15.0k
    // Because pointer arithmetic is represented by ElementRegion layers,
762
15.0k
    // the base symbol here should not contain any arithmetic.
763
15.0k
    assert(s && isa<SymbolData>(s));
764
15.0k
    assert(s->getType()->isAnyPointerType() ||
765
15.0k
           s->getType()->isReferenceType() ||
766
15.0k
           s->getType()->isBlockPointerType());
767
15.0k
    assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
768
15.0k
  }
769
770
public:
771
1.33M
  SymbolRef getSymbol() const { return sym; }
772
773
5.49k
  bool isBoundable() const override { return true; }
774
775
  void Profile(llvm::FoldingSetNodeID& ID) const override;
776
777
  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
778
                            SymbolRef sym,
779
                            const MemRegion* superRegion);
780
781
  void dumpToStream(raw_ostream &os) const override;
782
783
11.8M
  static bool classof(const MemRegion* R) {
784
11.8M
    return R->getKind() == SymbolicRegionKind;
785
11.8M
  }
786
};
787
788
/// StringRegion - Region associated with a StringLiteral.
789
class StringRegion : public TypedValueRegion {
790
  friend class MemRegionManager;
791
792
  const StringLiteral *Str;
793
794
  StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
795
2.81k
      : TypedValueRegion(sreg, StringRegionKind), Str(str) {
796
2.81k
    assert(str);
797
2.81k
  }
798
799
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
800
                            const StringLiteral *Str,
801
                            const MemRegion *superRegion);
802
803
public:
804
2.05k
  const StringLiteral *getStringLiteral() const { return Str; }
805
806
3.29k
  QualType getValueType() const override { return Str->getType(); }
807
808
46
  bool isBoundable() const override { return false; }
809
810
4.28k
  void Profile(llvm::FoldingSetNodeID& ID) const override {
811
4.28k
    ProfileRegion(ID, Str, superRegion);
812
4.28k
  }
813
814
  void dumpToStream(raw_ostream &os) const override;
815
816
28.7k
  static bool classof(const MemRegion* R) {
817
28.7k
    return R->getKind() == StringRegionKind;
818
28.7k
  }
819
};
820
821
/// The region associated with an ObjCStringLiteral.
822
class ObjCStringRegion : public TypedValueRegion {
823
  friend class MemRegionManager;
824
825
  const ObjCStringLiteral *Str;
826
827
  ObjCStringRegion(const ObjCStringLiteral *str,
828
                   const GlobalInternalSpaceRegion *sreg)
829
282
      : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
830
282
    assert(str);
831
282
  }
832
833
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
834
                            const ObjCStringLiteral *Str,
835
                            const MemRegion *superRegion);
836
837
public:
838
17
  const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
839
840
1.42k
  QualType getValueType() const override { return Str->getType(); }
841
842
296
  bool isBoundable() const override { return false; }
843
844
969
  void Profile(llvm::FoldingSetNodeID& ID) const override {
845
969
    ProfileRegion(ID, Str, superRegion);
846
969
  }
847
848
  void dumpToStream(raw_ostream &os) const override;
849
850
1.68k
  static bool classof(const MemRegion* R) {
851
1.68k
    return R->getKind() == ObjCStringRegionKind;
852
1.68k
  }
853
};
854
855
/// CompoundLiteralRegion - A memory region representing a compound literal.
856
///   Compound literals are essentially temporaries that are stack allocated
857
///   or in the global constant pool.
858
class CompoundLiteralRegion : public TypedValueRegion {
859
  friend class MemRegionManager;
860
861
  const CompoundLiteralExpr *CL;
862
863
  CompoundLiteralRegion(const CompoundLiteralExpr *cl,
864
                        const MemSpaceRegion *sReg)
865
48
      : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
866
48
    assert(cl);
867
48
    assert(isa<GlobalInternalSpaceRegion>(sReg) ||
868
48
           isa<StackLocalsSpaceRegion>(sReg));
869
48
  }
870
871
  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
872
                            const CompoundLiteralExpr *CL,
873
                            const MemRegion* superRegion);
874
875
public:
876
209
  QualType getValueType() const override { return CL->getType(); }
877
878
0
  bool isBoundable() const override { return !CL->isFileScope(); }
879
880
  void Profile(llvm::FoldingSetNodeID& ID) const override;
881
882
  void dumpToStream(raw_ostream &os) const override;
883
884
3
  const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
885
886
25.0k
  static bool classof(const MemRegion* R) {
887
25.0k
    return R->getKind() == CompoundLiteralRegionKind;
888
25.0k
  }
889
};
890
891
class DeclRegion : public TypedValueRegion {
892
protected:
893
  const ValueDecl *D;
894
895
  DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k)
896
55.6k
      : TypedValueRegion(sReg, k), D(d) {
897
55.6k
    assert(classof(this));
898
55.6k
    assert(d && d->isCanonicalDecl());
899
55.6k
  }
900
901
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
902
                      const MemRegion* superRegion, Kind k);
903
904
public:
905
1.12k
  const ValueDecl *getDecl() const { return D; }
906
  void Profile(llvm::FoldingSetNodeID& ID) const override;
907
908
58.1k
  static bool classof(const MemRegion* R) {
909
58.1k
    unsigned k = R->getKind();
910
58.1k
    return k >= BEGIN_DECL_REGIONS && 
k <= END_DECL_REGIONS58.1k
;
911
58.1k
  }
912
};
913
914
class VarRegion : public DeclRegion {
915
  friend class MemRegionManager;
916
917
  // Constructors and private methods.
918
  VarRegion(const VarDecl *vd, const MemRegion *sReg)
919
41.0k
      : DeclRegion(vd, sReg, VarRegionKind) {
920
41.0k
    // VarRegion appears in unknown space when it's a block variable as seen
921
41.0k
    // from a block using it, when this block is analyzed at top-level.
922
41.0k
    // Other block variables appear within block data regions,
923
41.0k
    // which, unlike everything else on this list, are not memory spaces.
924
41.0k
    assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
925
41.0k
           isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
926
41.0k
  }
927
928
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
929
694k
                            const MemRegion *superRegion) {
930
694k
    DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
931
694k
  }
932
933
public:
934
  void Profile(llvm::FoldingSetNodeID& ID) const override;
935
936
3.18M
  const VarDecl *getDecl() const { return cast<VarDecl>(D); }
937
938
  const StackFrameContext *getStackFrame() const;
939
940
2.05M
  QualType getValueType() const override {
941
2.05M
    // FIXME: We can cache this if needed.
942
2.05M
    return getDecl()->getType();
943
2.05M
  }
944
945
  void dumpToStream(raw_ostream &os) const override;
946
947
  bool canPrintPrettyAsExpr() const override;
948
949
  void printPrettyAsExpr(raw_ostream &os) const override;
950
951
7.20M
  static bool classof(const MemRegion* R) {
952
7.20M
    return R->getKind() == VarRegionKind;
953
7.20M
  }
954
};
955
956
/// CXXThisRegion - Represents the region for the implicit 'this' parameter
957
///  in a call to a C++ method.  This region doesn't represent the object
958
///  referred to by 'this', but rather 'this' itself.
959
class CXXThisRegion : public TypedValueRegion {
960
  friend class MemRegionManager;
961
962
  CXXThisRegion(const PointerType *thisPointerTy,
963
                const StackArgumentsSpaceRegion *sReg)
964
      : TypedValueRegion(sReg, CXXThisRegionKind),
965
11.5k
        ThisPointerTy(thisPointerTy) {
966
11.5k
    assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
967
11.5k
           "Invalid region type!");
968
11.5k
  }
969
970
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
971
                            const PointerType *PT,
972
                            const MemRegion *sReg);
973
974
public:
975
  void Profile(llvm::FoldingSetNodeID &ID) const override;
976
977
271k
  QualType getValueType() const override {
978
271k
    return QualType(ThisPointerTy, 0);
979
271k
  }
980
981
  void dumpToStream(raw_ostream &os) const override;
982
983
1.29M
  static bool classof(const MemRegion* R) {
984
1.29M
    return R->getKind() == CXXThisRegionKind;
985
1.29M
  }
986
987
private:
988
  const PointerType *ThisPointerTy;
989
};
990
991
class FieldRegion : public DeclRegion {
992
  friend class MemRegionManager;
993
994
  FieldRegion(const FieldDecl *fd, const SubRegion* sReg)
995
14.0k
      : DeclRegion(fd, sReg, FieldRegionKind) {}
996
997
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
998
135k
                            const MemRegion* superRegion) {
999
135k
    DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
1000
135k
  }
1001
1002
public:
1003
930k
  const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
1004
1005
810k
  QualType getValueType() const override {
1006
810k
    // FIXME: We can cache this if needed.
1007
810k
    return getDecl()->getType();
1008
810k
  }
1009
1010
  void dumpToStream(raw_ostream &os) const override;
1011
1012
  bool canPrintPretty() const override;
1013
  void printPretty(raw_ostream &os) const override;
1014
  bool canPrintPrettyAsExpr() const override;
1015
  void printPrettyAsExpr(raw_ostream &os) const override;
1016
1017
1.12M
  static bool classof(const MemRegion* R) {
1018
1.12M
    return R->getKind() == FieldRegionKind;
1019
1.12M
  }
1020
};
1021
1022
class ObjCIvarRegion : public DeclRegion {
1023
  friend class MemRegionManager;
1024
1025
  ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1026
1027
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1028
                            const MemRegion* superRegion);
1029
1030
public:
1031
  const ObjCIvarDecl *getDecl() const;
1032
  QualType getValueType() const override;
1033
1034
  bool canPrintPrettyAsExpr() const override;
1035
  void printPrettyAsExpr(raw_ostream &os) const override;
1036
1037
  void dumpToStream(raw_ostream &os) const override;
1038
1039
447k
  static bool classof(const MemRegion* R) {
1040
447k
    return R->getKind() == ObjCIvarRegionKind;
1041
447k
  }
1042
};
1043
1044
//===----------------------------------------------------------------------===//
1045
// Auxiliary data classes for use with MemRegions.
1046
//===----------------------------------------------------------------------===//
1047
1048
class RegionRawOffset {
1049
  friend class ElementRegion;
1050
1051
  const MemRegion *Region;
1052
  CharUnits Offset;
1053
1054
  RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
1055
18.8k
      : Region(reg), Offset(offset) {}
1056
1057
public:
1058
  // FIXME: Eventually support symbolic offsets.
1059
414
  CharUnits getOffset() const { return Offset; }
1060
34.1k
  const MemRegion *getRegion() const { return Region; }
1061
1062
  void dumpToStream(raw_ostream &os) const;
1063
  void dump() const;
1064
};
1065
1066
/// ElementRegion is used to represent both array elements and casts.
1067
class ElementRegion : public TypedValueRegion {
1068
  friend class MemRegionManager;
1069
1070
  QualType ElementType;
1071
  NonLoc Index;
1072
1073
  ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1074
      : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1075
11.7k
        Index(Idx) {
1076
11.7k
    assert((!Idx.getAs<nonloc::ConcreteInt>() ||
1077
11.7k
            Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
1078
11.7k
           "The index must be signed");
1079
11.7k
    assert(!elementType.isNull() && !elementType->isVoidType() &&
1080
11.7k
           "Invalid region type!");
1081
11.7k
  }
1082
1083
  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1084
                            SVal Idx, const MemRegion* superRegion);
1085
1086
public:
1087
425k
  NonLoc getIndex() const { return Index; }
1088
1089
341k
  QualType getValueType() const override { return ElementType; }
1090
1091
38.2k
  QualType getElementType() const { return ElementType; }
1092
1093
  /// Compute the offset within the array. The array might also be a subobject.
1094
  RegionRawOffset getAsArrayOffset() const;
1095
1096
  void dumpToStream(raw_ostream &os) const override;
1097
1098
  void Profile(llvm::FoldingSetNodeID& ID) const override;
1099
1100
5.95M
  static bool classof(const MemRegion* R) {
1101
5.95M
    return R->getKind() == ElementRegionKind;
1102
5.95M
  }
1103
};
1104
1105
// C++ temporary object associated with an expression.
1106
class CXXTempObjectRegion : public TypedValueRegion {
1107
  friend class MemRegionManager;
1108
1109
  Expr const *Ex;
1110
1111
  CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1112
3.87k
      : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1113
3.87k
    assert(E);
1114
3.87k
    assert(isa<StackLocalsSpaceRegion>(sReg) ||
1115
3.87k
           isa<GlobalInternalSpaceRegion>(sReg));
1116
3.87k
  }
1117
1118
  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1119
                            Expr const *E, const MemRegion *sReg);
1120
1121
public:
1122
22
  const Expr *getExpr() const { return Ex; }
1123
1124
188k
  QualType getValueType() const override { return Ex->getType(); }
1125
1126
  void dumpToStream(raw_ostream &os) const override;
1127
1128
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1129
1130
29.2k
  static bool classof(const MemRegion* R) {
1131
29.2k
    return R->getKind() == CXXTempObjectRegionKind;
1132
29.2k
  }
1133
};
1134
1135
// CXXBaseObjectRegion represents a base object within a C++ object. It is
1136
// identified by the base class declaration and the region of its parent object.
1137
class CXXBaseObjectRegion : public TypedValueRegion {
1138
  friend class MemRegionManager;
1139
1140
  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1141
1142
  CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1143
                      const SubRegion *SReg)
1144
1.05k
      : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1145
1.05k
    assert(RD);
1146
1.05k
  }
1147
1148
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1149
                            bool IsVirtual, const MemRegion *SReg);
1150
1151
public:
1152
9.76k
  const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1153
2.98k
  bool isVirtual() const { return Data.getInt(); }
1154
1155
  QualType getValueType() const override;
1156
1157
  void dumpToStream(raw_ostream &os) const override;
1158
1159
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1160
1161
  bool canPrintPrettyAsExpr() const override;
1162
1163
  void printPrettyAsExpr(raw_ostream &os) const override;
1164
1165
115k
  static bool classof(const MemRegion *region) {
1166
115k
    return region->getKind() == CXXBaseObjectRegionKind;
1167
115k
  }
1168
};
1169
1170
// CXXDerivedObjectRegion represents a derived-class object that surrounds
1171
// a C++ object. It is identified by the derived class declaration and the
1172
// region of its parent object. It is a bit counter-intuitive (but not otherwise
1173
// unseen) that this region represents a larger segment of memory that its
1174
// super-region.
1175
class CXXDerivedObjectRegion : public TypedValueRegion {
1176
  friend class MemRegionManager;
1177
1178
  const CXXRecordDecl *DerivedD;
1179
1180
  CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1181
20
      : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1182
20
    assert(DerivedD);
1183
20
    // In case of a concrete region, it should always be possible to model
1184
20
    // the base-to-derived cast by undoing a previous derived-to-base cast,
1185
20
    // otherwise the cast is most likely ill-formed.
1186
20
    assert(SReg->getSymbolicBase() &&
1187
20
           "Should have unwrapped a base region instead!");
1188
20
  }
1189
1190
  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1191
                            const MemRegion *SReg);
1192
1193
public:
1194
42
  const CXXRecordDecl *getDecl() const { return DerivedD; }
1195
1196
  QualType getValueType() const override;
1197
1198
  void dumpToStream(raw_ostream &os) const override;
1199
1200
  void Profile(llvm::FoldingSetNodeID &ID) const override;
1201
1202
  bool canPrintPrettyAsExpr() const override;
1203
1204
  void printPrettyAsExpr(raw_ostream &os) const override;
1205
1206
1.80k
  static bool classof(const MemRegion *region) {
1207
1.80k
    return region->getKind() == CXXDerivedObjectRegionKind;
1208
1.80k
  }
1209
};
1210
1211
template<typename RegionTy>
1212
127k
const RegionTy* MemRegion::getAs() const {
1213
127k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
108k
    return RT;
1215
19.0k
1216
19.0k
  return nullptr;
1217
19.0k
}
clang::ento::TypedValueRegion const* clang::ento::MemRegion::getAs<clang::ento::TypedValueRegion>() const
Line
Count
Source
1212
901
const RegionTy* MemRegion::getAs() const {
1213
901
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
804
    return RT;
1215
97
1216
97
  return nullptr;
1217
97
}
clang::ento::SymbolicRegion const* clang::ento::MemRegion::getAs<clang::ento::SymbolicRegion>() const
Line
Count
Source
1212
25.3k
const RegionTy* MemRegion::getAs() const {
1213
25.3k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
10.1k
    return RT;
1215
15.2k
1216
15.2k
  return nullptr;
1217
15.2k
}
clang::ento::VarRegion const* clang::ento::MemRegion::getAs<clang::ento::VarRegion>() const
Line
Count
Source
1212
614
const RegionTy* MemRegion::getAs() const {
1213
614
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
583
    return RT;
1215
31
1216
31
  return nullptr;
1217
31
}
clang::ento::CXXTempObjectRegion const* clang::ento::MemRegion::getAs<clang::ento::CXXTempObjectRegion>() const
Line
Count
Source
1212
3.27k
const RegionTy* MemRegion::getAs() const {
1213
3.27k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
326
    return RT;
1215
2.94k
1216
2.94k
  return nullptr;
1217
2.94k
}
clang::ento::ElementRegion const* clang::ento::MemRegion::getAs<clang::ento::ElementRegion>() const
Line
Count
Source
1212
129
const RegionTy* MemRegion::getAs() const {
1213
129
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
32
    return RT;
1215
97
1216
97
  return nullptr;
1217
97
}
clang::ento::MemRegion const* clang::ento::MemRegion::getAs<clang::ento::MemRegion>() const
Line
Count
Source
1212
18
const RegionTy* MemRegion::getAs() const {
1213
18
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
18
    return RT;
1215
0
1216
0
  return nullptr;
1217
0
}
clang::ento::FieldRegion const* clang::ento::MemRegion::getAs<clang::ento::FieldRegion>() const
Line
Count
Source
1212
23
const RegionTy* MemRegion::getAs() const {
1213
23
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
4
    return RT;
1215
19
1216
19
  return nullptr;
1217
19
}
clang::ento::DeclRegion const* clang::ento::MemRegion::getAs<clang::ento::DeclRegion>() const
Line
Count
Source
1212
305
const RegionTy* MemRegion::getAs() const {
1213
305
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
106
    return RT;
1215
199
1216
199
  return nullptr;
1217
199
}
clang::ento::SubRegion const* clang::ento::MemRegion::getAs<clang::ento::SubRegion>() const
Line
Count
Source
1212
1.06k
const RegionTy* MemRegion::getAs() const {
1213
1.06k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
1.06k
    return RT;
1215
0
1216
0
  return nullptr;
1217
0
}
clang::ento::FunctionCodeRegion const* clang::ento::MemRegion::getAs<clang::ento::FunctionCodeRegion>() const
Line
Count
Source
1212
96.2k
const RegionTy* MemRegion::getAs() const {
1213
96.2k
  if (const auto *RT = dyn_cast<RegionTy>(this))
1214
95.8k
    return RT;
1215
403
1216
403
  return nullptr;
1217
403
}
1218
1219
template<typename RegionTy>
1220
613
const RegionTy* MemRegion::castAs() const {
1221
613
  return cast<RegionTy>(this);
1222
613
}
1223
1224
//===----------------------------------------------------------------------===//
1225
// MemRegionManager - Factory object for creating regions.
1226
//===----------------------------------------------------------------------===//
1227
1228
class MemRegionManager {
1229
  ASTContext &Ctx;
1230
  llvm::BumpPtrAllocator& A;
1231
1232
  llvm::FoldingSet<MemRegion> Regions;
1233
1234
  GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1235
  GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1236
  GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1237
1238
  llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1239
    StackLocalsSpaceRegions;
1240
  llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1241
    StackArgumentsSpaceRegions;
1242
  llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1243
    StaticsGlobalSpaceRegions;
1244
1245
  HeapSpaceRegion *heap = nullptr;
1246
  UnknownSpaceRegion *unknown = nullptr;
1247
  CodeSpaceRegion *code = nullptr;
1248
1249
public:
1250
12.6k
  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {}
1251
  ~MemRegionManager();
1252
1253
799k
  ASTContext &getContext() { return Ctx; }
1254
1255
233
  llvm::BumpPtrAllocator &getAllocator() { return A; }
1256
1257
  /// \returns The static size in bytes of the region \p MR.
1258
  /// \note The region \p MR must be a 'SubRegion'.
1259
  DefinedOrUnknownSVal getStaticSize(const MemRegion *MR,
1260
                                     SValBuilder &SVB) const;
1261
1262
  /// getStackLocalsRegion - Retrieve the memory region associated with the
1263
  ///  specified stack frame.
1264
  const StackLocalsSpaceRegion *
1265
  getStackLocalsRegion(const StackFrameContext *STC);
1266
1267
  /// getStackArgumentsRegion - Retrieve the memory region associated with
1268
  ///  function/method arguments of the specified stack frame.
1269
  const StackArgumentsSpaceRegion *
1270
  getStackArgumentsRegion(const StackFrameContext *STC);
1271
1272
  /// getGlobalsRegion - Retrieve the memory region associated with
1273
  ///  global variables.
1274
  const GlobalsSpaceRegion *getGlobalsRegion(
1275
      MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1276
      const CodeTextRegion *R = nullptr);
1277
1278
  /// getHeapRegion - Retrieve the memory region associated with the
1279
  ///  generic "heap".
1280
  const HeapSpaceRegion *getHeapRegion();
1281
1282
  /// getUnknownRegion - Retrieve the memory region associated with unknown
1283
  /// memory space.
1284
  const UnknownSpaceRegion *getUnknownRegion();
1285
1286
  const CodeSpaceRegion *getCodeRegion();
1287
1288
  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1289
  const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1290
                                      const LocationContext *LC);
1291
1292
  /// getCompoundLiteralRegion - Retrieve the region associated with a
1293
  ///  given CompoundLiteral.
1294
  const CompoundLiteralRegion*
1295
  getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1296
                           const LocationContext *LC);
1297
1298
  /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1299
  ///  parameter 'this'.
1300
  const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1301
                                        const LocationContext *LC);
1302
1303
  /// Retrieve or create a "symbolic" memory region.
1304
  const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
1305
1306
  /// Return a unique symbolic region belonging to heap memory space.
1307
  const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1308
1309
  const StringRegion *getStringRegion(const StringLiteral *Str);
1310
1311
  const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1312
1313
  /// getVarRegion - Retrieve or create the memory region associated with
1314
  ///  a specified VarDecl and LocationContext.
1315
  const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
1316
1317
  /// getVarRegion - Retrieve or create the memory region associated with
1318
  ///  a specified VarDecl and super region.
1319
  const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR);
1320
1321
  /// getElementRegion - Retrieve the memory region associated with the
1322
  ///  associated element type, index, and super region.
1323
  const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1324
                                        const SubRegion *superRegion,
1325
                                        ASTContext &Ctx);
1326
1327
  const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1328
252
                                                 const SubRegion *superRegion) {
1329
252
    return getElementRegion(ER->getElementType(), ER->getIndex(),
1330
252
                            superRegion, ER->getContext());
1331
252
  }
1332
1333
  /// getFieldRegion - Retrieve or create the memory region associated with
1334
  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1335
  ///  memory region (which typically represents the memory representing
1336
  ///  a structure or class).
1337
  const FieldRegion *getFieldRegion(const FieldDecl *fd,
1338
                                    const SubRegion* superRegion);
1339
1340
  const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1341
450
                                             const SubRegion *superRegion) {
1342
450
    return getFieldRegion(FR->getDecl(), superRegion);
1343
450
  }
1344
1345
  /// getObjCIvarRegion - Retrieve or create the memory region associated with
1346
  ///   a specified Objective-c instance variable.  'superRegion' corresponds
1347
  ///   to the containing region (which typically represents the Objective-C
1348
  ///   object).
1349
  const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1350
                                          const SubRegion* superRegion);
1351
1352
  const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1353
                                                    LocationContext const *LC);
1354
1355
  /// Create a CXXBaseObjectRegion with the given base class for region
1356
  /// \p Super.
1357
  ///
1358
  /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1359
  const CXXBaseObjectRegion *
1360
  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1361
                         bool IsVirtual);
1362
1363
  /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1364
  /// super region.
1365
  const CXXBaseObjectRegion *
1366
  getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1367
40
                                  const SubRegion *superRegion) {
1368
40
    return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1369
40
                                  baseReg->isVirtual());
1370
40
  }
1371
1372
  /// Create a CXXDerivedObjectRegion with the given derived class for region
1373
  /// \p Super. This should not be used for casting an existing
1374
  /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
1375
  /// should be removed.
1376
  const CXXDerivedObjectRegion *
1377
  getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1378
                            const SubRegion *Super);
1379
1380
  const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1381
  const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1382
                                            CanQualType locTy,
1383
                                            AnalysisDeclContext *AC);
1384
1385
  /// getBlockDataRegion - Get the memory region associated with an instance
1386
  ///  of a block.  Unlike many other MemRegions, the LocationContext*
1387
  ///  argument is allowed to be NULL for cases where we have no known
1388
  ///  context.
1389
  const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1390
                                            const LocationContext *lc,
1391
                                            unsigned blockCount);
1392
1393
  /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
1394
  /// by static references. This differs from getCXXTempObjectRegion in the
1395
  /// super-region used.
1396
  const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
1397
1398
private:
1399
  template <typename RegionTy, typename SuperTy,
1400
            typename Arg1Ty>
1401
  RegionTy* getSubRegion(const Arg1Ty arg1,
1402
                         const SuperTy* superRegion);
1403
1404
  template <typename RegionTy, typename SuperTy,
1405
            typename Arg1Ty, typename Arg2Ty>
1406
  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1407
                         const SuperTy* superRegion);
1408
1409
  template <typename RegionTy, typename SuperTy,
1410
            typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1411
  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1412
                         const Arg3Ty arg3,
1413
                         const SuperTy* superRegion);
1414
1415
  template <typename REG>
1416
  const REG* LazyAllocate(REG*& region);
1417
1418
  template <typename REG, typename ARG>
1419
  const REG* LazyAllocate(REG*& region, ARG a);
1420
};
1421
1422
//===----------------------------------------------------------------------===//
1423
// Out-of-line member definitions.
1424
//===----------------------------------------------------------------------===//
1425
1426
777k
inline ASTContext &MemRegion::getContext() const {
1427
777k
  return getMemRegionManager().getContext();
1428
777k
}
1429
1430
//===----------------------------------------------------------------------===//
1431
// Means for storing region/symbol handling traits.
1432
//===----------------------------------------------------------------------===//
1433
1434
/// Information about invalidation for a particular region/symbol.
1435
class RegionAndSymbolInvalidationTraits {
1436
  using StorageTypeForKinds = unsigned char;
1437
1438
  llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1439
  llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1440
1441
  using const_region_iterator =
1442
      llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1443
  using const_symbol_iterator =
1444
      llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1445
1446
public:
1447
  /// Describes different invalidation traits.
1448
  enum InvalidationKinds {
1449
    /// Tells that a region's contents is not changed.
1450
    TK_PreserveContents = 0x1,
1451
1452
    /// Suppress pointer-escaping of a region.
1453
    TK_SuppressEscape = 0x2,
1454
1455
    // Do not invalidate super region.
1456
    TK_DoNotInvalidateSuperRegion = 0x4,
1457
1458
    /// When applied to a MemSpaceRegion, indicates the entire memory space
1459
    /// should be invalidated.
1460
    TK_EntireMemSpace = 0x8
1461
1462
    // Do not forget to extend StorageTypeForKinds if number of traits exceed
1463
    // the number of bits StorageTypeForKinds can store.
1464
  };
1465
1466
  void setTrait(SymbolRef Sym, InvalidationKinds IK);
1467
  void setTrait(const MemRegion *MR, InvalidationKinds IK);
1468
  bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1469
  bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1470
};
1471
1472
//===----------------------------------------------------------------------===//
1473
// Pretty-printing regions.
1474
//===----------------------------------------------------------------------===//
1475
225
inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1476
225
  R->dumpToStream(os);
1477
225
  return os;
1478
225
}
1479
1480
} // namespace ento
1481
1482
} // namespace clang
1483
1484
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H