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                                          unsigned blockCount) {
    207   const BlockTextRegion *BC =
    208     MemMgr.getBlockTextRegion(block, locTy, locContext->getAnalysisDeclContext());
    209   const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext,
    210                                                         blockCount);
    211   return loc::MemRegionVal(BD);
    212 }
    213 
    214 /// Return a memory region for the 'this' object reference.
    215 loc::MemRegionVal SValBuilder::getCXXThis(const CXXMethodDecl *D,
    216                                           const StackFrameContext *SFC) {
    217   return loc::MemRegionVal(getRegionManager().
    218                            getCXXThisRegion(D->getThisType(getContext()), SFC));
    219 }
    220 
    221 /// Return a memory region for the 'this' object reference.
    222 loc::MemRegionVal SValBuilder::getCXXThis(const CXXRecordDecl *D,
    223                                           const StackFrameContext *SFC) {
    224   const Type *T = D->getTypeForDecl();
    225   QualType PT = getContext().getPointerType(QualType(T, 0));
    226   return loc::MemRegionVal(getRegionManager().getCXXThisRegion(PT, SFC));
    227 }
    228 
    229 Optional<SVal> SValBuilder::getConstantVal(const Expr *E) {
    230   E = E->IgnoreParens();
    231 
    232   switch (E->getStmtClass()) {
    233   // Handle expressions that we treat differently from the AST's constant
    234   // evaluator.
    235   case Stmt::AddrLabelExprClass:
    236     return makeLoc(cast<AddrLabelExpr>(E));
    237 
    238   case Stmt::CXXScalarValueInitExprClass:
    239   case Stmt::ImplicitValueInitExprClass:
    240     return makeZeroVal(E->getType());
    241 
    242   case Stmt::ObjCStringLiteralClass: {
    243     const ObjCStringLiteral *SL = cast<ObjCStringLiteral>(E);
    244     return makeLoc(getRegionManager().getObjCStringRegion(SL));
    245   }
    246 
    247   case Stmt::StringLiteralClass: {
    248     const StringLiteral *SL = cast<StringLiteral>(E);
    249     return makeLoc(getRegionManager().getStringRegion(SL));
    250   }
    251 
    252   // Fast-path some expressions to avoid the overhead of going through the AST's
    253   // constant evaluator
    254   case Stmt::CharacterLiteralClass: {
    255     const CharacterLiteral *C = cast<CharacterLiteral>(E);
    256     return makeIntVal(C->getValue(), C->getType());
    257   }
    258 
    259   case Stmt::CXXBoolLiteralExprClass:
    260     return makeBoolVal(cast<CXXBoolLiteralExpr>(E));
    261 
    262   case Stmt::IntegerLiteralClass:
    263     return makeIntVal(cast<IntegerLiteral>(E));
    264 
    265   case Stmt::ObjCBoolLiteralExprClass:
    266     return makeBoolVal(cast<ObjCBoolLiteralExpr>(E));
    267 
    268   case Stmt::CXXNullPtrLiteralExprClass:
    269     return makeNull();
    270 
    271   case Stmt::ImplicitCastExprClass: {
    272     const CastExpr *CE = cast<CastExpr>(E);
    273     if (CE->getCastKind() == CK_ArrayToPointerDecay) {
    274       Optional<SVal> ArrayVal = getConstantVal(CE->getSubExpr());
    275       if (!ArrayVal)
    276         return None;
    277       return evalCast(*ArrayVal, CE->getType(), CE->getSubExpr()->getType());
    278     }
    279     // FALLTHROUGH
    280   }
    281 
    282   // If we don't have a special case, fall back to the AST's constant evaluator.
    283   default: {
    284     // Don't try to come up with a value for materialized temporaries.
    285     if (E->isGLValue())
    286       return None;
    287 
    288     ASTContext &Ctx = getContext();
    289     llvm::APSInt Result;
    290     if (E->EvaluateAsInt(Result, Ctx))
    291       return makeIntVal(Result);
    292 
    293     if (Loc::isLocType(E->getType()))
    294       if (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull))
    295         return makeNull();
    296 
    297     return None;
    298   }
    299   }
    300 }
    301 
    302 //===----------------------------------------------------------------------===//
    303 
    304 SVal SValBuilder::makeSymExprValNN(ProgramStateRef State,
    305                                    BinaryOperator::Opcode Op,
    306                                    NonLoc LHS, NonLoc RHS,
    307                                    QualType ResultTy) {
    308   if (!State->isTainted(RHS) && !State->isTainted(LHS))
    309     return UnknownVal();
    310 
    311   const SymExpr *symLHS = LHS.getAsSymExpr();
    312   const SymExpr *symRHS = RHS.getAsSymExpr();
    313   // TODO: When the Max Complexity is reached, we should conjure a symbol
    314   // instead of generating an Unknown value and propagate the taint info to it.
    315   const unsigned MaxComp = 10000; // 100000 28X
    316 
    317   if (symLHS && symRHS &&
    318       (symLHS->computeComplexity() + symRHS->computeComplexity()) <  MaxComp)
    319     return makeNonLoc(symLHS, Op, symRHS, ResultTy);
    320 
    321   if (symLHS && symLHS->computeComplexity() < MaxComp)
    322     if (Optional<nonloc::ConcreteInt> rInt = RHS.getAs<nonloc::ConcreteInt>())
    323       return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
    324 
    325   if (symRHS && symRHS->computeComplexity() < MaxComp)
    326     if (Optional<nonloc::ConcreteInt> lInt = LHS.getAs<nonloc::ConcreteInt>())
    327       return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
    328 
    329   return UnknownVal();
    330 }
    331 
    332 
    333 SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
    334                             SVal lhs, SVal rhs, QualType type) {
    335 
    336   if (lhs.isUndef() || rhs.isUndef())
    337     return UndefinedVal();
    338 
    339   if (lhs.isUnknown() || rhs.isUnknown())
    340     return UnknownVal();
    341 
    342   if (Optional<Loc> LV = lhs.getAs<Loc>()) {
    343     if (Optional<Loc> RV = rhs.getAs<Loc>())
    344       return evalBinOpLL(state, op, *LV, *RV, type);
    345 
    346     return evalBinOpLN(state, op, *LV, rhs.castAs<NonLoc>(), type);
    347   }
    348 
    349   if (Optional<Loc> RV = rhs.getAs<Loc>()) {
    350     // Support pointer arithmetic where the addend is on the left
    351     // and the pointer on the right.
    352     assert(op == BO_Add);
    353 
    354     // Commute the operands.
    355     return evalBinOpLN(state, op, *RV, lhs.castAs<NonLoc>(), type);
    356   }
    357 
    358   return evalBinOpNN(state, op, lhs.castAs<NonLoc>(), rhs.castAs<NonLoc>(),
    359                      type);
    360 }
    361 
    362 DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
    363                                          DefinedOrUnknownSVal lhs,
    364                                          DefinedOrUnknownSVal rhs) {
    365   return evalBinOp(state, BO_EQ, lhs, rhs, getConditionType())
    366       .castAs<DefinedOrUnknownSVal>();
    367 }
    368 
    369 /// Recursively check if the pointer types are equal modulo const, volatile,
    370 /// and restrict qualifiers. Also, assume that all types are similar to 'void'.
    371 /// Assumes the input types are canonical.
    372 static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy,
    373                                                          QualType FromTy) {
    374   while (Context.UnwrapSimilarPointerTypes(ToTy, FromTy)) {
    375     Qualifiers Quals1, Quals2;
    376     ToTy = Context.getUnqualifiedArrayType(ToTy, Quals1);
    377     FromTy = Context.getUnqualifiedArrayType(FromTy, Quals2);
    378 
    379     // Make sure that non-cvr-qualifiers the other qualifiers (e.g., address
    380     // spaces) are identical.
    381     Quals1.removeCVRQualifiers();
    382     Quals2.removeCVRQualifiers();
    383     if (Quals1 != Quals2)
    384       return false;
    385   }
    386 
    387   // If we are casting to void, the 'From' value can be used to represent the
    388   // 'To' value.
    389   if (ToTy->isVoidType())
    390     return true;
    391 
    392   if (ToTy != FromTy)
    393     return false;
    394 
    395   return true;
    396 }
    397 
    398 // FIXME: should rewrite according to the cast kind.
    399 SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
    400   castTy = Context.getCanonicalType(castTy);
    401   originalTy = Context.getCanonicalType(originalTy);
    402   if (val.isUnknownOrUndef() || castTy == originalTy)
    403     return val;
    404 
    405   if (castTy->isBooleanType()) {
    406     if (val.isUnknownOrUndef())
    407       return val;
    408     if (val.isConstant())
    409       return makeTruthVal(!val.isZeroConstant(), castTy);
    410     if (!Loc::isLocType(originalTy) &&
    411         !originalTy->isIntegralOrEnumerationType() &&
    412         !originalTy->isMemberPointerType())
    413       return UnknownVal();
    414     if (SymbolRef Sym = val.getAsSymbol(true)) {
    415       BasicValueFactory &BVF = getBasicValueFactory();
    416       // FIXME: If we had a state here, we could see if the symbol is known to
    417       // be zero, but we don't.
    418       return makeNonLoc(Sym, BO_NE, BVF.getValue(0, Sym->getType()), castTy);
    419     }
    420     // Loc values are not always true, they could be weakly linked functions.
    421     if (Optional<Loc> L = val.getAs<Loc>())
    422       return evalCastFromLoc(*L, castTy);
    423 
    424     Loc L = val.castAs<nonloc::LocAsInteger>().getLoc();
    425     return evalCastFromLoc(L, castTy);
    426   }
    427 
    428   // For const casts, casts to void, just propagate the value.
    429   if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
    430     if (shouldBeModeledWithNoOp(Context, Context.getPointerType(castTy),
    431                                          Context.getPointerType(originalTy)))
    432       return val;
    433 
    434   // Check for casts from pointers to integers.
    435   if (castTy->isIntegralOrEnumerationType() && Loc::isLocType(originalTy))
    436     return evalCastFromLoc(val.castAs<Loc>(), castTy);
    437 
    438   // Check for casts from integers to pointers.
    439   if (Loc::isLocType(castTy) && originalTy->isIntegralOrEnumerationType()) {
    440     if (Optional<nonloc::LocAsInteger> LV = val.getAs<nonloc::LocAsInteger>()) {
    441       if (const MemRegion *R = LV->getLoc().getAsRegion()) {
    442         StoreManager &storeMgr = StateMgr.getStoreManager();
    443         R = storeMgr.castRegion(R, castTy);
    444         return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
    445       }
    446       return LV->getLoc();
    447     }
    448     return dispatchCast(val, castTy);
    449   }
    450 
    451   // Just pass through function and block pointers.
    452   if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
    453     assert(Loc::isLocType(castTy));
    454     return val;
    455   }
    456 
    457   // Check for casts from array type to another type.
    458   if (const ArrayType *arrayT =
    459                       dyn_cast<ArrayType>(originalTy.getCanonicalType())) {
    460     // We will always decay to a pointer.
    461     QualType elemTy = arrayT->getElementType();
    462     val = StateMgr.ArrayToPointer(val.castAs<Loc>(), elemTy);
    463 
    464     // Are we casting from an array to a pointer?  If so just pass on
    465     // the decayed value.
    466     if (castTy->isPointerType() || castTy->isReferenceType())
    467       return val;
    468 
    469     // Are we casting from an array to an integer?  If so, cast the decayed
    470     // pointer value to an integer.
    471     assert(castTy->isIntegralOrEnumerationType());
    472 
    473     // FIXME: Keep these here for now in case we decide soon that we
    474     // need the original decayed type.
    475     //    QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
    476     //    QualType pointerTy = C.getPointerType(elemTy);
    477     return evalCastFromLoc(val.castAs<Loc>(), castTy);
    478   }
    479 
    480   // Check for casts from a region to a specific type.
    481   if (const MemRegion *R = val.getAsRegion()) {
    482     // Handle other casts of locations to integers.
    483     if (castTy->isIntegralOrEnumerationType())
    484       return evalCastFromLoc(loc::MemRegionVal(R), castTy);
    485 
    486     // FIXME: We should handle the case where we strip off view layers to get
    487     //  to a desugared type.
    488     if (!Loc::isLocType(castTy)) {
    489       // FIXME: There can be gross cases where one casts the result of a function
    490       // (that returns a pointer) to some other value that happens to fit
    491       // within that pointer value.  We currently have no good way to
    492       // model such operations.  When this happens, the underlying operation
    493       // is that the caller is reasoning about bits.  Conceptually we are
    494       // layering a "view" of a location on top of those bits.  Perhaps
    495       // we need to be more lazy about mutual possible views, even on an
    496       // SVal?  This may be necessary for bit-level reasoning as well.
    497       return UnknownVal();
    498     }
    499 
    500     // We get a symbolic function pointer for a dereference of a function
    501     // pointer, but it is of function type. Example:
    502 
    503     //  struct FPRec {
    504     //    void (*my_func)(int * x);
    505     //  };
    506     //
    507     //  int bar(int x);
    508     //
    509     //  int f1_a(struct FPRec* foo) {
    510     //    int x;
    511     //    (*foo->my_func)(&x);
    512     //    return bar(x)+1; // no-warning
    513     //  }
    514 
    515     assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() ||
    516            originalTy->isBlockPointerType() || castTy->isReferenceType());
    517 
    518     StoreManager &storeMgr = StateMgr.getStoreManager();
    519 
    520     // Delegate to store manager to get the result of casting a region to a
    521     // different type.  If the MemRegion* returned is NULL, this expression
    522     // Evaluates to UnknownVal.
    523     R = storeMgr.castRegion(R, castTy);
    524     return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
    525   }
    526 
    527   return dispatchCast(val, castTy);
    528 }
    529