Clang Project

clang_source_code/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
1//==- BasicValueFactory.h - Basic values for Path Sens 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 BasicValueFactory, a class that manages the lifetime
10//  of APSInt objects and symbolic constraints used by ExprEngine
11//  and related classes.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
16#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
17
18#include "clang/AST/ASTContext.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/Type.h"
21#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
22#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
23#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
24#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
25#include "llvm/ADT/APSInt.h"
26#include "llvm/ADT/FoldingSet.h"
27#include "llvm/ADT/ImmutableList.h"
28#include "llvm/ADT/iterator_range.h"
29#include "llvm/Support/Allocator.h"
30#include <cassert>
31#include <cstdint>
32#include <utility>
33
34namespace clang {
35
36class CXXBaseSpecifier;
37class DeclaratorDecl;
38
39namespace ento {
40
41class CompoundValData : public llvm::FoldingSetNode {
42  QualType T;
43  llvm::ImmutableList<SVal> L;
44
45public:
46  CompoundValData(QualType t, llvm::ImmutableList<SVal> l) : T(t), L(l) {
47    assert(NonLoc::isCompoundType(t));
48  }
49
50  using iterator = llvm::ImmutableList<SVal>::iterator;
51
52  iterator begin() const { return L.begin(); }
53  iterator end() const { return L.end(); }
54
55  static void Profile(llvm::FoldingSetNodeIDIDQualType T,
56                      llvm::ImmutableList<SVal> L);
57
58  void Profile(llvm::FoldingSetNodeIDID) { Profile(ID, T, L); }
59};
60
61class LazyCompoundValData : public llvm::FoldingSetNode {
62  StoreRef store;
63  const TypedValueRegion *region;
64
65public:
66  LazyCompoundValData(const StoreRef &stconst TypedValueRegion *r)
67      : store(st), region(r) {
68    getValueType())", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h", 68, __PRETTY_FUNCTION__))" file_link="../../../../../../include/assert.h.html#88" macro="true">assert(NonLoc::isCompoundType(r->getValueType()));
69  }
70
71  const void *getStore() const { return store.getStore(); }
72  const TypedValueRegion *getRegion() const { return region; }
73
74  static void Profile(llvm::FoldingSetNodeIDID,
75                      const StoreRef &store,
76                      const TypedValueRegion *region);
77
78  void Profile(llvm::FoldingSetNodeIDID) { Profile(IDstoreregion); }
79};
80
81class PointerToMemberData : public llvm::FoldingSetNode {
82  const DeclaratorDecl *D;
83  llvm::ImmutableList<const CXXBaseSpecifier *> L;
84
85public:
86  PointerToMemberData(const DeclaratorDecl *D,
87                      llvm::ImmutableList<const CXXBaseSpecifier *> L)
88      : D(D), L(L) {}
89
90  using iterator = llvm::ImmutableList<const CXXBaseSpecifier *>::iterator;
91
92  iterator begin() const { return L.begin(); }
93  iterator end() const { return L.end(); }
94
95  static void Profile(llvm::FoldingSetNodeIDIDconst DeclaratorDecl *D,
96                      llvm::ImmutableList<const CXXBaseSpecifier *> L);
97
98  void Profile(llvm::FoldingSetNodeIDID) { Profile(ID, D, L); }
99  const DeclaratorDecl *getDeclaratorDecl() const {return D;}
100
101  llvm::ImmutableList<const CXXBaseSpecifier *> getCXXBaseList() const {
102    return L;
103  }
104};
105
106class BasicValueFactory {
107  using APSIntSetTy =
108      llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt>>;
109
110  ASTContext &Ctx;
111  llvm::BumpPtrAllocator& BPAlloc;
112
113  APSIntSetTy APSIntSet;
114  void *PersistentSVals = nullptr;
115  void *PersistentSValPairs = nullptr;
116
117  llvm::ImmutableList<SVal>::Factory SValListFactory;
118  llvm::ImmutableList<const CXXBaseSpecifier *>::Factory CXXBaseListFactory;
119  llvm::FoldingSet<CompoundValData>  CompoundValDataSet;
120  llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
121  llvm::FoldingSet<PointerToMemberData> PointerToMemberDataSet;
122
123  // This is private because external clients should use the factory
124  // method that takes a QualType.
125  const llvm::APSIntgetValue(uint64_t Xunsigned BitWidthbool isUnsigned);
126
127public:
128  BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
129      : Ctx(ctx), BPAlloc(Alloc), SValListFactory(Alloc),
130        CXXBaseListFactory(Alloc) {}
131
132  ~BasicValueFactory();
133
134  ASTContext &getContext() const { return Ctx; }
135
136  const llvm::APSIntgetValue(const llvm::APSIntX);
137  const llvm::APSIntgetValue(const llvm::APInt& Xbool isUnsigned);
138  const llvm::APSIntgetValue(uint64_t XQualType T);
139
140  /// Returns the type of the APSInt used to store values of the given QualType.
141  APSIntType getAPSIntType(QualType Tconst {
142    isIntegralOrEnumerationType() || Loc..isLocType(T)", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h", 142, __PRETTY_FUNCTION__))" file_link="../../../../../../include/assert.h.html#88" macro="true">assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T));
143    return APSIntType(Ctx.getIntWidth(T),
144                      !T->isSignedIntegerOrEnumerationType());
145  }
146
147  /// Convert - Create a new persistent APSInt with the same value as 'From'
148  ///  but with the bitwidth and signedness of 'To'.
149  const llvm::APSInt &Convert(const llvm::APSIntTo,
150                              const llvm::APSIntFrom) {
151    APSIntType TargetType(To);
152    if (TargetType == APSIntType(From))
153      return From;
154
155    return getValue(TargetType.convert(From));
156  }
157
158  const llvm::APSInt &Convert(QualType Tconst llvm::APSInt &From) {
159    APSIntType TargetType = getAPSIntType(T);
160    if (TargetType == APSIntType(From))
161      return From;
162
163    return getValue(TargetType.convert(From));
164  }
165
166  const llvm::APSInt &getIntValue(uint64_t Xbool isUnsigned) {
167    QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
168    return getValue(XT);
169  }
170
171  const llvm::APSInt &getMaxValue(const llvm::APSInt &v) {
172    return getValue(APSIntType(v).getMaxValue());
173  }
174
175  const llvm::APSInt &getMinValue(const llvm::APSInt &v) {
176    return getValue(APSIntType(v).getMinValue());
177  }
178
179  const llvm::APSInt &getMaxValue(QualType T) {
180    return getValue(getAPSIntType(T).getMaxValue());
181  }
182
183  const llvm::APSInt &getMinValue(QualType T) {
184    return getValue(getAPSIntType(T).getMinValue());
185  }
186
187  const llvm::APSInt &Add1(const llvm::APSInt &V) {
188    llvm::APSInt X = V;
189    ++X;
190    return getValue(X);
191  }
192
193  const llvm::APSInt &Sub1(const llvm::APSInt &V) {
194    llvm::APSInt X = V;
195    --X;
196    return getValue(X);
197  }
198
199  const llvm::APSInt &getZeroWithTypeSize(QualType T) {
200    isScalarType()", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h", 200, __PRETTY_FUNCTION__))" file_link="../../../../../../include/assert.h.html#88" macro="true">assert(T->isScalarType());
201    return getValue(0Ctx.getTypeSize(T), true);
202  }
203
204  const llvm::APSInt &getZeroWithPtrWidth(bool isUnsigned = true) {
205    return getValue(0Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
206  }
207
208  const llvm::APSInt &getIntWithPtrWidth(uint64_t Xbool isUnsigned) {
209    return getValue(XCtx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
210  }
211
212  const llvm::APSInt &getTruthValue(bool bQualType T) {
213    return getValue(b ? 1 : 0Ctx.getIntWidth(T),
214                    T->isUnsignedIntegerOrEnumerationType());
215  }
216
217  const llvm::APSInt &getTruthValue(bool b) {
218    return getTruthValue(bCtx.getLogicalOperationType());
219  }
220
221  const CompoundValData *getCompoundValData(QualType T,
222                                            llvm::ImmutableList<SVal> Vals);
223
224  const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store,
225                                            const TypedValueRegion *region);
226
227  const PointerToMemberData *getPointerToMemberData(
228      const DeclaratorDecl *DD,
229      llvm::ImmutableList<const CXXBaseSpecifier *> L);
230
231  llvm::ImmutableList<SVal> getEmptySValList() {
232    return SValListFactory.getEmptyList();
233  }
234
235  llvm::ImmutableList<SVal> prependSVal(SVal X, llvm::ImmutableList<SVal> L) {
236    return SValListFactory.add(X, L);
237  }
238
239  llvm::ImmutableList<const CXXBaseSpecifier *> getEmptyCXXBaseList() {
240    return CXXBaseListFactory.getEmptyList();
241  }
242
243  llvm::ImmutableList<const CXXBaseSpecifier *> prependCXXBase(
244      const CXXBaseSpecifier *CBS,
245      llvm::ImmutableList<const CXXBaseSpecifier *> L) {
246    return CXXBaseListFactory.add(CBS, L);
247  }
248
249  const PointerToMemberData *accumCXXBase(
250      llvm::iterator_range<CastExpr::path_const_iterator> PathRange,
251      const nonloc::PointerToMember &PTM);
252
253  const llvm::APSIntevalAPSInt(BinaryOperator::Opcode Op,
254                                     const llvm::APSIntV1,
255                                     const llvm::APSIntV2);
256
257  const std::pair<SValuintptr_t>&
258  getPersistentSValWithData(const SValVuintptr_t Data);
259
260  const std::pair<SValSVal>&
261  getPersistentSValPair(const SValV1const SValV2);
262
263  const SValgetPersistentSVal(SVal X);
264};
265
266// namespace ento
267
268// namespace clang
269
270#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
271
clang::ento::CompoundValData::T
clang::ento::CompoundValData::L
clang::ento::CompoundValData::begin
clang::ento::CompoundValData::end
clang::ento::CompoundValData::Profile
clang::ento::CompoundValData::Profile
clang::ento::LazyCompoundValData::store
clang::ento::LazyCompoundValData::region
clang::ento::LazyCompoundValData::getStore
clang::ento::LazyCompoundValData::getRegion
clang::ento::LazyCompoundValData::Profile
clang::ento::LazyCompoundValData::Profile
clang::ento::PointerToMemberData::D
clang::ento::PointerToMemberData::L
clang::ento::PointerToMemberData::begin
clang::ento::PointerToMemberData::end
clang::ento::PointerToMemberData::Profile
clang::ento::PointerToMemberData::Profile
clang::ento::PointerToMemberData::getDeclaratorDecl
clang::ento::PointerToMemberData::getCXXBaseList
clang::ento::BasicValueFactory::Ctx
clang::ento::BasicValueFactory::BPAlloc
clang::ento::BasicValueFactory::APSIntSet
clang::ento::BasicValueFactory::PersistentSVals
clang::ento::BasicValueFactory::PersistentSValPairs
clang::ento::BasicValueFactory::Factory
clang::ento::BasicValueFactory::CompoundValDataSet
clang::ento::BasicValueFactory::LazyCompoundValDataSet
clang::ento::BasicValueFactory::PointerToMemberDataSet
clang::ento::BasicValueFactory::getValue
clang::ento::BasicValueFactory::getContext
clang::ento::BasicValueFactory::getValue
clang::ento::BasicValueFactory::getValue
clang::ento::BasicValueFactory::getValue
clang::ento::BasicValueFactory::getAPSIntType
clang::ento::BasicValueFactory::Convert
clang::ento::BasicValueFactory::Convert
clang::ento::BasicValueFactory::getIntValue
clang::ento::BasicValueFactory::getMaxValue
clang::ento::BasicValueFactory::getMinValue
clang::ento::BasicValueFactory::getMaxValue
clang::ento::BasicValueFactory::getMinValue
clang::ento::BasicValueFactory::Add1
clang::ento::BasicValueFactory::Sub1
clang::ento::BasicValueFactory::getZeroWithTypeSize
clang::ento::BasicValueFactory::getZeroWithPtrWidth
clang::ento::BasicValueFactory::getIntWithPtrWidth
clang::ento::BasicValueFactory::getTruthValue
clang::ento::BasicValueFactory::getTruthValue
clang::ento::BasicValueFactory::getCompoundValData
clang::ento::BasicValueFactory::getLazyCompoundValData
clang::ento::BasicValueFactory::getPointerToMemberData
clang::ento::BasicValueFactory::getEmptySValList
clang::ento::BasicValueFactory::prependSVal
clang::ento::BasicValueFactory::getEmptyCXXBaseList
clang::ento::BasicValueFactory::prependCXXBase
clang::ento::BasicValueFactory::accumCXXBase
clang::ento::BasicValueFactory::evalAPSInt
clang::ento::BasicValueFactory::getPersistentSValWithData
clang::ento::BasicValueFactory::getPersistentSValPair
clang::ento::BasicValueFactory::getPersistentSVal