1240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek//=== BasicValueFactory.cpp - Basic values for Path Sens analysis --*- C++ -*-//
2d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//
3d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//                     The LLVM Compiler Infrastructure
4d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//
5d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// This file is distributed under the University of Illinois Open Source
6d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek// License. See LICENSE.TXT for details.
7d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//
8d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//===----------------------------------------------------------------------===//
9d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//
10240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek//  This file defines BasicValueFactory, a class that manages the lifetime
11d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis//  of APSInt objects and symbolic constraints used by ExprEngine
12240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek//  and related classes.
13d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//
14d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek//===----------------------------------------------------------------------===//
15d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
169b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
172c0af358072e5be81634a8767e501b962dbdd3caTed Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
18d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
19d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenekusing namespace clang;
209ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
21d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
23632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek                              llvm::ImmutableList<SVal> L) {
246764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  T.Profile(ID);
25632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  ID.AddPointer(L.getInternalPointer());
266764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu}
276764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
28a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekvoid LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
29cf333339615da345c2ed6e873d94a501810d9f3fTed Kremenek                                  const StoreRef &store,
309697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek                                  const TypedValueRegion *region) {
31cf333339615da345c2ed6e873d94a501810d9f3fTed Kremenek  ID.AddPointer(store.getStore());
32a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  ID.AddPointer(region);
33a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek}
34a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek
351c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutypedef std::pair<SVal, uintptr_t> SValData;
361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutypedef std::pair<SVal, SVal> SValPair;
374d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
380fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremeneknamespace llvm {
391c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutemplate<> struct FoldingSetTrait<SValData> {
401c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
410fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek    X.first.Profile(ID);
42718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    ID.AddPointer( (void*) X.second);
430fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
440fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek};
451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
461c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutemplate<> struct FoldingSetTrait<SValPair> {
471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
484d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    X.first.Profile(ID);
494d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    X.second.Profile(ID);
504d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
514d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek};
520fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek}
530fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
541c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutypedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
551c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  PersistentSValsTy;
560fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
571c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutypedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  PersistentSValPairsTy;
594d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
60240f1f00dda1d481276ea872fe8f8851581a7e6bTed KremenekBasicValueFactory::~BasicValueFactory() {
61d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  // Note that the dstor for the contents of APSIntSet will never be called,
62d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  // so we iterate over the set and invoke the dstor for each APSInt.  This
63d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  // frees an aux. memory allocated to represent very large constants.
64d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
65d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    I->getValue().~APSInt();
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  delete (PersistentSValsTy*) PersistentSVals;
681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  delete (PersistentSValPairsTy*) PersistentSValPairs;
69d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
70d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
71240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenekconst llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
72d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  llvm::FoldingSetNodeID ID;
739c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
74d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
76d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  X.Profile(ID);
77d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!P) {
80d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
81d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    new (P) FoldNodeTy(X);
82d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    APSIntSet.InsertNode(P, InsertPos);
83d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  }
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
85d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  return *P;
86d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
87d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
88e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xuconst llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
89e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu                                                bool isUnsigned) {
90e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu  llvm::APSInt V(X, isUnsigned);
91e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu  return getValue(V);
92e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu}
93e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu
94240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenekconst llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
95d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek                                           bool isUnsigned) {
96d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  llvm::APSInt V(BitWidth, isUnsigned);
971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  V = X;
98d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  return getValue(V);
99d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
100d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
101240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenekconst llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10398be4943e8dc4f3905629a7102668960873cf863Chris Lattner  unsigned bits = Ctx.getTypeSize(T);
1045e9ebb3c0fb554d9285aa99c470abdf283272bd9Douglas Gregor  llvm::APSInt V(bits,
1055e9ebb3c0fb554d9285aa99c470abdf283272bd9Douglas Gregor                 T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T));
106d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  V = X;
107d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  return getValue(V);
108d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
109d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpconst CompoundValData*
111632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed KremenekBasicValueFactory::getCompoundValData(QualType T,
112632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek                                      llvm::ImmutableList<SVal> Vals) {
1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1146764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  llvm::FoldingSetNodeID ID;
115632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  CompoundValData::Profile(ID, T, Vals);
1169c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
1176764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
1186764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
1196764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
1206764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  if (!D) {
1216764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
122632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek    new (D) CompoundValData(T, Vals);
1236764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    CompoundValDataSet.InsertNode(D, InsertPos);
1246764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
1256764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
1266764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  return D;
1276764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu}
1286764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
129a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekconst LazyCompoundValData*
130cf333339615da345c2ed6e873d94a501810d9f3fTed KremenekBasicValueFactory::getLazyCompoundValData(const StoreRef &store,
1319697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek                                          const TypedValueRegion *region) {
132a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  llvm::FoldingSetNodeID ID;
133bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu  LazyCompoundValData::Profile(ID, store, region);
1349c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
136a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  LazyCompoundValData *D =
137a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
1381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
139a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  if (!D) {
140a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    D = (LazyCompoundValData*) BPAlloc.Allocate<LazyCompoundValData>();
141bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu    new (D) LazyCompoundValData(store, region);
142a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    LazyCompoundValDataSet.InsertNode(D, InsertPos);
143a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  }
1441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
145a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  return D;
146a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek}
147a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek
1488cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenekconst llvm::APSInt*
1499c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed KremenekBasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
150d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek                             const llvm::APSInt& V1, const llvm::APSInt& V2) {
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
152d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  switch (Op) {
153d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    default:
154d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek      assert (false && "Invalid Opcode.");
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1562de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Mul:
1578cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 * V2 );
1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Div:
1608cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 / V2 );
1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Rem:
1638cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 % V2 );
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Add:
1668cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 + V2 );
1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1682de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Sub:
1698cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 - V2 );
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1712de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Shl: {
1728cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek
1738cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // FIXME: This logic should probably go higher up, where we can
1748cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // test these conditions symbolically.
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1768cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // FIXME: Expand these checks to include all undefined behavior.
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1788cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      if (V2.isSigned() && V2.isNegative())
1798cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek        return NULL;
1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1818cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      uint64_t Amt = V2.getZExtValue();
1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1838cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      if (Amt > V1.getBitWidth())
1848cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek        return NULL;
1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1868cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1.operator<<( (unsigned) Amt ));
1878cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    }
1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1892de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Shr: {
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1918cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // FIXME: This logic should probably go higher up, where we can
1928cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // test these conditions symbolically.
1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1948cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // FIXME: Expand these checks to include all undefined behavior.
1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1968cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      if (V2.isSigned() && V2.isNegative())
1978cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek        return NULL;
1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1998cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      uint64_t Amt = V2.getZExtValue();
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2018cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      if (Amt > V1.getBitWidth())
2028cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek        return NULL;
2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2048cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1.operator>>( (unsigned) Amt ));
2058cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    }
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2072de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_LT:
2088cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 < V2 );
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2102de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_GT:
2118cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 > V2 );
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2132de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_LE:
2148cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 <= V2 );
2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2162de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_GE:
2178cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 >= V2 );
2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_EQ:
2208cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 == V2 );
2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2222de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_NE:
2238cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 != V2 );
2241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
225d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek      // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
2261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2272de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_And:
2288cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 & V2 );
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2302de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Or:
2318cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 | V2 );
2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2332de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Xor:
2348cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 ^ V2 );
235d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  }
236d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
2370fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2380fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2391c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuconst std::pair<SVal, uintptr_t>&
2401c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing XuBasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2420fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  // Lazily create the folding set.
2431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2450fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  llvm::FoldingSetNodeID ID;
2469c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
2470fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  V.Profile(ID);
248718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  ID.AddPointer((void*) Data);
2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2501c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2521c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
2530fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
2541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!P) {
2560fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
257718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    new (P) FoldNodeTy(std::make_pair(V, Data));
2580fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek    Map.InsertNode(P, InsertPos);
2590fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
2600fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
261718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  return P->getValue();
2620fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek}
2634d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
2641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuconst std::pair<SVal, SVal>&
2651c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing XuBasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2674d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  // Lazily create the folding set.
2681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
2691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2704d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  llvm::FoldingSetNodeID ID;
2719c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
2724d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  V1.Profile(ID);
2734d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  V2.Profile(ID);
2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2771c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
2784d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
2791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!P) {
2814d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
2824d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    new (P) FoldNodeTy(std::make_pair(V1, V2));
2834d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    Map.InsertNode(P, InsertPos);
2844d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2864d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  return P->getValue();
2874d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek}
2884d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
2891c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuconst SVal* BasicValueFactory::getPersistentSVal(SVal X) {
2901c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  return &getPersistentSValWithData(X, 0).first;
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
292