1 // SValBuilder.cpp - Basic class for all SValBuilder implementations -*- 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 SValBuilder, the base class for all (complete) SValBuilder 11 // implementations. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/AST/ExprCXX.h" 16 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 17 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 18 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" 19 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 20 #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h" 21 22 using namespace clang; 23 using namespace ento; 24 25 //===----------------------------------------------------------------------===// 26 // Basic SVal creation. 27 //===----------------------------------------------------------------------===// 28 29 void SValBuilder::anchor() { } 30 31 DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) { 32 if (Loc::isLocType(type)) 33 return makeNull(); 34 35 if (type->isIntegerType()) 36 return makeIntVal(0, type); 37 38 // FIXME: Handle floats. 39 // FIXME: Handle structs. 40 return UnknownVal(); 41 } 42 43 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, 44 const llvm::APSInt& rhs, QualType type) { 45 // The Environment ensures we always get a persistent APSInt in 46 // BasicValueFactory, so we don't need to get the APSInt from 47 // BasicValueFactory again. 48 assert(lhs); 49 assert(!Loc::isLocType(type)); 50 return nonloc::SymbolVal(SymMgr.getSymIntExpr(lhs, op, rhs, type)); 51 } 52 53 NonLoc SValBuilder::makeNonLoc(const llvm::APSInt& lhs, 54 BinaryOperator::Opcode op, const SymExpr *rhs, 55 QualType type) { 56 assert(rhs); 57 assert(!Loc::isLocType(type)); 58 return nonloc::SymbolVal(SymMgr.getIntSymExpr(lhs, op, rhs, type)); 59 } 60 61 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, 62 const SymExpr *rhs, QualType type) { 63 assert(lhs && rhs); 64 assert(haveSameType(lhs->getType(Context), rhs->getType(Context)) == true); 65 assert(!Loc::isLocType(type)); 66 return nonloc::SymbolVal(SymMgr.getSymSymExpr(lhs, op, rhs, type)); 67 } 68 69 NonLoc SValBuilder::makeNonLoc(const SymExpr *operand, 70 QualType fromTy, QualType toTy) { 71 assert(operand); 72 assert(!Loc::isLocType(toTy)); 73 return nonloc::SymbolVal(SymMgr.getCastSymbol(operand, fromTy, toTy)); 74 } 75 76 SVal SValBuilder::convertToArrayIndex(SVal val) { 77 if (val.isUnknownOrUndef()) 78 return val; 79 80 // Common case: we have an appropriately sized integer. 81 if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&val)) { 82 const llvm::APSInt& I = CI->getValue(); 83 if (I.getBitWidth() == ArrayIndexWidth && I.isSigned()) 84 return val; 85 } 86 87 return evalCastFromNonLoc(cast<NonLoc>(val), ArrayIndexTy); 88 } 89 90 nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){ 91 return makeTruthVal(boolean->getValue()); 92 } 93 94 DefinedOrUnknownSVal 95 SValBuilder::getRegionValueSymbolVal(const TypedValueRegion* region) { 96 QualType T = region->getValueType(); 97 98 if (!SymbolManager::canSymbolicate(T)) 99 return UnknownVal(); 100 101 SymbolRef sym = SymMgr.getRegionValueSymbol(region); 102 103 if (Loc::isLocType(T)) 104 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 105 106 return nonloc::SymbolVal(sym); 107 } 108 109 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *symbolTag, 110 const Expr *expr, 111 unsigned count) { 112 QualType T = expr->getType(); 113 return getConjuredSymbolVal(symbolTag, expr, T, count); 114 } 115 116 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *symbolTag, 117 const Expr *expr, 118 QualType type, 119 unsigned count) { 120 if (!SymbolManager::canSymbolicate(type)) 121 return UnknownVal(); 122 123 SymbolRef sym = SymMgr.getConjuredSymbol(expr, type, count, symbolTag); 124 125 if (Loc::isLocType(type)) 126 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 127 128 return nonloc::SymbolVal(sym); 129 } 130 131 DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag, 132 const MemRegion *region, 133 const Expr *expr, QualType type, 134 unsigned count) { 135 assert(SymbolManager::canSymbolicate(type) && "Invalid metadata symbol type"); 136 137 SymbolRef sym = 138 SymMgr.getMetadataSymbol(region, expr, type, count, symbolTag); 139 140 if (Loc::isLocType(type)) 141 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 142 143 return nonloc::SymbolVal(sym); 144 } 145 146 DefinedOrUnknownSVal 147 SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, 148 const TypedValueRegion *region) { 149 QualType T = region->getValueType(); 150 151 if (!SymbolManager::canSymbolicate(T)) 152 return UnknownVal(); 153 154 SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, region); 155 156 if (Loc::isLocType(T)) 157 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 158 159 return nonloc::SymbolVal(sym); 160 } 161 162 DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) { 163 return loc::MemRegionVal(MemMgr.getFunctionTextRegion(func)); 164 } 165 166 DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block, 167 CanQualType locTy, 168 const LocationContext *locContext) { 169 const BlockTextRegion *BC = 170 MemMgr.getBlockTextRegion(block, locTy, locContext->getAnalysisDeclContext()); 171 const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext); 172 return loc::MemRegionVal(BD); 173 } 174 175 //===----------------------------------------------------------------------===// 176 177 SVal SValBuilder::makeGenericVal(ProgramStateRef State, 178 BinaryOperator::Opcode Op, 179 NonLoc LHS, NonLoc RHS, 180 QualType ResultTy) { 181 // If operands are tainted, create a symbol to ensure that we propagate taint. 182 if (State->isTainted(RHS) || State->isTainted(LHS)) { 183 const SymExpr *symLHS; 184 const SymExpr *symRHS; 185 186 if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS)) { 187 symLHS = LHS.getAsSymExpr(); 188 return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy); 189 } 190 191 if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS)) { 192 symRHS = RHS.getAsSymExpr(); 193 return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy); 194 } 195 196 symLHS = LHS.getAsSymExpr(); 197 symRHS = RHS.getAsSymExpr(); 198 return makeNonLoc(symLHS, Op, symRHS, ResultTy); 199 } 200 return UnknownVal(); 201 } 202 203 204 SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 205 SVal lhs, SVal rhs, QualType type) { 206 207 if (lhs.isUndef() || rhs.isUndef()) 208 return UndefinedVal(); 209 210 if (lhs.isUnknown() || rhs.isUnknown()) 211 return UnknownVal(); 212 213 if (isa<Loc>(lhs)) { 214 if (isa<Loc>(rhs)) 215 return evalBinOpLL(state, op, cast<Loc>(lhs), cast<Loc>(rhs), type); 216 217 return evalBinOpLN(state, op, cast<Loc>(lhs), cast<NonLoc>(rhs), type); 218 } 219 220 if (isa<Loc>(rhs)) { 221 // Support pointer arithmetic where the addend is on the left 222 // and the pointer on the right. 223 assert(op == BO_Add); 224 225 // Commute the operands. 226 return evalBinOpLN(state, op, cast<Loc>(rhs), cast<NonLoc>(lhs), type); 227 } 228 229 return evalBinOpNN(state, op, cast<NonLoc>(lhs), cast<NonLoc>(rhs), type); 230 } 231 232 DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state, 233 DefinedOrUnknownSVal lhs, 234 DefinedOrUnknownSVal rhs) { 235 return cast<DefinedOrUnknownSVal>(evalBinOp(state, BO_EQ, lhs, rhs, 236 Context.IntTy)); 237 } 238 239 /// Recursively check if the pointer types are equal modulo const, volatile, 240 /// and restrict qualifiers. Assumes the input types are canonical. 241 /// TODO: This is based off of code in SemaCast; can we reuse it. 242 static bool haveSimilarTypes(ASTContext &Context, QualType T1, 243 QualType T2) { 244 while (Context.UnwrapSimilarPointerTypes(T1, T2)) { 245 Qualifiers Quals1, Quals2; 246 T1 = Context.getUnqualifiedArrayType(T1, Quals1); 247 T2 = Context.getUnqualifiedArrayType(T2, Quals2); 248 249 // Make sure that non cvr-qualifiers the other qualifiers (e.g., address 250 // spaces) are identical. 251 Quals1.removeCVRQualifiers(); 252 Quals2.removeCVRQualifiers(); 253 if (Quals1 != Quals2) 254 return false; 255 } 256 257 if (T1 != T2) 258 return false; 259 260 return true; 261 } 262 263 // FIXME: should rewrite according to the cast kind. 264 SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { 265 castTy = Context.getCanonicalType(castTy); 266 originalTy = Context.getCanonicalType(originalTy); 267 if (val.isUnknownOrUndef() || castTy == originalTy) 268 return val; 269 270 // For const casts, just propagate the value. 271 if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType()) 272 if (haveSimilarTypes(Context, Context.getPointerType(castTy), 273 Context.getPointerType(originalTy))) 274 return val; 275 276 // Check for casts from pointers to integers. 277 if (castTy->isIntegerType() && Loc::isLocType(originalTy)) 278 return evalCastFromLoc(cast<Loc>(val), castTy); 279 280 // Check for casts from integers to pointers. 281 if (Loc::isLocType(castTy) && originalTy->isIntegerType()) { 282 if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) { 283 if (const MemRegion *R = LV->getLoc().getAsRegion()) { 284 StoreManager &storeMgr = StateMgr.getStoreManager(); 285 R = storeMgr.castRegion(R, castTy); 286 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); 287 } 288 return LV->getLoc(); 289 } 290 return dispatchCast(val, castTy); 291 } 292 293 // Just pass through function and block pointers. 294 if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) { 295 assert(Loc::isLocType(castTy)); 296 return val; 297 } 298 299 // Check for casts from array type to another type. 300 if (originalTy->isArrayType()) { 301 // We will always decay to a pointer. 302 val = StateMgr.ArrayToPointer(cast<Loc>(val)); 303 304 // Are we casting from an array to a pointer? If so just pass on 305 // the decayed value. 306 if (castTy->isPointerType()) 307 return val; 308 309 // Are we casting from an array to an integer? If so, cast the decayed 310 // pointer value to an integer. 311 assert(castTy->isIntegerType()); 312 313 // FIXME: Keep these here for now in case we decide soon that we 314 // need the original decayed type. 315 // QualType elemTy = cast<ArrayType>(originalTy)->getElementType(); 316 // QualType pointerTy = C.getPointerType(elemTy); 317 return evalCastFromLoc(cast<Loc>(val), castTy); 318 } 319 320 // Check for casts from a region to a specific type. 321 if (const MemRegion *R = val.getAsRegion()) { 322 // FIXME: We should handle the case where we strip off view layers to get 323 // to a desugared type. 324 325 if (!Loc::isLocType(castTy)) { 326 // FIXME: There can be gross cases where one casts the result of a function 327 // (that returns a pointer) to some other value that happens to fit 328 // within that pointer value. We currently have no good way to 329 // model such operations. When this happens, the underlying operation 330 // is that the caller is reasoning about bits. Conceptually we are 331 // layering a "view" of a location on top of those bits. Perhaps 332 // we need to be more lazy about mutual possible views, even on an 333 // SVal? This may be necessary for bit-level reasoning as well. 334 return UnknownVal(); 335 } 336 337 // We get a symbolic function pointer for a dereference of a function 338 // pointer, but it is of function type. Example: 339 340 // struct FPRec { 341 // void (*my_func)(int * x); 342 // }; 343 // 344 // int bar(int x); 345 // 346 // int f1_a(struct FPRec* foo) { 347 // int x; 348 // (*foo->my_func)(&x); 349 // return bar(x)+1; // no-warning 350 // } 351 352 assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() || 353 originalTy->isBlockPointerType() || castTy->isReferenceType()); 354 355 StoreManager &storeMgr = StateMgr.getStoreManager(); 356 357 // Delegate to store manager to get the result of casting a region to a 358 // different type. If the MemRegion* returned is NULL, this expression 359 // Evaluates to UnknownVal. 360 R = storeMgr.castRegion(R, castTy); 361 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); 362 } 363 364 return dispatchCast(val, castTy); 365 } 366