clang API Documentation
00001 // SValBuilder.cpp - Basic class for all SValBuilder implementations -*- C++ -*- 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines SValBuilder, the base class for all (complete) SValBuilder 00011 // implementations. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/AST/ExprCXX.h" 00016 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 00017 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 00018 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" 00019 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 00020 #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h" 00021 00022 using namespace clang; 00023 using namespace ento; 00024 00025 //===----------------------------------------------------------------------===// 00026 // Basic SVal creation. 00027 //===----------------------------------------------------------------------===// 00028 00029 void SValBuilder::anchor() { } 00030 00031 DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) { 00032 if (Loc::isLocType(type)) 00033 return makeNull(); 00034 00035 if (type->isIntegerType()) 00036 return makeIntVal(0, type); 00037 00038 // FIXME: Handle floats. 00039 // FIXME: Handle structs. 00040 return UnknownVal(); 00041 } 00042 00043 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, 00044 const llvm::APSInt& rhs, QualType type) { 00045 // The Environment ensures we always get a persistent APSInt in 00046 // BasicValueFactory, so we don't need to get the APSInt from 00047 // BasicValueFactory again. 00048 assert(lhs); 00049 assert(!Loc::isLocType(type)); 00050 return nonloc::SymbolVal(SymMgr.getSymIntExpr(lhs, op, rhs, type)); 00051 } 00052 00053 NonLoc SValBuilder::makeNonLoc(const llvm::APSInt& lhs, 00054 BinaryOperator::Opcode op, const SymExpr *rhs, 00055 QualType type) { 00056 assert(rhs); 00057 assert(!Loc::isLocType(type)); 00058 return nonloc::SymbolVal(SymMgr.getIntSymExpr(lhs, op, rhs, type)); 00059 } 00060 00061 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, 00062 const SymExpr *rhs, QualType type) { 00063 assert(lhs && rhs); 00064 assert(!Loc::isLocType(type)); 00065 return nonloc::SymbolVal(SymMgr.getSymSymExpr(lhs, op, rhs, type)); 00066 } 00067 00068 NonLoc SValBuilder::makeNonLoc(const SymExpr *operand, 00069 QualType fromTy, QualType toTy) { 00070 assert(operand); 00071 assert(!Loc::isLocType(toTy)); 00072 return nonloc::SymbolVal(SymMgr.getCastSymbol(operand, fromTy, toTy)); 00073 } 00074 00075 SVal SValBuilder::convertToArrayIndex(SVal val) { 00076 if (val.isUnknownOrUndef()) 00077 return val; 00078 00079 // Common case: we have an appropriately sized integer. 00080 if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&val)) { 00081 const llvm::APSInt& I = CI->getValue(); 00082 if (I.getBitWidth() == ArrayIndexWidth && I.isSigned()) 00083 return val; 00084 } 00085 00086 return evalCastFromNonLoc(cast<NonLoc>(val), ArrayIndexTy); 00087 } 00088 00089 nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){ 00090 return makeTruthVal(boolean->getValue()); 00091 } 00092 00093 DefinedOrUnknownSVal 00094 SValBuilder::getRegionValueSymbolVal(const TypedValueRegion* region) { 00095 QualType T = region->getValueType(); 00096 00097 if (!SymbolManager::canSymbolicate(T)) 00098 return UnknownVal(); 00099 00100 SymbolRef sym = SymMgr.getRegionValueSymbol(region); 00101 00102 if (Loc::isLocType(T)) 00103 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 00104 00105 return nonloc::SymbolVal(sym); 00106 } 00107 00108 DefinedOrUnknownSVal 00109 SValBuilder::getConjuredSymbolVal(const void *symbolTag, 00110 const Expr *expr, 00111 const LocationContext *LCtx, 00112 unsigned count) { 00113 QualType T = expr->getType(); 00114 return getConjuredSymbolVal(symbolTag, expr, LCtx, T, count); 00115 } 00116 00117 DefinedOrUnknownSVal 00118 SValBuilder::getConjuredSymbolVal(const void *symbolTag, 00119 const Expr *expr, 00120 const LocationContext *LCtx, 00121 QualType type, 00122 unsigned count) { 00123 if (!SymbolManager::canSymbolicate(type)) 00124 return UnknownVal(); 00125 00126 SymbolRef sym = SymMgr.getConjuredSymbol(expr, LCtx, type, count, symbolTag); 00127 00128 if (Loc::isLocType(type)) 00129 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 00130 00131 return nonloc::SymbolVal(sym); 00132 } 00133 00134 00135 DefinedOrUnknownSVal 00136 SValBuilder::getConjuredSymbolVal(const Stmt *stmt, 00137 const LocationContext *LCtx, 00138 QualType type, 00139 unsigned visitCount) { 00140 if (!SymbolManager::canSymbolicate(type)) 00141 return UnknownVal(); 00142 00143 SymbolRef sym = SymMgr.getConjuredSymbol(stmt, LCtx, type, visitCount); 00144 00145 if (Loc::isLocType(type)) 00146 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 00147 00148 return nonloc::SymbolVal(sym); 00149 } 00150 00151 DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag, 00152 const MemRegion *region, 00153 const Expr *expr, QualType type, 00154 unsigned count) { 00155 assert(SymbolManager::canSymbolicate(type) && "Invalid metadata symbol type"); 00156 00157 SymbolRef sym = 00158 SymMgr.getMetadataSymbol(region, expr, type, count, symbolTag); 00159 00160 if (Loc::isLocType(type)) 00161 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 00162 00163 return nonloc::SymbolVal(sym); 00164 } 00165 00166 DefinedOrUnknownSVal 00167 SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, 00168 const TypedValueRegion *region) { 00169 QualType T = region->getValueType(); 00170 00171 if (!SymbolManager::canSymbolicate(T)) 00172 return UnknownVal(); 00173 00174 SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, region); 00175 00176 if (Loc::isLocType(T)) 00177 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 00178 00179 return nonloc::SymbolVal(sym); 00180 } 00181 00182 DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) { 00183 return loc::MemRegionVal(MemMgr.getFunctionTextRegion(func)); 00184 } 00185 00186 DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block, 00187 CanQualType locTy, 00188 const LocationContext *locContext) { 00189 const BlockTextRegion *BC = 00190 MemMgr.getBlockTextRegion(block, locTy, locContext->getAnalysisDeclContext()); 00191 const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext); 00192 return loc::MemRegionVal(BD); 00193 } 00194 00195 //===----------------------------------------------------------------------===// 00196 00197 SVal SValBuilder::makeSymExprValNN(ProgramStateRef State, 00198 BinaryOperator::Opcode Op, 00199 NonLoc LHS, NonLoc RHS, 00200 QualType ResultTy) { 00201 if (!State->isTainted(RHS) && !State->isTainted(LHS)) 00202 return UnknownVal(); 00203 00204 const SymExpr *symLHS = LHS.getAsSymExpr(); 00205 const SymExpr *symRHS = RHS.getAsSymExpr(); 00206 // TODO: When the Max Complexity is reached, we should conjure a symbol 00207 // instead of generating an Unknown value and propagate the taint info to it. 00208 const unsigned MaxComp = 10000; // 100000 28X 00209 00210 if (symLHS && symRHS && 00211 (symLHS->computeComplexity() + symRHS->computeComplexity()) < MaxComp) 00212 return makeNonLoc(symLHS, Op, symRHS, ResultTy); 00213 00214 if (symLHS && symLHS->computeComplexity() < MaxComp) 00215 if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS)) 00216 return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy); 00217 00218 if (symRHS && symRHS->computeComplexity() < MaxComp) 00219 if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS)) 00220 return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy); 00221 00222 return UnknownVal(); 00223 } 00224 00225 00226 SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 00227 SVal lhs, SVal rhs, QualType type) { 00228 00229 if (lhs.isUndef() || rhs.isUndef()) 00230 return UndefinedVal(); 00231 00232 if (lhs.isUnknown() || rhs.isUnknown()) 00233 return UnknownVal(); 00234 00235 if (isa<Loc>(lhs)) { 00236 if (isa<Loc>(rhs)) 00237 return evalBinOpLL(state, op, cast<Loc>(lhs), cast<Loc>(rhs), type); 00238 00239 return evalBinOpLN(state, op, cast<Loc>(lhs), cast<NonLoc>(rhs), type); 00240 } 00241 00242 if (isa<Loc>(rhs)) { 00243 // Support pointer arithmetic where the addend is on the left 00244 // and the pointer on the right. 00245 assert(op == BO_Add); 00246 00247 // Commute the operands. 00248 return evalBinOpLN(state, op, cast<Loc>(rhs), cast<NonLoc>(lhs), type); 00249 } 00250 00251 return evalBinOpNN(state, op, cast<NonLoc>(lhs), cast<NonLoc>(rhs), type); 00252 } 00253 00254 DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state, 00255 DefinedOrUnknownSVal lhs, 00256 DefinedOrUnknownSVal rhs) { 00257 return cast<DefinedOrUnknownSVal>(evalBinOp(state, BO_EQ, lhs, rhs, 00258 Context.IntTy)); 00259 } 00260 00261 /// Recursively check if the pointer types are equal modulo const, volatile, 00262 /// and restrict qualifiers. Assumes the input types are canonical. 00263 /// TODO: This is based off of code in SemaCast; can we reuse it. 00264 static bool haveSimilarTypes(ASTContext &Context, QualType T1, 00265 QualType T2) { 00266 while (Context.UnwrapSimilarPointerTypes(T1, T2)) { 00267 Qualifiers Quals1, Quals2; 00268 T1 = Context.getUnqualifiedArrayType(T1, Quals1); 00269 T2 = Context.getUnqualifiedArrayType(T2, Quals2); 00270 00271 // Make sure that non cvr-qualifiers the other qualifiers (e.g., address 00272 // spaces) are identical. 00273 Quals1.removeCVRQualifiers(); 00274 Quals2.removeCVRQualifiers(); 00275 if (Quals1 != Quals2) 00276 return false; 00277 } 00278 00279 if (T1 != T2) 00280 return false; 00281 00282 return true; 00283 } 00284 00285 // FIXME: should rewrite according to the cast kind. 00286 SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { 00287 castTy = Context.getCanonicalType(castTy); 00288 originalTy = Context.getCanonicalType(originalTy); 00289 if (val.isUnknownOrUndef() || castTy == originalTy) 00290 return val; 00291 00292 // For const casts, just propagate the value. 00293 if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType()) 00294 if (haveSimilarTypes(Context, Context.getPointerType(castTy), 00295 Context.getPointerType(originalTy))) 00296 return val; 00297 00298 // Check for casts from pointers to integers. 00299 if (castTy->isIntegerType() && Loc::isLocType(originalTy)) 00300 return evalCastFromLoc(cast<Loc>(val), castTy); 00301 00302 // Check for casts from integers to pointers. 00303 if (Loc::isLocType(castTy) && originalTy->isIntegerType()) { 00304 if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) { 00305 if (const MemRegion *R = LV->getLoc().getAsRegion()) { 00306 StoreManager &storeMgr = StateMgr.getStoreManager(); 00307 R = storeMgr.castRegion(R, castTy); 00308 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); 00309 } 00310 return LV->getLoc(); 00311 } 00312 return dispatchCast(val, castTy); 00313 } 00314 00315 // Just pass through function and block pointers. 00316 if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) { 00317 assert(Loc::isLocType(castTy)); 00318 return val; 00319 } 00320 00321 // Check for casts from array type to another type. 00322 if (originalTy->isArrayType()) { 00323 // We will always decay to a pointer. 00324 val = StateMgr.ArrayToPointer(cast<Loc>(val)); 00325 00326 // Are we casting from an array to a pointer? If so just pass on 00327 // the decayed value. 00328 if (castTy->isPointerType()) 00329 return val; 00330 00331 // Are we casting from an array to an integer? If so, cast the decayed 00332 // pointer value to an integer. 00333 assert(castTy->isIntegerType()); 00334 00335 // FIXME: Keep these here for now in case we decide soon that we 00336 // need the original decayed type. 00337 // QualType elemTy = cast<ArrayType>(originalTy)->getElementType(); 00338 // QualType pointerTy = C.getPointerType(elemTy); 00339 return evalCastFromLoc(cast<Loc>(val), castTy); 00340 } 00341 00342 // Check for casts from a region to a specific type. 00343 if (const MemRegion *R = val.getAsRegion()) { 00344 // Handle other casts of locations to integers. 00345 if (castTy->isIntegerType()) 00346 return evalCastFromLoc(loc::MemRegionVal(R), castTy); 00347 00348 // FIXME: We should handle the case where we strip off view layers to get 00349 // to a desugared type. 00350 if (!Loc::isLocType(castTy)) { 00351 // FIXME: There can be gross cases where one casts the result of a function 00352 // (that returns a pointer) to some other value that happens to fit 00353 // within that pointer value. We currently have no good way to 00354 // model such operations. When this happens, the underlying operation 00355 // is that the caller is reasoning about bits. Conceptually we are 00356 // layering a "view" of a location on top of those bits. Perhaps 00357 // we need to be more lazy about mutual possible views, even on an 00358 // SVal? This may be necessary for bit-level reasoning as well. 00359 return UnknownVal(); 00360 } 00361 00362 // We get a symbolic function pointer for a dereference of a function 00363 // pointer, but it is of function type. Example: 00364 00365 // struct FPRec { 00366 // void (*my_func)(int * x); 00367 // }; 00368 // 00369 // int bar(int x); 00370 // 00371 // int f1_a(struct FPRec* foo) { 00372 // int x; 00373 // (*foo->my_func)(&x); 00374 // return bar(x)+1; // no-warning 00375 // } 00376 00377 assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() || 00378 originalTy->isBlockPointerType() || castTy->isReferenceType()); 00379 00380 StoreManager &storeMgr = StateMgr.getStoreManager(); 00381 00382 // Delegate to store manager to get the result of casting a region to a 00383 // different type. If the MemRegion* returned is NULL, this expression 00384 // Evaluates to UnknownVal. 00385 R = storeMgr.castRegion(R, castTy); 00386 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); 00387 } 00388 00389 return dispatchCast(val, castTy); 00390 }