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