summaryrefslogtreecommitdiff
path: root/clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h')
-rw-r--r--clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h270
1 files changed, 270 insertions, 0 deletions
diff --git a/clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
new file mode 100644
index 00000000..ac218bc0
--- /dev/null
+++ b/clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -0,0 +1,270 @@
+//==- BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines BasicValueFactory, a class that manages the lifetime
+// of APSInt objects and symbolic constraints used by ExprEngine
+// and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Allocator.h"
+#include <cassert>
+#include <cstdint>
+#include <utility>
+
+namespace clang {
+
+class CXXBaseSpecifier;
+class DeclaratorDecl;
+
+namespace ento {
+
+class CompoundValData : public llvm::FoldingSetNode {
+ QualType T;
+ llvm::ImmutableList<SVal> L;
+
+public:
+ CompoundValData(QualType t, llvm::ImmutableList<SVal> l) : T(t), L(l) {
+ assert(NonLoc::isCompoundType(t));
+ }
+
+ using iterator = llvm::ImmutableList<SVal>::iterator;
+
+ iterator begin() const { return L.begin(); }
+ iterator end() const { return L.end(); }
+
+ static void Profile(llvm::FoldingSetNodeID& ID, QualType T,
+ llvm::ImmutableList<SVal> L);
+
+ void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); }
+};
+
+class LazyCompoundValData : public llvm::FoldingSetNode {
+ StoreRef store;
+ const TypedValueRegion *region;
+
+public:
+ LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r)
+ : store(st), region(r) {
+ assert(NonLoc::isCompoundType(r->getValueType()));
+ }
+
+ const void *getStore() const { return store.getStore(); }
+ const TypedValueRegion *getRegion() const { return region; }
+
+ static void Profile(llvm::FoldingSetNodeID& ID,
+ const StoreRef &store,
+ const TypedValueRegion *region);
+
+ void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
+};
+
+class PointerToMemberData : public llvm::FoldingSetNode {
+ const DeclaratorDecl *D;
+ llvm::ImmutableList<const CXXBaseSpecifier *> L;
+
+public:
+ PointerToMemberData(const DeclaratorDecl *D,
+ llvm::ImmutableList<const CXXBaseSpecifier *> L)
+ : D(D), L(L) {}
+
+ using iterator = llvm::ImmutableList<const CXXBaseSpecifier *>::iterator;
+
+ iterator begin() const { return L.begin(); }
+ iterator end() const { return L.end(); }
+
+ static void Profile(llvm::FoldingSetNodeID& ID, const DeclaratorDecl *D,
+ llvm::ImmutableList<const CXXBaseSpecifier *> L);
+
+ void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, D, L); }
+ const DeclaratorDecl *getDeclaratorDecl() const {return D;}
+
+ llvm::ImmutableList<const CXXBaseSpecifier *> getCXXBaseList() const {
+ return L;
+ }
+};
+
+class BasicValueFactory {
+ using APSIntSetTy =
+ llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt>>;
+
+ ASTContext &Ctx;
+ llvm::BumpPtrAllocator& BPAlloc;
+
+ APSIntSetTy APSIntSet;
+ void *PersistentSVals = nullptr;
+ void *PersistentSValPairs = nullptr;
+
+ llvm::ImmutableList<SVal>::Factory SValListFactory;
+ llvm::ImmutableList<const CXXBaseSpecifier *>::Factory CXXBaseListFactory;
+ llvm::FoldingSet<CompoundValData> CompoundValDataSet;
+ llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
+ llvm::FoldingSet<PointerToMemberData> PointerToMemberDataSet;
+
+ // This is private because external clients should use the factory
+ // method that takes a QualType.
+ const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
+
+public:
+ BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
+ : Ctx(ctx), BPAlloc(Alloc), SValListFactory(Alloc),
+ CXXBaseListFactory(Alloc) {}
+
+ ~BasicValueFactory();
+
+ ASTContext &getContext() const { return Ctx; }
+
+ const llvm::APSInt& getValue(const llvm::APSInt& X);
+ const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned);
+ const llvm::APSInt& getValue(uint64_t X, QualType T);
+
+ /// Returns the type of the APSInt used to store values of the given QualType.
+ APSIntType getAPSIntType(QualType T) const {
+ assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T));
+ return APSIntType(Ctx.getIntWidth(T),
+ !T->isSignedIntegerOrEnumerationType());
+ }
+
+ /// Convert - Create a new persistent APSInt with the same value as 'From'
+ /// but with the bitwidth and signedness of 'To'.
+ const llvm::APSInt &Convert(const llvm::APSInt& To,
+ const llvm::APSInt& From) {
+ APSIntType TargetType(To);
+ if (TargetType == APSIntType(From))
+ return From;
+
+ return getValue(TargetType.convert(From));
+ }
+
+ const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
+ APSIntType TargetType = getAPSIntType(T);
+ if (TargetType == APSIntType(From))
+ return From;
+
+ return getValue(TargetType.convert(From));
+ }
+
+ const llvm::APSInt &getIntValue(uint64_t X, bool isUnsigned) {
+ QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
+ return getValue(X, T);
+ }
+
+ const llvm::APSInt &getMaxValue(const llvm::APSInt &v) {
+ return getValue(APSIntType(v).getMaxValue());
+ }
+
+ const llvm::APSInt &getMinValue(const llvm::APSInt &v) {
+ return getValue(APSIntType(v).getMinValue());
+ }
+
+ const llvm::APSInt &getMaxValue(QualType T) {
+ return getValue(getAPSIntType(T).getMaxValue());
+ }
+
+ const llvm::APSInt &getMinValue(QualType T) {
+ return getValue(getAPSIntType(T).getMinValue());
+ }
+
+ const llvm::APSInt &Add1(const llvm::APSInt &V) {
+ llvm::APSInt X = V;
+ ++X;
+ return getValue(X);
+ }
+
+ const llvm::APSInt &Sub1(const llvm::APSInt &V) {
+ llvm::APSInt X = V;
+ --X;
+ return getValue(X);
+ }
+
+ const llvm::APSInt &getZeroWithTypeSize(QualType T) {
+ assert(T->isScalarType());
+ return getValue(0, Ctx.getTypeSize(T), true);
+ }
+
+ const llvm::APSInt &getZeroWithPtrWidth(bool isUnsigned = true) {
+ return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
+ }
+
+ const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) {
+ return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
+ }
+
+ const llvm::APSInt &getTruthValue(bool b, QualType T) {
+ return getValue(b ? 1 : 0, Ctx.getIntWidth(T),
+ T->isUnsignedIntegerOrEnumerationType());
+ }
+
+ const llvm::APSInt &getTruthValue(bool b) {
+ return getTruthValue(b, Ctx.getLogicalOperationType());
+ }
+
+ const CompoundValData *getCompoundValData(QualType T,
+ llvm::ImmutableList<SVal> Vals);
+
+ const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store,
+ const TypedValueRegion *region);
+
+ const PointerToMemberData *getPointerToMemberData(
+ const DeclaratorDecl *DD,
+ llvm::ImmutableList<const CXXBaseSpecifier *> L);
+
+ llvm::ImmutableList<SVal> getEmptySValList() {
+ return SValListFactory.getEmptyList();
+ }
+
+ llvm::ImmutableList<SVal> prependSVal(SVal X, llvm::ImmutableList<SVal> L) {
+ return SValListFactory.add(X, L);
+ }
+
+ llvm::ImmutableList<const CXXBaseSpecifier *> getEmptyCXXBaseList() {
+ return CXXBaseListFactory.getEmptyList();
+ }
+
+ llvm::ImmutableList<const CXXBaseSpecifier *> prependCXXBase(
+ const CXXBaseSpecifier *CBS,
+ llvm::ImmutableList<const CXXBaseSpecifier *> L) {
+ return CXXBaseListFactory.add(CBS, L);
+ }
+
+ const PointerToMemberData *accumCXXBase(
+ llvm::iterator_range<CastExpr::path_const_iterator> PathRange,
+ const nonloc::PointerToMember &PTM);
+
+ const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op,
+ const llvm::APSInt& V1,
+ const llvm::APSInt& V2);
+
+ const std::pair<SVal, uintptr_t>&
+ getPersistentSValWithData(const SVal& V, uintptr_t Data);
+
+ const std::pair<SVal, SVal>&
+ getPersistentSValPair(const SVal& V1, const SVal& V2);
+
+ const SVal* getPersistentSVal(SVal X);
+};
+
+} // namespace ento
+
+} // namespace clang
+
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H