clang API Documentation

SValBuilder.cpp
Go to the documentation of this file.
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 }