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
16478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer#include "clang/AST/ASTContext.h"
179b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
182c0af358072e5be81634a8767e501b962dbdd3caTed Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
19d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
20d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenekusing namespace clang;
219ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
22d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
24632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek                              llvm::ImmutableList<SVal> L) {
256764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  T.Profile(ID);
26632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  ID.AddPointer(L.getInternalPointer());
276764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu}
286764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
29a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekvoid LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
30cf333339615da345c2ed6e873d94a501810d9f3fTed Kremenek                                  const StoreRef &store,
319697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek                                  const TypedValueRegion *region) {
32cf333339615da345c2ed6e873d94a501810d9f3fTed Kremenek  ID.AddPointer(store.getStore());
33a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  ID.AddPointer(region);
34a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek}
35a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek
361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutypedef std::pair<SVal, uintptr_t> SValData;
371c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutypedef std::pair<SVal, SVal> SValPair;
384d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
390fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremeneknamespace llvm {
401c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutemplate<> struct FoldingSetTrait<SValData> {
411c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
420fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek    X.first.Profile(ID);
43718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    ID.AddPointer( (void*) X.second);
440fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
450fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek};
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutemplate<> struct FoldingSetTrait<SValPair> {
481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
494d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    X.first.Profile(ID);
504d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    X.second.Profile(ID);
514d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
524d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek};
530fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek}
540fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
551c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutypedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
561c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  PersistentSValsTy;
570fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xutypedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
591c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  PersistentSValPairsTy;
604d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
61240f1f00dda1d481276ea872fe8f8851581a7e6bTed KremenekBasicValueFactory::~BasicValueFactory() {
62d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  // Note that the dstor for the contents of APSIntSet will never be called,
63d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  // so we iterate over the set and invoke the dstor for each APSInt.  This
64d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  // frees an aux. memory allocated to represent very large constants.
65d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
66d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    I->getValue().~APSInt();
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  delete (PersistentSValsTy*) PersistentSVals;
691c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  delete (PersistentSValPairsTy*) PersistentSValPairs;
70d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
71d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
72240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenekconst llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
73d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  llvm::FoldingSetNodeID ID;
749c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
75d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
77d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  X.Profile(ID);
78d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!P) {
81d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
82d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    new (P) FoldNodeTy(X);
83d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    APSIntSet.InsertNode(P, InsertPos);
84d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  }
851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
86d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  return *P;
87d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
88d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
89e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xuconst llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
90e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu                                                bool isUnsigned) {
91e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu  llvm::APSInt V(X, isUnsigned);
92e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu  return getValue(V);
93e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu}
94e8a964bdb46349e4fa3433c8e5104d2a0f7f5c65Zhongxing Xu
95240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenekconst llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
96d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek                                           bool isUnsigned) {
97d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  llvm::APSInt V(BitWidth, isUnsigned);
981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  V = X;
99d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  return getValue(V);
100d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
101d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
102240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenekconst llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10491ab900a939e95d965e18299b66928fdbe2aa38dJordan Rose  return getValue(getAPSIntType(T).getValue(X));
105d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
106d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek
1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpconst CompoundValData*
108632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed KremenekBasicValueFactory::getCompoundValData(QualType T,
109632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek                                      llvm::ImmutableList<SVal> Vals) {
1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1116764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  llvm::FoldingSetNodeID ID;
112632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek  CompoundValData::Profile(ID, T, Vals);
1139c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
1146764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
1156764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
1166764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
1176764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  if (!D) {
1186764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
119632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek    new (D) CompoundValData(T, Vals);
1206764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu    CompoundValDataSet.InsertNode(D, InsertPos);
1216764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  }
1226764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
1236764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu  return D;
1246764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu}
1256764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu
126a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekconst LazyCompoundValData*
127cf333339615da345c2ed6e873d94a501810d9f3fTed KremenekBasicValueFactory::getLazyCompoundValData(const StoreRef &store,
1289697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek                                          const TypedValueRegion *region) {
129a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  llvm::FoldingSetNodeID ID;
130bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu  LazyCompoundValData::Profile(ID, store, region);
1319c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
133a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  LazyCompoundValData *D =
134a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
136a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  if (!D) {
137a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    D = (LazyCompoundValData*) BPAlloc.Allocate<LazyCompoundValData>();
138bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu    new (D) LazyCompoundValData(store, region);
139a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    LazyCompoundValDataSet.InsertNode(D, InsertPos);
140a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  }
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
142a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  return D;
143a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek}
144a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek
1458cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenekconst llvm::APSInt*
1469c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed KremenekBasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
147d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek                             const llvm::APSInt& V1, const llvm::APSInt& V2) {
1481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
149d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  switch (Op) {
150d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek    default:
151d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek      assert (false && "Invalid Opcode.");
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1532de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Mul:
1548cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 * V2 );
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1562de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Div:
1578cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 / V2 );
1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Rem:
1608cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 % V2 );
1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Add:
1638cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 + V2 );
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Sub:
1668cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 - V2 );
1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1682de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Shl: {
1698cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek
1708cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // FIXME: This logic should probably go higher up, where we can
1718cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // test these conditions symbolically.
1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1738cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // FIXME: Expand these checks to include all undefined behavior.
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1758cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      if (V2.isSigned() && V2.isNegative())
1768cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek        return NULL;
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1788cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      uint64_t Amt = V2.getZExtValue();
1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1808cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      if (Amt > V1.getBitWidth())
1818cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek        return NULL;
1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1838cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1.operator<<( (unsigned) Amt ));
1848cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    }
1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1862de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Shr: {
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1888cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // FIXME: This logic should probably go higher up, where we can
1898cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // test these conditions symbolically.
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1918cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      // FIXME: Expand these checks to include all undefined behavior.
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1938cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      if (V2.isSigned() && V2.isNegative())
1948cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek        return NULL;
1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1968cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      uint64_t Amt = V2.getZExtValue();
1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1988cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      if (Amt > V1.getBitWidth())
1998cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek        return NULL;
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2018cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1.operator>>( (unsigned) Amt ));
2028cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    }
2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2042de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_LT:
2058cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 < V2 );
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2072de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_GT:
2088cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 > V2 );
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2102de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_LE:
2118cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 <= V2 );
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2132de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_GE:
2148cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 >= V2 );
2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2162de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_EQ:
2178cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 == V2 );
2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_NE:
2208cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getTruthValue( V1 != V2 );
2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
222d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek      // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2242de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_And:
2258cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 & V2 );
2261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2272de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Or:
2288cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 | V2 );
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2302de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    case BO_Xor:
2318cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return &getValue( V1 ^ V2 );
232d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek  }
233d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek}
2340fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2350fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
2361c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuconst std::pair<SVal, uintptr_t>&
2371c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing XuBasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2390fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  // Lazily create the folding set.
2401c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2420fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  llvm::FoldingSetNodeID ID;
2439c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
2440fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  V.Profile(ID);
245718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  ID.AddPointer((void*) Data);
2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
2500fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!P) {
2530fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
254718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek    new (P) FoldNodeTy(std::make_pair(V, Data));
2550fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek    Map.InsertNode(P, InsertPos);
2560fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek  }
2570fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek
258718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek  return P->getValue();
2590fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek}
2604d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
2611c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuconst std::pair<SVal, SVal>&
2621c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing XuBasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2644d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  // Lazily create the folding set.
2651c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2674d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  llvm::FoldingSetNodeID ID;
2689c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void *InsertPos;
2694d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  V1.Profile(ID);
2704d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  V2.Profile(ID);
2711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2721c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2741c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
2754d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!P) {
2784d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
2794d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    new (P) FoldNodeTy(std::make_pair(V1, V2));
2804d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek    Map.InsertNode(P, InsertPos);
2814d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  }
2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2834d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek  return P->getValue();
2844d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek}
2854d0348b6c74d2710a3693bbfbcfc5fcb3bc132eeTed Kremenek
2861c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuconst SVal* BasicValueFactory::getPersistentSVal(SVal X) {
2871c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  return &getPersistentSValWithData(X, 0).first;
2881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
289