Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
Line
Count
Source (jump to first uncovered line)
1
//===- SVals.h - Abstract Values 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 SVal, Loc, and NonLoc, classes that represent
10
//  abstract r-values for use with path-sensitive value tracking.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
15
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
16
17
#include "clang/AST/Expr.h"
18
#include "clang/AST/Type.h"
19
#include "clang/Basic/LLVM.h"
20
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
21
#include "llvm/ADT/FoldingSet.h"
22
#include "llvm/ADT/ImmutableList.h"
23
#include "llvm/ADT/None.h"
24
#include "llvm/ADT/Optional.h"
25
#include "llvm/ADT/PointerUnion.h"
26
#include "llvm/Support/Casting.h"
27
#include <cassert>
28
#include <cstdint>
29
#include <utility>
30
31
//==------------------------------------------------------------------------==//
32
//  Base SVal types.
33
//==------------------------------------------------------------------------==//
34
35
namespace clang {
36
37
class CXXBaseSpecifier;
38
class DeclaratorDecl;
39
class FunctionDecl;
40
class LabelDecl;
41
42
namespace ento {
43
44
class BasicValueFactory;
45
class CompoundValData;
46
class LazyCompoundValData;
47
class MemRegion;
48
class PointerToMemberData;
49
class SValBuilder;
50
class TypedValueRegion;
51
52
namespace nonloc {
53
54
/// Sub-kinds for NonLoc values.
55
enum Kind {
56
#define NONLOC_SVAL(Id, Parent) Id ## Kind,
57
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
58
};
59
60
} // namespace nonloc
61
62
namespace loc {
63
64
/// Sub-kinds for Loc values.
65
enum Kind {
66
#define LOC_SVAL(Id, Parent) Id ## Kind,
67
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
68
};
69
70
} // namespace loc
71
72
/// SVal - This represents a symbolic expression, which can be either
73
///  an L-value or an R-value.
74
///
75
class SVal {
76
public:
77
  enum BaseKind {
78
    // The enumerators must be representable using 2 bits.
79
#define BASIC_SVAL(Id, Parent) Id ## Kind,
80
#define ABSTRACT_SVAL_WITH_KIND(Id, Parent) Id ## Kind,
81
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
82
  };
83
  enum { BaseBits = 2, BaseMask = 0x3 };
84
85
protected:
86
  const void *Data = nullptr;
87
88
  /// The lowest 2 bits are a BaseKind (0 -- 3).
89
  ///  The higher bits are an unsigned "kind" value.
90
  unsigned Kind = 0;
91
92
  explicit SVal(const void *d, bool isLoc, unsigned ValKind)
93
2.14M
      : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
94
95
349k
  explicit SVal(BaseKind k, const void *D = nullptr) : Data(D), Kind(k) {}
96
97
public:
98
128k
  explicit SVal() = default;
99
100
  /// Convert to the specified SVal type, asserting that this SVal is of
101
  /// the desired type.
102
  template<typename T>
103
5.01M
  T castAs() const {
104
5.01M
    assert(T::isKind(*this));
105
5.01M
    return *static_cast<const T *>(this);
106
5.01M
  }
clang::ento::Loc clang::ento::SVal::castAs<clang::ento::Loc>() const
Line
Count
Source
103
468k
  T castAs() const {
104
468k
    assert(T::isKind(*this));
105
468k
    return *static_cast<const T *>(this);
106
468k
  }
clang::ento::DefinedSVal clang::ento::SVal::castAs<clang::ento::DefinedSVal>() const
Line
Count
Source
103
992k
  T castAs() const {
104
992k
    assert(T::isKind(*this));
105
992k
    return *static_cast<const T *>(this);
106
992k
  }
clang::ento::NonLoc clang::ento::SVal::castAs<clang::ento::NonLoc>() const
Line
Count
Source
103
1.12M
  T castAs() const {
104
1.12M
    assert(T::isKind(*this));
105
1.12M
    return *static_cast<const T *>(this);
106
1.12M
  }
clang::ento::DefinedOrUnknownSVal clang::ento::SVal::castAs<clang::ento::DefinedOrUnknownSVal>() const
Line
Count
Source
103
339k
  T castAs() const {
104
339k
    assert(T::isKind(*this));
105
339k
    return *static_cast<const T *>(this);
106
339k
  }
clang::ento::nonloc::ConcreteInt clang::ento::SVal::castAs<clang::ento::nonloc::ConcreteInt>() const
Line
Count
Source
103
668k
  T castAs() const {
104
668k
    assert(T::isKind(*this));
105
668k
    return *static_cast<const T *>(this);
106
668k
  }
clang::ento::loc::MemRegionVal clang::ento::SVal::castAs<clang::ento::loc::MemRegionVal>() const
Line
Count
Source
103
1.13M
  T castAs() const {
104
1.13M
    assert(T::isKind(*this));
105
1.13M
    return *static_cast<const T *>(this);
106
1.13M
  }
clang::ento::UndefinedVal clang::ento::SVal::castAs<clang::ento::UndefinedVal>() const
Line
Count
Source
103
1
  T castAs() const {
104
1
    assert(T::isKind(*this));
105
1
    return *static_cast<const T *>(this);
106
1
  }
clang::ento::UnknownVal clang::ento::SVal::castAs<clang::ento::UnknownVal>() const
Line
Count
Source
103
14
  T castAs() const {
104
14
    assert(T::isKind(*this));
105
14
    return *static_cast<const T *>(this);
106
14
  }
clang::ento::loc::ConcreteInt clang::ento::SVal::castAs<clang::ento::loc::ConcreteInt>() const
Line
Count
Source
103
118
  T castAs() const {
104
118
    assert(T::isKind(*this));
105
118
    return *static_cast<const T *>(this);
106
118
  }
Unexecuted instantiation: clang::ento::loc::GotoLabel clang::ento::SVal::castAs<clang::ento::loc::GotoLabel>() const
clang::ento::nonloc::CompoundVal clang::ento::SVal::castAs<clang::ento::nonloc::CompoundVal>() const
Line
Count
Source
103
1.98k
  T castAs() const {
104
1.98k
    assert(T::isKind(*this));
105
1.98k
    return *static_cast<const T *>(this);
106
1.98k
  }
clang::ento::nonloc::LazyCompoundVal clang::ento::SVal::castAs<clang::ento::nonloc::LazyCompoundVal>() const
Line
Count
Source
103
2
  T castAs() const {
104
2
    assert(T::isKind(*this));
105
2
    return *static_cast<const T *>(this);
106
2
  }
clang::ento::nonloc::LocAsInteger clang::ento::SVal::castAs<clang::ento::nonloc::LocAsInteger>() const
Line
Count
Source
103
79
  T castAs() const {
104
79
    assert(T::isKind(*this));
105
79
    return *static_cast<const T *>(this);
106
79
  }
clang::ento::nonloc::SymbolVal clang::ento::SVal::castAs<clang::ento::nonloc::SymbolVal>() const
Line
Count
Source
103
282k
  T castAs() const {
104
282k
    assert(T::isKind(*this));
105
282k
    return *static_cast<const T *>(this);
106
282k
  }
clang::ento::nonloc::PointerToMember clang::ento::SVal::castAs<clang::ento::nonloc::PointerToMember>() const
Line
Count
Source
103
20
  T castAs() const {
104
20
    assert(T::isKind(*this));
105
20
    return *static_cast<const T *>(this);
106
20
  }
Unexecuted instantiation: clang::ento::KnownSVal clang::ento::SVal::castAs<clang::ento::KnownSVal>() const
107
108
  /// Convert to the specified SVal type, returning None if this SVal is
109
  /// not of the desired type.
110
  template<typename T>
111
25.6M
  Optional<T> getAs() const {
112
25.6M
    if (!T::isKind(*this))
113
17.4M
      return None;
114
8.20M
    return *static_cast<const T *>(this);
115
8.20M
  }
llvm::Optional<clang::ento::Loc> clang::ento::SVal::getAs<clang::ento::Loc>() const
Line
Count
Source
111
1.89M
  Optional<T> getAs() const {
112
1.89M
    if (!T::isKind(*this))
113
383k
      return None;
114
1.50M
    return *static_cast<const T *>(this);
115
1.50M
  }
llvm::Optional<clang::ento::NonLoc> clang::ento::SVal::getAs<clang::ento::NonLoc>() const
Line
Count
Source
111
82.9k
  Optional<T> getAs() const {
112
82.9k
    if (!T::isKind(*this))
113
51.3k
      return None;
114
31.6k
    return *static_cast<const T *>(this);
115
31.6k
  }
llvm::Optional<clang::ento::UndefinedVal> clang::ento::SVal::getAs<clang::ento::UndefinedVal>() const
Line
Count
Source
111
1.31k
  Optional<T> getAs() const {
112
1.31k
    if (!T::isKind(*this))
113
315
      return None;
114
995
    return *static_cast<const T *>(this);
115
995
  }
llvm::Optional<clang::ento::nonloc::ConcreteInt> clang::ento::SVal::getAs<clang::ento::nonloc::ConcreteInt>() const
Line
Count
Source
111
1.17M
  Optional<T> getAs() const {
112
1.17M
    if (!T::isKind(*this))
113
897k
      return None;
114
276k
    return *static_cast<const T *>(this);
115
276k
  }
llvm::Optional<clang::ento::nonloc::SymbolVal> clang::ento::SVal::getAs<clang::ento::nonloc::SymbolVal>() const
Line
Count
Source
111
5.10M
  Optional<T> getAs() const {
112
5.10M
    if (!T::isKind(*this))
113
3.47M
      return None;
114
1.62M
    return *static_cast<const T *>(this);
115
1.62M
  }
llvm::Optional<clang::ento::loc::MemRegionVal> clang::ento::SVal::getAs<clang::ento::loc::MemRegionVal>() const
Line
Count
Source
111
8.02M
  Optional<T> getAs() const {
112
8.02M
    if (!T::isKind(*this))
113
3.39M
      return None;
114
4.62M
    return *static_cast<const T *>(this);
115
4.62M
  }
llvm::Optional<clang::ento::DefinedSVal> clang::ento::SVal::getAs<clang::ento::DefinedSVal>() const
Line
Count
Source
111
37.3k
  Optional<T> getAs() const {
112
37.3k
    if (!T::isKind(*this))
113
394
      return None;
114
36.9k
    return *static_cast<const T *>(this);
115
36.9k
  }
llvm::Optional<clang::ento::loc::ConcreteInt> clang::ento::SVal::getAs<clang::ento::loc::ConcreteInt>() const
Line
Count
Source
111
1.64M
  Optional<T> getAs() const {
112
1.64M
    if (!T::isKind(*this))
113
1.63M
      return None;
114
14.4k
    return *static_cast<const T *>(this);
115
14.4k
  }
llvm::Optional<clang::ento::DefinedOrUnknownSVal> clang::ento::SVal::getAs<clang::ento::DefinedOrUnknownSVal>() const
Line
Count
Source
111
3.57k
  Optional<T> getAs() const {
112
3.57k
    if (!T::isKind(*this))
113
1
      return None;
114
3.57k
    return *static_cast<const T *>(this);
115
3.57k
  }
llvm::Optional<clang::ento::loc::GotoLabel> clang::ento::SVal::getAs<clang::ento::loc::GotoLabel>() const
Line
Count
Source
111
9.79k
  Optional<T> getAs() const {
112
9.79k
    if (!T::isKind(*this))
113
9.78k
      return None;
114
14
    return *static_cast<const T *>(this);
115
14
  }
llvm::Optional<clang::ento::nonloc::LazyCompoundVal> clang::ento::SVal::getAs<clang::ento::nonloc::LazyCompoundVal>() const
Line
Count
Source
111
2.45M
  Optional<T> getAs() const {
112
2.45M
    if (!T::isKind(*this))
113
2.37M
      return None;
114
84.5k
    return *static_cast<const T *>(this);
115
84.5k
  }
llvm::Optional<clang::ento::nonloc::CompoundVal> clang::ento::SVal::getAs<clang::ento::nonloc::CompoundVal>() const
Line
Count
Source
111
366k
  Optional<T> getAs() const {
112
366k
    if (!T::isKind(*this))
113
364k
      return None;
114
2.21k
    return *static_cast<const T *>(this);
115
2.21k
  }
llvm::Optional<clang::ento::nonloc::LocAsInteger> clang::ento::SVal::getAs<clang::ento::nonloc::LocAsInteger>() const
Line
Count
Source
111
4.65M
  Optional<T> getAs() const {
112
4.65M
    if (!T::isKind(*this))
113
4.65M
      return None;
114
923
    return *static_cast<const T *>(this);
115
923
  }
llvm::Optional<clang::ento::KnownSVal> clang::ento::SVal::getAs<clang::ento::KnownSVal>() const
Line
Count
Source
111
1.58k
  Optional<T> getAs() const {
112
1.58k
    if (!T::isKind(*this))
113
1
      return None;
114
1.58k
    return *static_cast<const T *>(this);
115
1.58k
  }
llvm::Optional<clang::ento::nonloc::PointerToMember> clang::ento::SVal::getAs<clang::ento::nonloc::PointerToMember>() const
Line
Count
Source
111
166k
  Optional<T> getAs() const {
112
166k
    if (!T::isKind(*this))
113
166k
      return None;
114
247
    return *static_cast<const T *>(this);
115
247
  }
116
117
20.8M
  unsigned getRawKind() const { return Kind; }
118
25.7M
  BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
119
16.4M
  unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
120
121
  // This method is required for using SVal in a FoldingSetNode.  It
122
  // extracts a unique signature for this SVal object.
123
4.50M
  void Profile(llvm::FoldingSetNodeID &ID) const {
124
4.50M
    ID.AddInteger((unsigned) getRawKind());
125
4.50M
    ID.AddPointer(Data);
126
4.50M
  }
127
128
5.77M
  bool operator==(const SVal &R) const {
129
5.77M
    return getRawKind() == R.getRawKind() && 
Data == R.Data5.67M
;
130
5.77M
  }
131
132
143k
  bool operator!=(const SVal &R) const {
133
143k
    return !(*this == R);
134
143k
  }
135
136
1.62M
  bool isUnknown() const {
137
1.62M
    return getRawKind() == UnknownValKind;
138
1.62M
  }
139
140
958k
  bool isUndef() const {
141
958k
    return getRawKind() == UndefinedValKind;
142
958k
  }
143
144
1.94M
  bool isUnknownOrUndef() const {
145
1.94M
    return getRawKind() <= UnknownValKind;
146
1.94M
  }
147
148
296k
  bool isValid() const {
149
296k
    return getRawKind() > UnknownValKind;
150
296k
  }
151
152
  bool isConstant() const;
153
154
  bool isConstant(int I) const;
155
156
  bool isZeroConstant() const;
157
158
  /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
159
  bool hasConjuredSymbol() const;
160
161
  /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
162
  /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
163
  /// Otherwise return 0.
164
  const FunctionDecl *getAsFunctionDecl() const;
165
166
  /// If this SVal is a location and wraps a symbol, return that
167
  ///  SymbolRef. Otherwise return 0.
168
  ///
169
  /// Casts are ignored during lookup.
170
  /// \param IncludeBaseRegions The boolean that controls whether the search
171
  /// should continue to the base regions if the region is not symbolic.
172
  SymbolRef getAsLocSymbol(bool IncludeBaseRegions = false) const;
173
174
  /// Get the symbol in the SVal or its base region.
175
  SymbolRef getLocSymbolInBase() const;
176
177
  /// If this SVal wraps a symbol return that SymbolRef.
178
  /// Otherwise, return 0.
179
  ///
180
  /// Casts are ignored during lookup.
181
  /// \param IncludeBaseRegions The boolean that controls whether the search
182
  /// should continue to the base regions if the region is not symbolic.
183
  SymbolRef getAsSymbol(bool IncludeBaseRegions = false) const;
184
185
  /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
186
  ///  return that expression.  Otherwise return NULL.
187
  const SymExpr *getAsSymbolicExpression() const;
188
189
  const SymExpr *getAsSymExpr() const;
190
191
  const MemRegion *getAsRegion() const;
192
193
  /// printJson - Pretty-prints in JSON format.
194
  void printJson(raw_ostream &Out, bool AddQuotes) const;
195
196
  void dumpToStream(raw_ostream &OS) const;
197
  void dump() const;
198
199
1.67M
  SymExpr::symbol_iterator symbol_begin() const {
200
1.67M
    const SymExpr *SE = getAsSymbol(/*IncludeBaseRegions=*/true);
201
1.67M
    if (SE)
202
838k
      return SE->symbol_begin();
203
837k
    else
204
837k
      return SymExpr::symbol_iterator();
205
1.67M
  }
206
207
1.67M
  SymExpr::symbol_iterator symbol_end() const {
208
1.67M
    return SymExpr::symbol_end();
209
1.67M
  }
210
};
211
212
0
inline raw_ostream &operator<<(raw_ostream &os, clang::ento::SVal V) {
213
0
  V.dumpToStream(os);
214
0
  return os;
215
0
}
216
217
class UndefinedVal : public SVal {
218
public:
219
60.1k
  UndefinedVal() : SVal(UndefinedValKind) {}
220
221
private:
222
  friend class SVal;
223
224
1.31k
  static bool isKind(const SVal& V) {
225
1.31k
    return V.getBaseKind() == UndefinedValKind;
226
1.31k
  }
227
};
228
229
class DefinedOrUnknownSVal : public SVal {
230
public:
231
  // We want calling these methods to be a compiler error since they are
232
  // tautologically false.
233
  bool isUndef() const = delete;
234
  bool isValid() const = delete;
235
236
protected:
237
  DefinedOrUnknownSVal() = default;
238
  explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
239
2.14M
      : SVal(d, isLoc, ValKind) {}
240
289k
  explicit DefinedOrUnknownSVal(BaseKind k, void *D = nullptr) : SVal(k, D) {}
241
242
private:
243
  friend class SVal;
244
245
3.57k
  static bool isKind(const SVal& V) {
246
3.57k
    return !V.isUndef();
247
3.57k
  }
248
};
249
250
class UnknownVal : public DefinedOrUnknownSVal {
251
public:
252
289k
  explicit UnknownVal() : DefinedOrUnknownSVal(UnknownValKind) {}
253
254
private:
255
  friend class SVal;
256
257
0
  static bool isKind(const SVal &V) {
258
0
    return V.getBaseKind() == UnknownValKind;
259
0
  }
260
};
261
262
class DefinedSVal : public DefinedOrUnknownSVal {
263
public:
264
  // We want calling these methods to be a compiler error since they are
265
  // tautologically true/false.
266
  bool isUnknown() const = delete;
267
  bool isUnknownOrUndef() const = delete;
268
  bool isValid() const = delete;
269
270
protected:
271
  DefinedSVal() = default;
272
  explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind)
273
2.14M
      : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
274
275
private:
276
  friend class SVal;
277
278
37.3k
  static bool isKind(const SVal& V) {
279
37.3k
    return !V.isUnknownOrUndef();
280
37.3k
  }
281
};
282
283
/// Represents an SVal that is guaranteed to not be UnknownVal.
284
class KnownSVal : public SVal {
285
  friend class SVal;
286
287
  KnownSVal() = default;
288
289
1.58k
  static bool isKind(const SVal &V) {
290
1.58k
    return !V.isUnknown();
291
1.58k
  }
292
293
public:
294
0
  KnownSVal(const DefinedSVal &V) : SVal(V) {}
295
6
  KnownSVal(const UndefinedVal &V) : SVal(V) {}
296
};
297
298
class NonLoc : public DefinedSVal {
299
protected:
300
  NonLoc() = default;
301
  explicit NonLoc(unsigned SubKind, const void *d)
302
1.33M
      : DefinedSVal(d, false, SubKind) {}
303
304
public:
305
  void dumpToStream(raw_ostream &Out) const;
306
307
0
  static bool isCompoundType(QualType T) {
308
0
    return T->isArrayType() || T->isRecordType() ||
309
0
           T->isAnyComplexType() || T->isVectorType();
310
0
  }
311
312
private:
313
  friend class SVal;
314
315
82.9k
  static bool isKind(const SVal& V) {
316
82.9k
    return V.getBaseKind() == NonLocKind;
317
82.9k
  }
318
};
319
320
class Loc : public DefinedSVal {
321
protected:
322
  Loc() = default;
323
  explicit Loc(unsigned SubKind, const void *D)
324
810k
      : DefinedSVal(const_cast<void *>(D), true, SubKind) {}
325
326
public:
327
  void dumpToStream(raw_ostream &Out) const;
328
329
2.30M
  static bool isLocType(QualType T) {
330
2.30M
    return T->isAnyPointerType() || 
T->isBlockPointerType()1.39M
||
331
2.30M
           
T->isReferenceType()1.39M
||
T->isNullPtrType()1.37M
;
332
2.30M
  }
333
334
private:
335
  friend class SVal;
336
337
1.89M
  static bool isKind(const SVal& V) {
338
1.89M
    return V.getBaseKind() == LocKind;
339
1.89M
  }
340
};
341
342
//==------------------------------------------------------------------------==//
343
//  Subclasses of NonLoc.
344
//==------------------------------------------------------------------------==//
345
346
namespace nonloc {
347
348
/// Represents symbolic expression that isn't a location.
349
class SymbolVal : public NonLoc {
350
public:
351
  SymbolVal() = delete;
352
560k
  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {
353
560k
    assert(sym);
354
560k
    assert(!Loc::isLocType(sym->getType()));
355
560k
  }
356
357
2.06M
  SymbolRef getSymbol() const {
358
2.06M
    return (const SymExpr *) Data;
359
2.06M
  }
360
361
170k
  bool isExpression() const {
362
170k
    return !isa<SymbolData>(getSymbol());
363
170k
  }
364
365
private:
366
  friend class SVal;
367
368
5.10M
  static bool isKind(const SVal& V) {
369
5.10M
    return V.getBaseKind() == NonLocKind &&
370
5.10M
           
V.getSubKind() == SymbolValKind3.50M
;
371
5.10M
  }
372
373
0
  static bool isKind(const NonLoc& V) {
374
0
    return V.getSubKind() == SymbolValKind;
375
0
  }
376
};
377
378
/// Value representing integer constant.
379
class ConcreteInt : public NonLoc {
380
public:
381
729k
  explicit ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
382
383
784k
  const llvm::APSInt& getValue() const {
384
784k
    return *static_cast<const llvm::APSInt *>(Data);
385
784k
  }
386
387
  // Transfer functions for binary/unary operations on ConcreteInts.
388
  SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op,
389
                 const ConcreteInt& R) const;
390
391
  ConcreteInt evalComplement(SValBuilder &svalBuilder) const;
392
393
  ConcreteInt evalMinus(SValBuilder &svalBuilder) const;
394
395
private:
396
  friend class SVal;
397
398
  ConcreteInt() = default;
399
400
1.17M
  static bool isKind(const SVal& V) {
401
1.17M
    return V.getBaseKind() == NonLocKind &&
402
1.17M
           
V.getSubKind() == ConcreteIntKind551k
;
403
1.17M
  }
404
405
0
  static bool isKind(const NonLoc& V) {
406
0
    return V.getSubKind() == ConcreteIntKind;
407
0
  }
408
};
409
410
class LocAsInteger : public NonLoc {
411
  friend class ento::SValBuilder;
412
413
  explicit LocAsInteger(const std::pair<SVal, uintptr_t> &data)
414
128
      : NonLoc(LocAsIntegerKind, &data) {
415
128
    // We do not need to represent loc::ConcreteInt as LocAsInteger,
416
128
    // as it'd collapse into a nonloc::ConcreteInt instead.
417
128
    assert(data.first.getBaseKind() == LocKind &&
418
128
           (data.first.getSubKind() == loc::MemRegionValKind ||
419
128
            data.first.getSubKind() == loc::GotoLabelKind));
420
128
  }
421
422
public:
423
894
  Loc getLoc() const {
424
894
    const std::pair<SVal, uintptr_t> *D =
425
894
      static_cast<const std::pair<SVal, uintptr_t> *>(Data);
426
894
    return D->first.castAs<Loc>();
427
894
  }
428
429
0
  Loc getPersistentLoc() const {
430
0
    const std::pair<SVal, uintptr_t> *D =
431
0
      static_cast<const std::pair<SVal, uintptr_t> *>(Data);
432
0
    const SVal& V = D->first;
433
0
    return V.castAs<Loc>();
434
0
  }
435
436
102
  unsigned getNumBits() const {
437
102
    const std::pair<SVal, uintptr_t> *D =
438
102
      static_cast<const std::pair<SVal, uintptr_t> *>(Data);
439
102
    return D->second;
440
102
  }
441
442
private:
443
  friend class SVal;
444
445
  LocAsInteger() = default;
446
447
4.65M
  static bool isKind(const SVal& V) {
448
4.65M
    return V.getBaseKind() == NonLocKind &&
449
4.65M
           
V.getSubKind() == LocAsIntegerKind2.83M
;
450
4.65M
  }
451
452
0
  static bool isKind(const NonLoc& V) {
453
0
    return V.getSubKind() == LocAsIntegerKind;
454
0
  }
455
};
456
457
class CompoundVal : public NonLoc {
458
  friend class ento::SValBuilder;
459
460
1.09k
  explicit CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
461
462
public:
463
6.39k
  const CompoundValData* getValue() const {
464
6.39k
    return static_cast<const CompoundValData *>(Data);
465
6.39k
  }
466
467
  using iterator = llvm::ImmutableList<SVal>::iterator;
468
469
  iterator begin() const;
470
  iterator end() const;
471
472
private:
473
  friend class SVal;
474
475
  CompoundVal() = default;
476
477
366k
  static bool isKind(const SVal& V) {
478
366k
    return V.getBaseKind() == NonLocKind && 
V.getSubKind() == CompoundValKind260k
;
479
366k
  }
480
481
0
  static bool isKind(const NonLoc& V) {
482
0
    return V.getSubKind() == CompoundValKind;
483
0
  }
484
};
485
486
class LazyCompoundVal : public NonLoc {
487
  friend class ento::SValBuilder;
488
489
  explicit LazyCompoundVal(const LazyCompoundValData *D)
490
39.6k
      : NonLoc(LazyCompoundValKind, D) {}
491
492
public:
493
57.3k
  const LazyCompoundValData *getCVData() const {
494
57.3k
    return static_cast<const LazyCompoundValData *>(Data);
495
57.3k
  }
496
497
  const void *getStore() const;
498
  const TypedValueRegion *getRegion() const;
499
500
private:
501
  friend class SVal;
502
503
  LazyCompoundVal() = default;
504
505
2.45M
  static bool isKind(const SVal& V) {
506
2.45M
    return V.getBaseKind() == NonLocKind &&
507
2.45M
           
V.getSubKind() == LazyCompoundValKind1.77M
;
508
2.45M
  }
509
510
0
  static bool isKind(const NonLoc& V) {
511
0
    return V.getSubKind() == LazyCompoundValKind;
512
0
  }
513
};
514
515
/// Value representing pointer-to-member.
516
///
517
/// This value is qualified as NonLoc because neither loading nor storing
518
/// operations are applied to it. Instead, the analyzer uses the L-value coming
519
/// from pointer-to-member applied to an object.
520
/// This SVal is represented by a DeclaratorDecl which can be a member function
521
/// pointer or a member data pointer and a list of CXXBaseSpecifiers. This list
522
/// is required to accumulate the pointer-to-member cast history to figure out
523
/// the correct subobject field.
524
class PointerToMember : public NonLoc {
525
  friend class ento::SValBuilder;
526
527
public:
528
  using PTMDataType =
529
      llvm::PointerUnion<const DeclaratorDecl *, const PointerToMemberData *>;
530
531
266
  const PTMDataType getPTMData() const {
532
266
    return PTMDataType::getFromOpaqueValue(const_cast<void *>(Data));
533
266
  }
534
535
  bool isNullMemberPointer() const;
536
537
  const DeclaratorDecl *getDecl() const;
538
539
  template<typename AdjustedDecl>
540
21
  const AdjustedDecl *getDeclAs() const {
541
21
    return dyn_cast_or_null<AdjustedDecl>(getDecl());
542
21
  }
543
544
  using iterator = llvm::ImmutableList<const CXXBaseSpecifier *>::iterator;
545
546
  iterator begin() const;
547
  iterator end() const;
548
549
private:
550
  friend class SVal;
551
552
  PointerToMember() = default;
553
  explicit PointerToMember(const PTMDataType D)
554
65
      : NonLoc(PointerToMemberKind, D.getOpaqueValue()) {}
555
556
166k
  static bool isKind(const SVal& V) {
557
166k
    return V.getBaseKind() == NonLocKind &&
558
166k
           
V.getSubKind() == PointerToMemberKind147k
;
559
166k
  }
560
561
0
  static bool isKind(const NonLoc& V) {
562
0
    return V.getSubKind() == PointerToMemberKind;
563
0
  }
564
};
565
566
} // namespace nonloc
567
568
//==------------------------------------------------------------------------==//
569
//  Subclasses of Loc.
570
//==------------------------------------------------------------------------==//
571
572
namespace loc {
573
574
class GotoLabel : public Loc {
575
public:
576
60
  explicit GotoLabel(const LabelDecl *Label) : Loc(GotoLabelKind, Label) {
577
60
    assert(Label);
578
60
  }
579
580
12
  const LabelDecl *getLabel() const {
581
12
    return static_cast<const LabelDecl *>(Data);
582
12
  }
583
584
private:
585
  friend class SVal;
586
587
  GotoLabel() = default;
588
589
9.79k
  static bool isKind(const SVal& V) {
590
9.79k
    return V.getBaseKind() == LocKind && 
V.getSubKind() == GotoLabelKind9.79k
;
591
9.79k
  }
592
593
0
  static bool isKind(const Loc& V) {
594
0
    return V.getSubKind() == GotoLabelKind;
595
0
  }
596
};
597
598
class MemRegionVal : public Loc {
599
public:
600
802k
  explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionValKind, r) {
601
802k
    assert(r);
602
802k
  }
603
604
  /// Get the underlining region.
605
5.19M
  const MemRegion *getRegion() const {
606
5.19M
    return static_cast<const MemRegion *>(Data);
607
5.19M
  }
608
609
  /// Get the underlining region and strip casts.
610
  const MemRegion* stripCasts(bool StripBaseCasts = true) const;
611
612
  template <typename REGION>
613
10.5k
  const REGION* getRegionAs() const {
614
10.5k
    return dyn_cast<REGION>(getRegion());
615
10.5k
  }
clang::ento::FieldRegion const* clang::ento::loc::MemRegionVal::getRegionAs<clang::ento::FieldRegion>() const
Line
Count
Source
613
662
  const REGION* getRegionAs() const {
614
662
    return dyn_cast<REGION>(getRegion());
615
662
  }
clang::ento::TypedValueRegion const* clang::ento::loc::MemRegionVal::getRegionAs<clang::ento::TypedValueRegion>() const
Line
Count
Source
613
80
  const REGION* getRegionAs() const {
614
80
    return dyn_cast<REGION>(getRegion());
615
80
  }
clang::ento::SubRegion const* clang::ento::loc::MemRegionVal::getRegionAs<clang::ento::SubRegion>() const
Line
Count
Source
613
9.76k
  const REGION* getRegionAs() const {
614
9.76k
    return dyn_cast<REGION>(getRegion());
615
9.76k
  }
616
617
0
  bool operator==(const MemRegionVal &R) const {
618
0
    return getRegion() == R.getRegion();
619
0
  }
620
621
0
  bool operator!=(const MemRegionVal &R) const {
622
0
    return getRegion() != R.getRegion();
623
0
  }
624
625
private:
626
  friend class SVal;
627
628
  MemRegionVal() = default;
629
630
8.02M
  static bool isKind(const SVal& V) {
631
8.02M
    return V.getBaseKind() == LocKind &&
632
8.02M
           
V.getSubKind() == MemRegionValKind4.70M
;
633
8.02M
  }
634
635
0
  static bool isKind(const Loc& V) {
636
0
    return V.getSubKind() == MemRegionValKind;
637
0
  }
638
};
639
640
class ConcreteInt : public Loc {
641
public:
642
8.70k
  explicit ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
643
644
9.16k
  const llvm::APSInt &getValue() const {
645
9.16k
    return *static_cast<const llvm::APSInt *>(Data);
646
9.16k
  }
647
648
  // Transfer functions for binary/unary operations on ConcreteInts.
649
  SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
650
                 const ConcreteInt& R) const;
651
652
private:
653
  friend class SVal;
654
655
  ConcreteInt() = default;
656
657
1.64M
  static bool isKind(const SVal& V) {
658
1.64M
    return V.getBaseKind() == LocKind &&
659
1.64M
           
V.getSubKind() == ConcreteIntKind1.24M
;
660
1.64M
  }
661
662
0
  static bool isKind(const Loc& V) {
663
0
    return V.getSubKind() == ConcreteIntKind;
664
0
  }
665
};
666
667
} // namespace loc
668
669
} // namespace ento
670
671
} // namespace clang
672
673
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H