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