Home | History | Annotate | Download | only in Core
      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/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
     16 #include "clang/AST/DeclCXX.h"
     17 #include "clang/AST/ExprCXX.h"
     18 #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
     19 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
     20 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
     21 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
     22 
     23 using namespace clang;
     24 using namespace ento;
     25 
     26 //===----------------------------------------------------------------------===//
     27 // Basic SVal creation.
     28 //===----------------------------------------------------------------------===//
     29 
     30 void SValBuilder::anchor() { }
     31 
     32 DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) {
     33   if (Loc::isLocType(type))
     34     return makeNull();
     35 
     36   if (type->isIntegralOrEnumerationType())
     37     return makeIntVal(0, type);
     38 
     39   // FIXME: Handle floats.
     40   // FIXME: Handle structs.
     41   return UnknownVal();
     42 }
     43 
     44 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
     45                                 const llvm::APSInt& rhs, QualType type) {
     46   // The Environment ensures we always get a persistent APSInt in
     47   // BasicValueFactory, so we don't need to get the APSInt from
     48   // BasicValueFactory again.
     49   assert(lhs);
     50   assert(!Loc::isLocType(type));
     51   return nonloc::SymbolVal(SymMgr.getSymIntExpr(lhs, op, rhs, type));
     52 }
     53 
     54 NonLoc SValBuilder::makeNonLoc(const llvm::APSInt& lhs,
     55                                BinaryOperator::Opcode op, const SymExpr *rhs,
     56                                QualType type) {
     57   assert(rhs);
     58   assert(!Loc::isLocType(type));
     59   return nonloc::SymbolVal(SymMgr.getIntSymExpr(lhs, op, rhs, type));
     60 }
     61 
     62 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
     63                                const SymExpr *rhs, QualType type) {
     64   assert(lhs && rhs);
     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 (Optional<nonloc::ConcreteInt> CI = val.getAs<nonloc::ConcreteInt>()) {
     82     const llvm::APSInt& I = CI->getValue();
     83     if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
     84       return val;
     85   }
     86 
     87   return evalCastFromNonLoc(val.castAs<NonLoc>(), 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::conjureSymbolVal(const void *SymbolTag,
    110                                                    const Expr *Ex,
    111                                                    const LocationContext *LCtx,
    112                                                    unsigned Count) {
    113   QualType T = Ex->getType();
    114 
    115   // Compute the type of the result. If the expression is not an R-value, the
    116   // result should be a location.
    117   QualType ExType = Ex->getType();
    118   if (Ex->isGLValue())
    119     T = LCtx->getAnalysisDeclContext()->getASTContext().getPointerType(ExType);
    120 
    121   return conjureSymbolVal(SymbolTag, Ex, LCtx, T, Count);
    122 }
    123 
    124 DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *symbolTag,
    125                                                    const Expr *expr,
    126                                                    const LocationContext *LCtx,
    127                                                    QualType type,
    128                                                    unsigned count) {
    129   if (!SymbolManager::canSymbolicate(type))
    130     return UnknownVal();
    131 
    132   SymbolRef sym = SymMgr.conjureSymbol(expr, LCtx, type, count, symbolTag);
    133 
    134   if (Loc::isLocType(type))
    135     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
    136 
    137   return nonloc::SymbolVal(sym);
    138 }
    139 
    140 
    141 DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const Stmt *stmt,
    142                                                    const LocationContext *LCtx,
    143                                                    QualType type,
    144                                                    unsigned visitCount) {
    145   if (!SymbolManager::canSymbolicate(type))
    146     return UnknownVal();
    147 
    148   SymbolRef sym = SymMgr.conjureSymbol(stmt, LCtx, type, visitCount);
    149 
    150   if (Loc::isLocType(type))
    151     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
    152 
    153   return nonloc::SymbolVal(sym);
    154 }
    155 
    156 DefinedOrUnknownSVal
    157 SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
    158                                       const LocationContext *LCtx,
    159                                       unsigned VisitCount) {
    160   QualType T = E->getType();
    161   assert(Loc::isLocType(T));
    162   assert(SymbolManager::canSymbolicate(T));
    163 
    164   SymbolRef sym = SymMgr.conjureSymbol(E, LCtx, T, VisitCount);
    165   return loc::MemRegionVal(MemMgr.getSymbolicHeapRegion(sym));
    166 }
    167 
    168 DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag,
    169                                               const MemRegion *region,
    170                                               const Expr *expr, QualType type,
    171                                               unsigned count) {
    172   assert(SymbolManager::canSymbolicate(type) && "Invalid metadata symbol type");
    173 
    174   SymbolRef sym =
    175       SymMgr.getMetadataSymbol(region, expr, type, count, symbolTag);
    176 
    177   if (Loc::isLocType(type))
    178     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
    179 
    180   return nonloc::SymbolVal(sym);
    181 }
    182 
    183 DefinedOrUnknownSVal
    184 SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
    185                                              const TypedValueRegion *region) {
    186   QualType T = region->getValueType();
    187 
    188   if (!SymbolManager::canSymbolicate(T))
    189     return UnknownVal();
    190 
    191   SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, region);
    192 
    193   if (Loc::isLocType(T))
    194     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
    195 
    196   return nonloc::SymbolVal(sym);
    197 }
    198 
    199 DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) {
    200   return loc::MemRegionVal(MemMgr.getFunctionTextRegion(func));
    201 }
    202 
    203 DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
    204                                          CanQualType locTy,
    205                                          const LocationContext *locContext) {
    206   const BlockTextRegion *BC =
    207     MemMgr.getBlockTextRegion(block, locTy, locContext->getAnalysisDeclContext());
    208   const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext);
    209   return loc::MemRegionVal(BD);
    210 }
    211 
    212 /// Return a memory region for the 'this' object reference.
    213 loc::MemRegionVal SValBuilder::getCXXThis(const CXXMethodDecl *D,
    214                                           const StackFrameContext *SFC) {
    215   return loc::MemRegionVal(getRegionManager().
    216                            getCXXThisRegion(D->getThisType(getContext()), SFC));
    217 }
    218 
    219 /// Return a memory region for the 'this' object reference.
    220 loc::MemRegionVal SValBuilder::getCXXThis(const CXXRecordDecl *D,
    221                                           const StackFrameContext *SFC) {
    222   const Type *T = D->getTypeForDecl();
    223   QualType PT = getContext().getPointerType(QualType(T, 0));
    224   return loc::MemRegionVal(getRegionManager().getCXXThisRegion(PT, SFC));
    225 }
    226 
    227 Optional<SVal> SValBuilder::getConstantVal(const Expr *E) {
    228   E = E->IgnoreParens();
    229 
    230   switch (E->getStmtClass()) {
    231   // Handle expressions that we treat differently from the AST's constant
    232   // evaluator.
    233   case Stmt::AddrLabelExprClass:
    234     return makeLoc(cast<AddrLabelExpr>(E));
    235 
    236   case Stmt::CXXScalarValueInitExprClass:
    237   case Stmt::ImplicitValueInitExprClass:
    238     return makeZeroVal(E->getType());
    239 
    240   case Stmt::ObjCStringLiteralClass: {
    241     const ObjCStringLiteral *SL = cast<ObjCStringLiteral>(E);
    242     return makeLoc(getRegionManager().getObjCStringRegion(SL));
    243   }
    244 
    245   case Stmt::StringLiteralClass: {
    246     const StringLiteral *SL = cast<StringLiteral>(E);
    247     return makeLoc(getRegionManager().getStringRegion(SL));
    248   }
    249 
    250   // Fast-path some expressions to avoid the overhead of going through the AST's
    251   // constant evaluator
    252   case Stmt::CharacterLiteralClass: {
    253     const CharacterLiteral *C = cast<CharacterLiteral>(E);
    254     return makeIntVal(C->getValue(), C->getType());
    255   }
    256 
    257   case Stmt::CXXBoolLiteralExprClass:
    258     return makeBoolVal(cast<CXXBoolLiteralExpr>(E));
    259 
    260   case Stmt::IntegerLiteralClass:
    261     return makeIntVal(cast<IntegerLiteral>(E));
    262 
    263   case Stmt::ObjCBoolLiteralExprClass:
    264     return makeBoolVal(cast<ObjCBoolLiteralExpr>(E));
    265 
    266   case Stmt::CXXNullPtrLiteralExprClass:
    267     return makeNull();
    268 
    269   case Stmt::ImplicitCastExprClass: {
    270     const CastExpr *CE = cast<CastExpr>(E);
    271     if (CE->getCastKind() == CK_ArrayToPointerDecay) {
    272       Optional<SVal> ArrayVal = getConstantVal(CE->getSubExpr());
    273       if (!ArrayVal)
    274         return None;
    275       return evalCast(*ArrayVal, CE->getType(), CE->getSubExpr()->getType());
    276     }
    277     // FALLTHROUGH
    278   }
    279 
    280   // If we don't have a special case, fall back to the AST's constant evaluator.
    281   default: {
    282     // Don't try to come up with a value for materialized temporaries.
    283     if (E->isGLValue())
    284       return None;
    285 
    286     ASTContext &Ctx = getContext();
    287     llvm::APSInt Result;
    288     if (E->EvaluateAsInt(Result, Ctx))
    289       return makeIntVal(Result);
    290 
    291     if (Loc::isLocType(E->getType()))
    292       if (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull))
    293         return makeNull();
    294 
    295     return None;
    296   }
    297   }
    298 }
    299 
    300 //===----------------------------------------------------------------------===//
    301 
    302 SVal SValBuilder::makeSymExprValNN(ProgramStateRef State,
    303                                    BinaryOperator::Opcode Op,
    304                                    NonLoc LHS, NonLoc RHS,
    305                                    QualType ResultTy) {
    306   if (!State->isTainted(RHS) && !State->isTainted(LHS))
    307     return UnknownVal();
    308 
    309   const SymExpr *symLHS = LHS.getAsSymExpr();
    310   const SymExpr *symRHS = RHS.getAsSymExpr();
    311   // TODO: When the Max Complexity is reached, we should conjure a symbol
    312   // instead of generating an Unknown value and propagate the taint info to it.
    313   const unsigned MaxComp = 10000; // 100000 28X
    314 
    315   if (symLHS && symRHS &&
    316       (symLHS->computeComplexity() + symRHS->computeComplexity()) <  MaxComp)
    317     return makeNonLoc(symLHS, Op, symRHS, ResultTy);
    318 
    319   if (symLHS && symLHS->computeComplexity() < MaxComp)
    320     if (Optional<nonloc::ConcreteInt> rInt = RHS.getAs<nonloc::ConcreteInt>())
    321       return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
    322 
    323   if (symRHS && symRHS->computeComplexity() < MaxComp)
    324     if (Optional<nonloc::ConcreteInt> lInt = LHS.getAs<nonloc::ConcreteInt>())
    325       return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
    326 
    327   return UnknownVal();
    328 }
    329 
    330 
    331 SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
    332                             SVal lhs, SVal rhs, QualType type) {
    333 
    334   if (lhs.isUndef() || rhs.isUndef())
    335     return UndefinedVal();
    336 
    337   if (lhs.isUnknown() || rhs.isUnknown())
    338     return UnknownVal();
    339 
    340   if (Optional<Loc> LV = lhs.getAs<Loc>()) {
    341     if (Optional<Loc> RV = rhs.getAs<Loc>())
    342       return evalBinOpLL(state, op, *LV, *RV, type);
    343 
    344     return evalBinOpLN(state, op, *LV, rhs.castAs<NonLoc>(), type);
    345   }
    346 
    347   if (Optional<Loc> RV = rhs.getAs<Loc>()) {
    348     // Support pointer arithmetic where the addend is on the left
    349     // and the pointer on the right.
    350     assert(op == BO_Add);
    351 
    352     // Commute the operands.
    353     return evalBinOpLN(state, op, *RV, lhs.castAs<NonLoc>(), type);
    354   }
    355 
    356   return evalBinOpNN(state, op, lhs.castAs<NonLoc>(), rhs.castAs<NonLoc>(),
    357                      type);
    358 }
    359 
    360 DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
    361                                          DefinedOrUnknownSVal lhs,
    362                                          DefinedOrUnknownSVal rhs) {
    363   return evalBinOp(state, BO_EQ, lhs, rhs, Context.IntTy)
    364       .castAs<DefinedOrUnknownSVal>();
    365 }
    366 
    367 /// Recursively check if the pointer types are equal modulo const, volatile,
    368 /// and restrict qualifiers. Also, assume that all types are similar to 'void'.
    369 /// Assumes the input types are canonical.
    370 static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy,
    371                                                          QualType FromTy) {
    372   while (Context.UnwrapSimilarPointerTypes(ToTy, FromTy)) {
    373     Qualifiers Quals1, Quals2;
    374     ToTy = Context.getUnqualifiedArrayType(ToTy, Quals1);
    375     FromTy = Context.getUnqualifiedArrayType(FromTy, Quals2);
    376 
    377     // Make sure that non cvr-qualifiers the other qualifiers (e.g., address
    378     // spaces) are identical.
    379     Quals1.removeCVRQualifiers();
    380     Quals2.removeCVRQualifiers();
    381     if (Quals1 != Quals2)
    382       return false;
    383   }
    384 
    385   // If we are casting to void, the 'From' value can be used to represent the
    386   // 'To' value.
    387   if (ToTy->isVoidType())
    388     return true;
    389 
    390   if (ToTy != FromTy)
    391     return false;
    392 
    393   return true;
    394 }
    395 
    396 // FIXME: should rewrite according to the cast kind.
    397 SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
    398   castTy = Context.getCanonicalType(castTy);
    399   originalTy = Context.getCanonicalType(originalTy);
    400   if (val.isUnknownOrUndef() || castTy == originalTy)
    401     return val;
    402 
    403   if (castTy->isBooleanType()) {
    404     if (val.isUnknownOrUndef())
    405       return val;
    406     if (val.isConstant())
    407       return makeTruthVal(!val.isZeroConstant(), castTy);
    408     if (SymbolRef Sym = val.getAsSymbol()) {
    409       BasicValueFactory &BVF = getBasicValueFactory();
    410       // FIXME: If we had a state here, we could see if the symbol is known to
    411       // be zero, but we don't.
    412       return makeNonLoc(Sym, BO_NE, BVF.getValue(0, Sym->getType()), castTy);
    413     }
    414 
    415     assert(val.getAs<Loc>() || val.getAs<nonloc::LocAsInteger>());
    416     return makeTruthVal(true, castTy);
    417   }
    418 
    419   // For const casts, casts to void, just propagate the value.
    420   if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
    421     if (shouldBeModeledWithNoOp(Context, Context.getPointerType(castTy),
    422                                          Context.getPointerType(originalTy)))
    423       return val;
    424 
    425   // Check for casts from pointers to integers.
    426   if (castTy->isIntegralOrEnumerationType() && Loc::isLocType(originalTy))
    427     return evalCastFromLoc(val.castAs<Loc>(), castTy);
    428 
    429   // Check for casts from integers to pointers.
    430   if (Loc::isLocType(castTy) && originalTy->isIntegralOrEnumerationType()) {
    431     if (Optional<nonloc::LocAsInteger> LV = val.getAs<nonloc::LocAsInteger>()) {
    432       if (const MemRegion *R = LV->getLoc().getAsRegion()) {
    433         StoreManager &storeMgr = StateMgr.getStoreManager();
    434         R = storeMgr.castRegion(R, castTy);
    435         return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
    436       }
    437       return LV->getLoc();
    438     }
    439     return dispatchCast(val, castTy);
    440   }
    441 
    442   // Just pass through function and block pointers.
    443   if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
    444     assert(Loc::isLocType(castTy));
    445     return val;
    446   }
    447 
    448   // Check for casts from array type to another type.
    449   if (const ArrayType *arrayT =
    450                       dyn_cast<ArrayType>(originalTy.getCanonicalType())) {
    451     // We will always decay to a pointer.
    452     QualType elemTy = arrayT->getElementType();
    453     val = StateMgr.ArrayToPointer(val.castAs<Loc>(), elemTy);
    454 
    455     // Are we casting from an array to a pointer?  If so just pass on
    456     // the decayed value.
    457     if (castTy->isPointerType() || castTy->isReferenceType())
    458       return val;
    459 
    460     // Are we casting from an array to an integer?  If so, cast the decayed
    461     // pointer value to an integer.
    462     assert(castTy->isIntegralOrEnumerationType());
    463 
    464     // FIXME: Keep these here for now in case we decide soon that we
    465     // need the original decayed type.
    466     //    QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
    467     //    QualType pointerTy = C.getPointerType(elemTy);
    468     return evalCastFromLoc(val.castAs<Loc>(), castTy);
    469   }
    470 
    471   // Check for casts from a region to a specific type.
    472   if (const MemRegion *R = val.getAsRegion()) {
    473     // Handle other casts of locations to integers.
    474     if (castTy->isIntegralOrEnumerationType())
    475       return evalCastFromLoc(loc::MemRegionVal(R), castTy);
    476 
    477     // FIXME: We should handle the case where we strip off view layers to get
    478     //  to a desugared type.
    479     if (!Loc::isLocType(castTy)) {
    480       // FIXME: There can be gross cases where one casts the result of a function
    481       // (that returns a pointer) to some other value that happens to fit
    482       // within that pointer value.  We currently have no good way to
    483       // model such operations.  When this happens, the underlying operation
    484       // is that the caller is reasoning about bits.  Conceptually we are
    485       // layering a "view" of a location on top of those bits.  Perhaps
    486       // we need to be more lazy about mutual possible views, even on an
    487       // SVal?  This may be necessary for bit-level reasoning as well.
    488       return UnknownVal();
    489     }
    490 
    491     // We get a symbolic function pointer for a dereference of a function
    492     // pointer, but it is of function type. Example:
    493 
    494     //  struct FPRec {
    495     //    void (*my_func)(int * x);
    496     //  };
    497     //
    498     //  int bar(int x);
    499     //
    500     //  int f1_a(struct FPRec* foo) {
    501     //    int x;
    502     //    (*foo->my_func)(&x);
    503     //    return bar(x)+1; // no-warning
    504     //  }
    505 
    506     assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() ||
    507            originalTy->isBlockPointerType() || castTy->isReferenceType());
    508 
    509     StoreManager &storeMgr = StateMgr.getStoreManager();
    510 
    511     // Delegate to store manager to get the result of casting a region to a
    512     // different type.  If the MemRegion* returned is NULL, this expression
    513     // Evaluates to UnknownVal.
    514     R = storeMgr.castRegion(R, castTy);
    515     return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
    516   }
    517 
    518   return dispatchCast(val, castTy);
    519 }
    520