| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 1 | //== ValueManager.cpp - Aggregate manager of symbols and SVals --*- C++ -*--==// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | //  This file defines ValueManager, a class that manages symbolic values | 
|  | 11 | //  and SVals created for use by GRExprEngine and related classes.  It | 
|  | 12 | //  wraps and owns SymbolManager, MemRegionManager, and BasicValueFactory. | 
|  | 13 | // | 
|  | 14 | //===----------------------------------------------------------------------===// | 
|  | 15 |  | 
| Ted Kremenek | d6b8708 | 2010-01-25 04:41:41 +0000 | [diff] [blame] | 16 | #include "clang/Checker/PathSensitive/ValueManager.h" | 
|  | 17 | #include "clang/Analysis/AnalysisContext.h" | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 18 |  | 
|  | 19 | using namespace clang; | 
|  | 20 | using namespace llvm; | 
|  | 21 |  | 
|  | 22 | //===----------------------------------------------------------------------===// | 
|  | 23 | // Utility methods for constructing SVals. | 
|  | 24 | //===----------------------------------------------------------------------===// | 
|  | 25 |  | 
| Ted Kremenek | 7020eae | 2009-09-11 22:07:28 +0000 | [diff] [blame] | 26 | DefinedOrUnknownSVal ValueManager::makeZeroVal(QualType T) { | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 27 | if (Loc::IsLocType(T)) | 
| Zhongxing Xu | 7718ae4 | 2009-06-23 09:02:15 +0000 | [diff] [blame] | 28 | return makeNull(); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 29 |  | 
|  | 30 | if (T->isIntegerType()) | 
| Zhongxing Xu | 7718ae4 | 2009-06-23 09:02:15 +0000 | [diff] [blame] | 31 | return makeIntVal(0, T); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 32 |  | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 33 | // FIXME: Handle floats. | 
|  | 34 | // FIXME: Handle structs. | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 35 | return UnknownVal(); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 36 | } | 
|  | 37 |  | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 38 | //===----------------------------------------------------------------------===// | 
|  | 39 | // Utility methods for constructing Non-Locs. | 
|  | 40 | //===----------------------------------------------------------------------===// | 
|  | 41 |  | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 42 | NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, | 
|  | 43 | const APSInt& v, QualType T) { | 
|  | 44 | // The Environment ensures we always get a persistent APSInt in | 
|  | 45 | // BasicValueFactory, so we don't need to get the APSInt from | 
|  | 46 | // BasicValueFactory again. | 
|  | 47 | assert(!Loc::IsLocType(T)); | 
|  | 48 | return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T)); | 
|  | 49 | } | 
|  | 50 |  | 
|  | 51 | NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, | 
|  | 52 | const SymExpr *rhs, QualType T) { | 
|  | 53 | assert(SymMgr.getType(lhs) == SymMgr.getType(rhs)); | 
|  | 54 | assert(!Loc::IsLocType(T)); | 
|  | 55 | return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T)); | 
|  | 56 | } | 
|  | 57 |  | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 58 |  | 
| Ted Kremenek | f267a15 | 2009-07-16 01:32:00 +0000 | [diff] [blame] | 59 | SVal ValueManager::convertToArrayIndex(SVal V) { | 
| Ted Kremenek | ac7c724 | 2009-07-21 21:03:30 +0000 | [diff] [blame] | 60 | if (V.isUnknownOrUndef()) | 
|  | 61 | return V; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 62 |  | 
| Ted Kremenek | f267a15 | 2009-07-16 01:32:00 +0000 | [diff] [blame] | 63 | // Common case: we have an appropriately sized integer. | 
|  | 64 | if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&V)) { | 
|  | 65 | const llvm::APSInt& I = CI->getValue(); | 
|  | 66 | if (I.getBitWidth() == ArrayIndexWidth && I.isSigned()) | 
|  | 67 | return V; | 
|  | 68 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 69 |  | 
| Ted Kremenek | ac7c724 | 2009-07-21 21:03:30 +0000 | [diff] [blame] | 70 | return SVator->EvalCastNL(cast<NonLoc>(V), ArrayIndexTy); | 
| Ted Kremenek | f267a15 | 2009-07-16 01:32:00 +0000 | [diff] [blame] | 71 | } | 
|  | 72 |  | 
| Zhongxing Xu | 6d3cc38 | 2010-03-01 06:56:52 +0000 | [diff] [blame] | 73 | DefinedOrUnknownSVal | 
|  | 74 | ValueManager::getRegionValueSymbolVal(const TypedRegion* R) { | 
|  | 75 | QualType T = R->getValueType(SymMgr.getContext()); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 76 |  | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 77 | if (!SymbolManager::canSymbolicate(T)) | 
|  | 78 | return UnknownVal(); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 79 |  | 
| Zhongxing Xu | 6d3cc38 | 2010-03-01 06:56:52 +0000 | [diff] [blame] | 80 | SymbolRef sym = SymMgr.getRegionValueSymbol(R); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 81 |  | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 82 | if (Loc::IsLocType(T)) | 
|  | 83 | return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 84 |  | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 85 | return nonloc::SymbolVal(sym); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 86 | } | 
|  | 87 |  | 
| Ted Kremenek | e41b81e | 2009-09-27 20:45:21 +0000 | [diff] [blame] | 88 | DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag, | 
|  | 89 | const Expr *E, | 
|  | 90 | unsigned Count) { | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 91 | QualType T = E->getType(); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 92 |  | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 93 | if (!SymbolManager::canSymbolicate(T)) | 
|  | 94 | return UnknownVal(); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 95 |  | 
| Ted Kremenek | e41b81e | 2009-09-27 20:45:21 +0000 | [diff] [blame] | 96 | SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 97 |  | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 98 | if (Loc::IsLocType(T)) | 
| Zhongxing Xu | 7718ae4 | 2009-06-23 09:02:15 +0000 | [diff] [blame] | 99 | return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 100 |  | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 101 | return nonloc::SymbolVal(sym); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 102 | } | 
|  | 103 |  | 
| Ted Kremenek | e41b81e | 2009-09-27 20:45:21 +0000 | [diff] [blame] | 104 | DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag, | 
|  | 105 | const Expr *E, | 
| Ted Kremenek | 7020eae | 2009-09-11 22:07:28 +0000 | [diff] [blame] | 106 | QualType T, | 
|  | 107 | unsigned Count) { | 
|  | 108 |  | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 109 | if (!SymbolManager::canSymbolicate(T)) | 
|  | 110 | return UnknownVal(); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 111 |  | 
| Ted Kremenek | e41b81e | 2009-09-27 20:45:21 +0000 | [diff] [blame] | 112 | SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 113 |  | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 114 | if (Loc::IsLocType(T)) | 
| Zhongxing Xu | 7718ae4 | 2009-06-23 09:02:15 +0000 | [diff] [blame] | 115 | return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 116 |  | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 117 | return nonloc::SymbolVal(sym); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 118 | } | 
|  | 119 |  | 
| Ted Kremenek | c6c2157 | 2009-07-15 02:27:32 +0000 | [diff] [blame] | 120 |  | 
| Ted Kremenek | 7020eae | 2009-09-11 22:07:28 +0000 | [diff] [blame] | 121 | DefinedOrUnknownSVal | 
|  | 122 | ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, | 
|  | 123 | const TypedRegion *R) { | 
| Ted Kremenek | c6c2157 | 2009-07-15 02:27:32 +0000 | [diff] [blame] | 124 | QualType T = R->getValueType(R->getContext()); | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 125 |  | 
|  | 126 | if (!SymbolManager::canSymbolicate(T)) | 
|  | 127 | return UnknownVal(); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 128 |  | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 129 | SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 130 |  | 
| Ted Kremenek | c6c2157 | 2009-07-15 02:27:32 +0000 | [diff] [blame] | 131 | if (Loc::IsLocType(T)) | 
|  | 132 | return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 133 |  | 
| Ted Kremenek | 1f22aa7 | 2009-08-01 06:17:29 +0000 | [diff] [blame] | 134 | return nonloc::SymbolVal(sym); | 
| Ted Kremenek | c6c2157 | 2009-07-15 02:27:32 +0000 | [diff] [blame] | 135 | } | 
|  | 136 |  | 
| Ted Kremenek | 7020eae | 2009-09-11 22:07:28 +0000 | [diff] [blame] | 137 | DefinedSVal ValueManager::getFunctionPointer(const FunctionDecl* FD) { | 
| Ted Kremenek | 721fcc0 | 2009-12-04 00:26:31 +0000 | [diff] [blame] | 138 | return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD)); | 
| Zhongxing Xu | 0808f70 | 2009-06-23 06:22:22 +0000 | [diff] [blame] | 139 | } | 
| Ted Kremenek | 10a50e7 | 2009-11-25 01:32:22 +0000 | [diff] [blame] | 140 |  | 
| Ted Kremenek | b63ad7a | 2009-11-25 23:53:07 +0000 | [diff] [blame] | 141 | DefinedSVal ValueManager::getBlockPointer(const BlockDecl *D, | 
|  | 142 | CanQualType locTy, | 
|  | 143 | const LocationContext *LC) { | 
| Ted Kremenek | 04af9f2 | 2009-12-07 22:05:27 +0000 | [diff] [blame] | 144 | const BlockTextRegion *BC = | 
|  | 145 | MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext()); | 
| Ted Kremenek | 721fcc0 | 2009-12-04 00:26:31 +0000 | [diff] [blame] | 146 | const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC); | 
| Ted Kremenek | b63ad7a | 2009-11-25 23:53:07 +0000 | [diff] [blame] | 147 | return loc::MemRegionVal(BD); | 
| Ted Kremenek | 10a50e7 | 2009-11-25 01:32:22 +0000 | [diff] [blame] | 148 | } | 
|  | 149 |  |