Home | History | Annotate | Line # | Download | only in Core
      1 //=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 //  This file defines ExprEngine's support for C expressions.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #include "clang/AST/ExprCXX.h"
     14 #include "clang/AST/DeclCXX.h"
     15 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
     16 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
     17 
     18 using namespace clang;
     19 using namespace ento;
     20 using llvm::APSInt;
     21 
     22 /// Optionally conjure and return a symbol for offset when processing
     23 /// an expression \p Expression.
     24 /// If \p Other is a location, conjure a symbol for \p Symbol
     25 /// (offset) if it is unknown so that memory arithmetic always
     26 /// results in an ElementRegion.
     27 /// \p Count The number of times the current basic block was visited.
     28 static SVal conjureOffsetSymbolOnLocation(
     29     SVal Symbol, SVal Other, Expr* Expression, SValBuilder &svalBuilder,
     30     unsigned Count, const LocationContext *LCtx) {
     31   QualType Ty = Expression->getType();
     32   if (Other.getAs<Loc>() &&
     33       Ty->isIntegralOrEnumerationType() &&
     34       Symbol.isUnknown()) {
     35     return svalBuilder.conjureSymbolVal(Expression, LCtx, Ty, Count);
     36   }
     37   return Symbol;
     38 }
     39 
     40 void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
     41                                      ExplodedNode *Pred,
     42                                      ExplodedNodeSet &Dst) {
     43 
     44   Expr *LHS = B->getLHS()->IgnoreParens();
     45   Expr *RHS = B->getRHS()->IgnoreParens();
     46 
     47   // FIXME: Prechecks eventually go in ::Visit().
     48   ExplodedNodeSet CheckedSet;
     49   ExplodedNodeSet Tmp2;
     50   getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
     51 
     52   // With both the LHS and RHS evaluated, process the operation itself.
     53   for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
     54          it != ei; ++it) {
     55 
     56     ProgramStateRef state = (*it)->getState();
     57     const LocationContext *LCtx = (*it)->getLocationContext();
     58     SVal LeftV = state->getSVal(LHS, LCtx);
     59     SVal RightV = state->getSVal(RHS, LCtx);
     60 
     61     BinaryOperator::Opcode Op = B->getOpcode();
     62 
     63     if (Op == BO_Assign) {
     64       // EXPERIMENTAL: "Conjured" symbols.
     65       // FIXME: Handle structs.
     66       if (RightV.isUnknown()) {
     67         unsigned Count = currBldrCtx->blockCount();
     68         RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx,
     69                                               Count);
     70       }
     71       // Simulate the effects of a "store":  bind the value of the RHS
     72       // to the L-Value represented by the LHS.
     73       SVal ExprVal = B->isGLValue() ? LeftV : RightV;
     74       evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal),
     75                 LeftV, RightV);
     76       continue;
     77     }
     78 
     79     if (!B->isAssignmentOp()) {
     80       StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
     81 
     82       if (B->isAdditiveOp()) {
     83         // TODO: This can be removed after we enable history tracking with
     84         // SymSymExpr.
     85         unsigned Count = currBldrCtx->blockCount();
     86         RightV = conjureOffsetSymbolOnLocation(
     87             RightV, LeftV, RHS, svalBuilder, Count, LCtx);
     88         LeftV = conjureOffsetSymbolOnLocation(
     89             LeftV, RightV, LHS, svalBuilder, Count, LCtx);
     90       }
     91 
     92       // Although we don't yet model pointers-to-members, we do need to make
     93       // sure that the members of temporaries have a valid 'this' pointer for
     94       // other checks.
     95       if (B->getOpcode() == BO_PtrMemD)
     96         state = createTemporaryRegionIfNeeded(state, LCtx, LHS);
     97 
     98       // Process non-assignments except commas or short-circuited
     99       // logical expressions (LAnd and LOr).
    100       SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
    101       if (!Result.isUnknown()) {
    102         state = state->BindExpr(B, LCtx, Result);
    103       } else {
    104         // If we cannot evaluate the operation escape the operands.
    105         state = escapeValues(state, LeftV, PSK_EscapeOther);
    106         state = escapeValues(state, RightV, PSK_EscapeOther);
    107       }
    108 
    109       Bldr.generateNode(B, *it, state);
    110       continue;
    111     }
    112 
    113     assert (B->isCompoundAssignmentOp());
    114 
    115     switch (Op) {
    116       default:
    117         llvm_unreachable("Invalid opcode for compound assignment.");
    118       case BO_MulAssign: Op = BO_Mul; break;
    119       case BO_DivAssign: Op = BO_Div; break;
    120       case BO_RemAssign: Op = BO_Rem; break;
    121       case BO_AddAssign: Op = BO_Add; break;
    122       case BO_SubAssign: Op = BO_Sub; break;
    123       case BO_ShlAssign: Op = BO_Shl; break;
    124       case BO_ShrAssign: Op = BO_Shr; break;
    125       case BO_AndAssign: Op = BO_And; break;
    126       case BO_XorAssign: Op = BO_Xor; break;
    127       case BO_OrAssign:  Op = BO_Or;  break;
    128     }
    129 
    130     // Perform a load (the LHS).  This performs the checks for
    131     // null dereferences, and so on.
    132     ExplodedNodeSet Tmp;
    133     SVal location = LeftV;
    134     evalLoad(Tmp, B, LHS, *it, state, location);
    135 
    136     for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E;
    137          ++I) {
    138 
    139       state = (*I)->getState();
    140       const LocationContext *LCtx = (*I)->getLocationContext();
    141       SVal V = state->getSVal(LHS, LCtx);
    142 
    143       // Get the computation type.
    144       QualType CTy =
    145         cast<CompoundAssignOperator>(B)->getComputationResultType();
    146       CTy = getContext().getCanonicalType(CTy);
    147 
    148       QualType CLHSTy =
    149         cast<CompoundAssignOperator>(B)->getComputationLHSType();
    150       CLHSTy = getContext().getCanonicalType(CLHSTy);
    151 
    152       QualType LTy = getContext().getCanonicalType(LHS->getType());
    153 
    154       // Promote LHS.
    155       V = svalBuilder.evalCast(V, CLHSTy, LTy);
    156 
    157       // Compute the result of the operation.
    158       SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
    159                                          B->getType(), CTy);
    160 
    161       // EXPERIMENTAL: "Conjured" symbols.
    162       // FIXME: Handle structs.
    163 
    164       SVal LHSVal;
    165 
    166       if (Result.isUnknown()) {
    167         // The symbolic value is actually for the type of the left-hand side
    168         // expression, not the computation type, as this is the value the
    169         // LValue on the LHS will bind to.
    170         LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy,
    171                                               currBldrCtx->blockCount());
    172         // However, we need to convert the symbol to the computation type.
    173         Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
    174       }
    175       else {
    176         // The left-hand side may bind to a different value then the
    177         // computation type.
    178         LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
    179       }
    180 
    181       // In C++, assignment and compound assignment operators return an
    182       // lvalue.
    183       if (B->isGLValue())
    184         state = state->BindExpr(B, LCtx, location);
    185       else
    186         state = state->BindExpr(B, LCtx, Result);
    187 
    188       evalStore(Tmp2, B, LHS, *I, state, location, LHSVal);
    189     }
    190   }
    191 
    192   // FIXME: postvisits eventually go in ::Visit()
    193   getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
    194 }
    195 
    196 void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
    197                                 ExplodedNodeSet &Dst) {
    198 
    199   CanQualType T = getContext().getCanonicalType(BE->getType());
    200 
    201   const BlockDecl *BD = BE->getBlockDecl();
    202   // Get the value of the block itself.
    203   SVal V = svalBuilder.getBlockPointer(BD, T,
    204                                        Pred->getLocationContext(),
    205                                        currBldrCtx->blockCount());
    206 
    207   ProgramStateRef State = Pred->getState();
    208 
    209   // If we created a new MemRegion for the block, we should explicitly bind
    210   // the captured variables.
    211   if (const BlockDataRegion *BDR =
    212       dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
    213 
    214     BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(),
    215                                               E = BDR->referenced_vars_end();
    216 
    217     auto CI = BD->capture_begin();
    218     auto CE = BD->capture_end();
    219     for (; I != E; ++I) {
    220       const VarRegion *capturedR = I.getCapturedRegion();
    221       const TypedValueRegion *originalR = I.getOriginalRegion();
    222 
    223       // If the capture had a copy expression, use the result of evaluating
    224       // that expression, otherwise use the original value.
    225       // We rely on the invariant that the block declaration's capture variables
    226       // are a prefix of the BlockDataRegion's referenced vars (which may include
    227       // referenced globals, etc.) to enable fast lookup of the capture for a
    228       // given referenced var.
    229       const Expr *copyExpr = nullptr;
    230       if (CI != CE) {
    231         assert(CI->getVariable() == capturedR->getDecl());
    232         copyExpr = CI->getCopyExpr();
    233         CI++;
    234       }
    235 
    236       if (capturedR != originalR) {
    237         SVal originalV;
    238         const LocationContext *LCtx = Pred->getLocationContext();
    239         if (copyExpr) {
    240           originalV = State->getSVal(copyExpr, LCtx);
    241         } else {
    242           originalV = State->getSVal(loc::MemRegionVal(originalR));
    243         }
    244         State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
    245       }
    246     }
    247   }
    248 
    249   ExplodedNodeSet Tmp;
    250   StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
    251   Bldr.generateNode(BE, Pred,
    252                     State->BindExpr(BE, Pred->getLocationContext(), V),
    253                     nullptr, ProgramPoint::PostLValueKind);
    254 
    255   // FIXME: Move all post/pre visits to ::Visit().
    256   getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
    257 }
    258 
    259 ProgramStateRef ExprEngine::handleLValueBitCast(
    260     ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx,
    261     QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr,
    262     ExplodedNode* Pred) {
    263   if (T->isLValueReferenceType()) {
    264     assert(!CastE->getType()->isLValueReferenceType());
    265     ExTy = getContext().getLValueReferenceType(ExTy);
    266   } else if (T->isRValueReferenceType()) {
    267     assert(!CastE->getType()->isRValueReferenceType());
    268     ExTy = getContext().getRValueReferenceType(ExTy);
    269   }
    270   // Delegate to SValBuilder to process.
    271   SVal OrigV = state->getSVal(Ex, LCtx);
    272   SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
    273   // Negate the result if we're treating the boolean as a signed i1
    274   if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
    275     V = evalMinus(V);
    276   state = state->BindExpr(CastE, LCtx, V);
    277   if (V.isUnknown() && !OrigV.isUnknown()) {
    278     state = escapeValues(state, OrigV, PSK_EscapeOther);
    279   }
    280   Bldr.generateNode(CastE, Pred, state);
    281 
    282   return state;
    283 }
    284 
    285 ProgramStateRef ExprEngine::handleLVectorSplat(
    286     ProgramStateRef state, const LocationContext* LCtx, const CastExpr* CastE,
    287     StmtNodeBuilder &Bldr, ExplodedNode* Pred) {
    288   // Recover some path sensitivity by conjuring a new value.
    289   QualType resultType = CastE->getType();
    290   if (CastE->isGLValue())
    291     resultType = getContext().getPointerType(resultType);
    292   SVal result = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx,
    293                                              resultType,
    294                                              currBldrCtx->blockCount());
    295   state = state->BindExpr(CastE, LCtx, result);
    296   Bldr.generateNode(CastE, Pred, state);
    297 
    298   return state;
    299 }
    300 
    301 void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
    302                            ExplodedNode *Pred, ExplodedNodeSet &Dst) {
    303 
    304   ExplodedNodeSet dstPreStmt;
    305   getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this);
    306 
    307   if (CastE->getCastKind() == CK_LValueToRValue) {
    308     for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
    309          I!=E; ++I) {
    310       ExplodedNode *subExprNode = *I;
    311       ProgramStateRef state = subExprNode->getState();
    312       const LocationContext *LCtx = subExprNode->getLocationContext();
    313       evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
    314     }
    315     return;
    316   }
    317 
    318   // All other casts.
    319   QualType T = CastE->getType();
    320   QualType ExTy = Ex->getType();
    321 
    322   if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
    323     T = ExCast->getTypeAsWritten();
    324 
    325   StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx);
    326   for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
    327        I != E; ++I) {
    328 
    329     Pred = *I;
    330     ProgramStateRef state = Pred->getState();
    331     const LocationContext *LCtx = Pred->getLocationContext();
    332 
    333     switch (CastE->getCastKind()) {
    334       case CK_LValueToRValue:
    335         llvm_unreachable("LValueToRValue casts handled earlier.");
    336       case CK_ToVoid:
    337         continue;
    338         // The analyzer doesn't do anything special with these casts,
    339         // since it understands retain/release semantics already.
    340       case CK_ARCProduceObject:
    341       case CK_ARCConsumeObject:
    342       case CK_ARCReclaimReturnedObject:
    343       case CK_ARCExtendBlockObject: // Fall-through.
    344       case CK_CopyAndAutoreleaseBlockObject:
    345         // The analyser can ignore atomic casts for now, although some future
    346         // checkers may want to make certain that you're not modifying the same
    347         // value through atomic and nonatomic pointers.
    348       case CK_AtomicToNonAtomic:
    349       case CK_NonAtomicToAtomic:
    350         // True no-ops.
    351       case CK_NoOp:
    352       case CK_ConstructorConversion:
    353       case CK_UserDefinedConversion:
    354       case CK_FunctionToPointerDecay:
    355       case CK_BuiltinFnToFnPtr: {
    356         // Copy the SVal of Ex to CastE.
    357         ProgramStateRef state = Pred->getState();
    358         const LocationContext *LCtx = Pred->getLocationContext();
    359         SVal V = state->getSVal(Ex, LCtx);
    360         state = state->BindExpr(CastE, LCtx, V);
    361         Bldr.generateNode(CastE, Pred, state);
    362         continue;
    363       }
    364       case CK_MemberPointerToBoolean:
    365       case CK_PointerToBoolean: {
    366         SVal V = state->getSVal(Ex, LCtx);
    367         auto PTMSV = V.getAs<nonloc::PointerToMember>();
    368         if (PTMSV)
    369           V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
    370         if (V.isUndef() || PTMSV) {
    371           state = state->BindExpr(CastE, LCtx, V);
    372           Bldr.generateNode(CastE, Pred, state);
    373           continue;
    374         }
    375         // Explicitly proceed with default handler for this case cascade.
    376         state =
    377             handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
    378         continue;
    379       }
    380       case CK_Dependent:
    381       case CK_ArrayToPointerDecay:
    382       case CK_BitCast:
    383       case CK_LValueToRValueBitCast:
    384       case CK_AddressSpaceConversion:
    385       case CK_BooleanToSignedIntegral:
    386       case CK_IntegralToPointer:
    387       case CK_PointerToIntegral: {
    388         SVal V = state->getSVal(Ex, LCtx);
    389         if (V.getAs<nonloc::PointerToMember>()) {
    390           state = state->BindExpr(CastE, LCtx, UnknownVal());
    391           Bldr.generateNode(CastE, Pred, state);
    392           continue;
    393         }
    394         // Explicitly proceed with default handler for this case cascade.
    395         state =
    396             handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
    397         continue;
    398       }
    399       case CK_IntegralToBoolean:
    400       case CK_IntegralToFloating:
    401       case CK_FloatingToIntegral:
    402       case CK_FloatingToBoolean:
    403       case CK_FloatingCast:
    404       case CK_FloatingRealToComplex:
    405       case CK_FloatingComplexToReal:
    406       case CK_FloatingComplexToBoolean:
    407       case CK_FloatingComplexCast:
    408       case CK_FloatingComplexToIntegralComplex:
    409       case CK_IntegralRealToComplex:
    410       case CK_IntegralComplexToReal:
    411       case CK_IntegralComplexToBoolean:
    412       case CK_IntegralComplexCast:
    413       case CK_IntegralComplexToFloatingComplex:
    414       case CK_CPointerToObjCPointerCast:
    415       case CK_BlockPointerToObjCPointerCast:
    416       case CK_AnyPointerToBlockPointerCast:
    417       case CK_ObjCObjectLValueCast:
    418       case CK_ZeroToOCLOpaqueType:
    419       case CK_IntToOCLSampler:
    420       case CK_LValueBitCast:
    421       case CK_FloatingToFixedPoint:
    422       case CK_FixedPointToFloating:
    423       case CK_FixedPointCast:
    424       case CK_FixedPointToBoolean:
    425       case CK_FixedPointToIntegral:
    426       case CK_IntegralToFixedPoint: {
    427         state =
    428             handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
    429         continue;
    430       }
    431       case CK_IntegralCast: {
    432         // Delegate to SValBuilder to process.
    433         SVal V = state->getSVal(Ex, LCtx);
    434         V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
    435         state = state->BindExpr(CastE, LCtx, V);
    436         Bldr.generateNode(CastE, Pred, state);
    437         continue;
    438       }
    439       case CK_DerivedToBase:
    440       case CK_UncheckedDerivedToBase: {
    441         // For DerivedToBase cast, delegate to the store manager.
    442         SVal val = state->getSVal(Ex, LCtx);
    443         val = getStoreManager().evalDerivedToBase(val, CastE);
    444         state = state->BindExpr(CastE, LCtx, val);
    445         Bldr.generateNode(CastE, Pred, state);
    446         continue;
    447       }
    448       // Handle C++ dyn_cast.
    449       case CK_Dynamic: {
    450         SVal val = state->getSVal(Ex, LCtx);
    451 
    452         // Compute the type of the result.
    453         QualType resultType = CastE->getType();
    454         if (CastE->isGLValue())
    455           resultType = getContext().getPointerType(resultType);
    456 
    457         bool Failed = false;
    458 
    459         // Check if the value being cast evaluates to 0.
    460         if (val.isZeroConstant())
    461           Failed = true;
    462         // Else, evaluate the cast.
    463         else
    464           val = getStoreManager().attemptDownCast(val, T, Failed);
    465 
    466         if (Failed) {
    467           if (T->isReferenceType()) {
    468             // A bad_cast exception is thrown if input value is a reference.
    469             // Currently, we model this, by generating a sink.
    470             Bldr.generateSink(CastE, Pred, state);
    471             continue;
    472           } else {
    473             // If the cast fails on a pointer, bind to 0.
    474             state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull());
    475           }
    476         } else {
    477           // If we don't know if the cast succeeded, conjure a new symbol.
    478           if (val.isUnknown()) {
    479             DefinedOrUnknownSVal NewSym =
    480               svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
    481                                            currBldrCtx->blockCount());
    482             state = state->BindExpr(CastE, LCtx, NewSym);
    483           } else
    484             // Else, bind to the derived region value.
    485             state = state->BindExpr(CastE, LCtx, val);
    486         }
    487         Bldr.generateNode(CastE, Pred, state);
    488         continue;
    489       }
    490       case CK_BaseToDerived: {
    491         SVal val = state->getSVal(Ex, LCtx);
    492         QualType resultType = CastE->getType();
    493         if (CastE->isGLValue())
    494           resultType = getContext().getPointerType(resultType);
    495 
    496         bool Failed = false;
    497 
    498         if (!val.isConstant()) {
    499           val = getStoreManager().attemptDownCast(val, T, Failed);
    500         }
    501 
    502         // Failed to cast or the result is unknown, fall back to conservative.
    503         if (Failed || val.isUnknown()) {
    504           val =
    505             svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
    506                                          currBldrCtx->blockCount());
    507         }
    508         state = state->BindExpr(CastE, LCtx, val);
    509         Bldr.generateNode(CastE, Pred, state);
    510         continue;
    511       }
    512       case CK_NullToPointer: {
    513         SVal V = svalBuilder.makeNull();
    514         state = state->BindExpr(CastE, LCtx, V);
    515         Bldr.generateNode(CastE, Pred, state);
    516         continue;
    517       }
    518       case CK_NullToMemberPointer: {
    519         SVal V = svalBuilder.getMemberPointer(nullptr);
    520         state = state->BindExpr(CastE, LCtx, V);
    521         Bldr.generateNode(CastE, Pred, state);
    522         continue;
    523       }
    524       case CK_DerivedToBaseMemberPointer:
    525       case CK_BaseToDerivedMemberPointer:
    526       case CK_ReinterpretMemberPointer: {
    527         SVal V = state->getSVal(Ex, LCtx);
    528         if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
    529           SVal CastedPTMSV =
    530               svalBuilder.makePointerToMember(getBasicVals().accumCXXBase(
    531                   CastE->path(), *PTMSV, CastE->getCastKind()));
    532           state = state->BindExpr(CastE, LCtx, CastedPTMSV);
    533           Bldr.generateNode(CastE, Pred, state);
    534           continue;
    535         }
    536         // Explicitly proceed with default handler for this case cascade.
    537         state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
    538         continue;
    539       }
    540       // Various C++ casts that are not handled yet.
    541       case CK_ToUnion:
    542       case CK_VectorSplat: {
    543         state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
    544         continue;
    545       }
    546       case CK_MatrixCast: {
    547         // TODO: Handle MatrixCast here.
    548         continue;
    549       }
    550     }
    551   }
    552 }
    553 
    554 void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
    555                                           ExplodedNode *Pred,
    556                                           ExplodedNodeSet &Dst) {
    557   StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
    558 
    559   ProgramStateRef State = Pred->getState();
    560   const LocationContext *LCtx = Pred->getLocationContext();
    561 
    562   const Expr *Init = CL->getInitializer();
    563   SVal V = State->getSVal(CL->getInitializer(), LCtx);
    564 
    565   if (isa<CXXConstructExpr>(Init) || isa<CXXStdInitializerListExpr>(Init)) {
    566     // No work needed. Just pass the value up to this expression.
    567   } else {
    568     assert(isa<InitListExpr>(Init));
    569     Loc CLLoc = State->getLValue(CL, LCtx);
    570     State = State->bindLoc(CLLoc, V, LCtx);
    571 
    572     if (CL->isGLValue())
    573       V = CLLoc;
    574   }
    575 
    576   B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));
    577 }
    578 
    579 void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
    580                                ExplodedNodeSet &Dst) {
    581   if (isa<TypedefNameDecl>(*DS->decl_begin())) {
    582     // C99 6.7.7 "Any array size expressions associated with variable length
    583     // array declarators are evaluated each time the declaration of the typedef
    584     // name is reached in the order of execution."
    585     // The checkers should know about typedef to be able to handle VLA size
    586     // expressions.
    587     ExplodedNodeSet DstPre;
    588     getCheckerManager().runCheckersForPreStmt(DstPre, Pred, DS, *this);
    589     getCheckerManager().runCheckersForPostStmt(Dst, DstPre, DS, *this);
    590     return;
    591   }
    592 
    593   // Assumption: The CFG has one DeclStmt per Decl.
    594   const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
    595 
    596   if (!VD) {
    597     //TODO:AZ: remove explicit insertion after refactoring is done.
    598     Dst.insert(Pred);
    599     return;
    600   }
    601 
    602   // FIXME: all pre/post visits should eventually be handled by ::Visit().
    603   ExplodedNodeSet dstPreVisit;
    604   getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
    605 
    606   ExplodedNodeSet dstEvaluated;
    607   StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
    608   for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
    609        I!=E; ++I) {
    610     ExplodedNode *N = *I;
    611     ProgramStateRef state = N->getState();
    612     const LocationContext *LC = N->getLocationContext();
    613 
    614     // Decls without InitExpr are not initialized explicitly.
    615     if (const Expr *InitEx = VD->getInit()) {
    616 
    617       // Note in the state that the initialization has occurred.
    618       ExplodedNode *UpdatedN = N;
    619       SVal InitVal = state->getSVal(InitEx, LC);
    620 
    621       assert(DS->isSingleDecl());
    622       if (getObjectUnderConstruction(state, DS, LC)) {
    623         state = finishObjectConstruction(state, DS, LC);
    624         // We constructed the object directly in the variable.
    625         // No need to bind anything.
    626         B.generateNode(DS, UpdatedN, state);
    627       } else {
    628         // Recover some path-sensitivity if a scalar value evaluated to
    629         // UnknownVal.
    630         if (InitVal.isUnknown()) {
    631           QualType Ty = InitEx->getType();
    632           if (InitEx->isGLValue()) {
    633             Ty = getContext().getPointerType(Ty);
    634           }
    635 
    636           InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty,
    637                                                  currBldrCtx->blockCount());
    638         }
    639 
    640 
    641         B.takeNodes(UpdatedN);
    642         ExplodedNodeSet Dst2;
    643         evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true);
    644         B.addNodes(Dst2);
    645       }
    646     }
    647     else {
    648       B.generateNode(DS, N, state);
    649     }
    650   }
    651 
    652   getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this);
    653 }
    654 
    655 void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
    656                                   ExplodedNodeSet &Dst) {
    657   // This method acts upon CFG elements for logical operators && and ||
    658   // and attaches the value (true or false) to them as expressions.
    659   // It doesn't produce any state splits.
    660   // If we made it that far, we're past the point when we modeled the short
    661   // circuit. It means that we should have precise knowledge about whether
    662   // we've short-circuited. If we did, we already know the value we need to
    663   // bind. If we didn't, the value of the RHS (casted to the boolean type)
    664   // is the answer.
    665   // Currently this method tries to figure out whether we've short-circuited
    666   // by looking at the ExplodedGraph. This method is imperfect because there
    667   // could inevitably have been merges that would have resulted in multiple
    668   // potential path traversal histories. We bail out when we fail.
    669   // Due to this ambiguity, a more reliable solution would have been to
    670   // track the short circuit operation history path-sensitively until
    671   // we evaluate the respective logical operator.
    672   assert(B->getOpcode() == BO_LAnd ||
    673          B->getOpcode() == BO_LOr);
    674 
    675   StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
    676   ProgramStateRef state = Pred->getState();
    677 
    678   if (B->getType()->isVectorType()) {
    679     // FIXME: We do not model vector arithmetic yet. When adding support for
    680     // that, note that the CFG-based reasoning below does not apply, because
    681     // logical operators on vectors are not short-circuit. Currently they are
    682     // modeled as short-circuit in Clang CFG but this is incorrect.
    683     // Do not set the value for the expression. It'd be UnknownVal by default.
    684     Bldr.generateNode(B, Pred, state);
    685     return;
    686   }
    687 
    688   ExplodedNode *N = Pred;
    689   while (!N->getLocation().getAs<BlockEntrance>()) {
    690     ProgramPoint P = N->getLocation();
    691     assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
    692     (void) P;
    693     if (N->pred_size() != 1) {
    694       // We failed to track back where we came from.
    695       Bldr.generateNode(B, Pred, state);
    696       return;
    697     }
    698     N = *N->pred_begin();
    699   }
    700 
    701   if (N->pred_size() != 1) {
    702     // We failed to track back where we came from.
    703     Bldr.generateNode(B, Pred, state);
    704     return;
    705   }
    706 
    707   N = *N->pred_begin();
    708   BlockEdge BE = N->getLocation().castAs<BlockEdge>();
    709   SVal X;
    710 
    711   // Determine the value of the expression by introspecting how we
    712   // got this location in the CFG.  This requires looking at the previous
    713   // block we were in and what kind of control-flow transfer was involved.
    714   const CFGBlock *SrcBlock = BE.getSrc();
    715   // The only terminator (if there is one) that makes sense is a logical op.
    716   CFGTerminator T = SrcBlock->getTerminator();
    717   if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
    718     (void) Term;
    719     assert(Term->isLogicalOp());
    720     assert(SrcBlock->succ_size() == 2);
    721     // Did we take the true or false branch?
    722     unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
    723     X = svalBuilder.makeIntVal(constant, B->getType());
    724   }
    725   else {
    726     // If there is no terminator, by construction the last statement
    727     // in SrcBlock is the value of the enclosing expression.
    728     // However, we still need to constrain that value to be 0 or 1.
    729     assert(!SrcBlock->empty());
    730     CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
    731     const Expr *RHS = cast<Expr>(Elem.getStmt());
    732     SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
    733 
    734     if (RHSVal.isUndef()) {
    735       X = RHSVal;
    736     } else {
    737       // We evaluate "RHSVal != 0" expression which result in 0 if the value is
    738       // known to be false, 1 if the value is known to be true and a new symbol
    739       // when the assumption is unknown.
    740       nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType()));
    741       X = evalBinOp(N->getState(), BO_NE,
    742                     svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
    743                     Zero, B->getType());
    744     }
    745   }
    746   Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
    747 }
    748 
    749 void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
    750                                    ExplodedNode *Pred,
    751                                    ExplodedNodeSet &Dst) {
    752   StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
    753 
    754   ProgramStateRef state = Pred->getState();
    755   const LocationContext *LCtx = Pred->getLocationContext();
    756   QualType T = getContext().getCanonicalType(IE->getType());
    757   unsigned NumInitElements = IE->getNumInits();
    758 
    759   if (!IE->isGLValue() && !IE->isTransparent() &&
    760       (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
    761        T->isAnyComplexType())) {
    762     llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
    763 
    764     // Handle base case where the initializer has no elements.
    765     // e.g: static int* myArray[] = {};
    766     if (NumInitElements == 0) {
    767       SVal V = svalBuilder.makeCompoundVal(T, vals);
    768       B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
    769       return;
    770     }
    771 
    772     for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
    773          ei = IE->rend(); it != ei; ++it) {
    774       SVal V = state->getSVal(cast<Expr>(*it), LCtx);
    775       vals = getBasicVals().prependSVal(V, vals);
    776     }
    777 
    778     B.generateNode(IE, Pred,
    779                    state->BindExpr(IE, LCtx,
    780                                    svalBuilder.makeCompoundVal(T, vals)));
    781     return;
    782   }
    783 
    784   // Handle scalars: int{5} and int{} and GLvalues.
    785   // Note, if the InitListExpr is a GLvalue, it means that there is an address
    786   // representing it, so it must have a single init element.
    787   assert(NumInitElements <= 1);
    788 
    789   SVal V;
    790   if (NumInitElements == 0)
    791     V = getSValBuilder().makeZeroVal(T);
    792   else
    793     V = state->getSVal(IE->getInit(0), LCtx);
    794 
    795   B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
    796 }
    797 
    798 void ExprEngine::VisitGuardedExpr(const Expr *Ex,
    799                                   const Expr *L,
    800                                   const Expr *R,
    801                                   ExplodedNode *Pred,
    802                                   ExplodedNodeSet &Dst) {
    803   assert(L && R);
    804 
    805   StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
    806   ProgramStateRef state = Pred->getState();
    807   const LocationContext *LCtx = Pred->getLocationContext();
    808   const CFGBlock *SrcBlock = nullptr;
    809 
    810   // Find the predecessor block.
    811   ProgramStateRef SrcState = state;
    812   for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
    813     ProgramPoint PP = N->getLocation();
    814     if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) {
    815       // If the state N has multiple predecessors P, it means that successors
    816       // of P are all equivalent.
    817       // In turn, that means that all nodes at P are equivalent in terms
    818       // of observable behavior at N, and we can follow any of them.
    819       // FIXME: a more robust solution which does not walk up the tree.
    820       continue;
    821     }
    822     SrcBlock = PP.castAs<BlockEdge>().getSrc();
    823     SrcState = N->getState();
    824     break;
    825   }
    826 
    827   assert(SrcBlock && "missing function entry");
    828 
    829   // Find the last expression in the predecessor block.  That is the
    830   // expression that is used for the value of the ternary expression.
    831   bool hasValue = false;
    832   SVal V;
    833 
    834   for (CFGElement CE : llvm::reverse(*SrcBlock)) {
    835     if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
    836       const Expr *ValEx = cast<Expr>(CS->getStmt());
    837       ValEx = ValEx->IgnoreParens();
    838 
    839       // For GNU extension '?:' operator, the left hand side will be an
    840       // OpaqueValueExpr, so get the underlying expression.
    841       if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
    842         L = OpaqueEx->getSourceExpr();
    843 
    844       // If the last expression in the predecessor block matches true or false
    845       // subexpression, get its the value.
    846       if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
    847         hasValue = true;
    848         V = SrcState->getSVal(ValEx, LCtx);
    849       }
    850       break;
    851     }
    852   }
    853 
    854   if (!hasValue)
    855     V = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
    856                                      currBldrCtx->blockCount());
    857 
    858   // Generate a new node with the binding from the appropriate path.
    859   B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
    860 }
    861 
    862 void ExprEngine::
    863 VisitOffsetOfExpr(const OffsetOfExpr *OOE,
    864                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
    865   StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
    866   Expr::EvalResult Result;
    867   if (OOE->EvaluateAsInt(Result, getContext())) {
    868     APSInt IV = Result.Val.getInt();
    869     assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
    870     assert(OOE->getType()->castAs<BuiltinType>()->isInteger());
    871     assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
    872     SVal X = svalBuilder.makeIntVal(IV);
    873     B.generateNode(OOE, Pred,
    874                    Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
    875                                               X));
    876   }
    877   // FIXME: Handle the case where __builtin_offsetof is not a constant.
    878 }
    879 
    880 
    881 void ExprEngine::
    882 VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
    883                               ExplodedNode *Pred,
    884                               ExplodedNodeSet &Dst) {
    885   // FIXME: Prechecks eventually go in ::Visit().
    886   ExplodedNodeSet CheckedSet;
    887   getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
    888 
    889   ExplodedNodeSet EvalSet;
    890   StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
    891 
    892   QualType T = Ex->getTypeOfArgument();
    893 
    894   for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
    895        I != E; ++I) {
    896     if (Ex->getKind() == UETT_SizeOf) {
    897       if (!T->isIncompleteType() && !T->isConstantSizeType()) {
    898         assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
    899 
    900         // FIXME: Add support for VLA type arguments and VLA expressions.
    901         // When that happens, we should probably refactor VLASizeChecker's code.
    902         continue;
    903       } else if (T->getAs<ObjCObjectType>()) {
    904         // Some code tries to take the sizeof an ObjCObjectType, relying that
    905         // the compiler has laid out its representation.  Just report Unknown
    906         // for these.
    907         continue;
    908       }
    909     }
    910 
    911     APSInt Value = Ex->EvaluateKnownConstInt(getContext());
    912     CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
    913 
    914     ProgramStateRef state = (*I)->getState();
    915     state = state->BindExpr(Ex, (*I)->getLocationContext(),
    916                             svalBuilder.makeIntVal(amt.getQuantity(),
    917                                                    Ex->getType()));
    918     Bldr.generateNode(Ex, *I, state);
    919   }
    920 
    921   getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
    922 }
    923 
    924 void ExprEngine::handleUOExtension(ExplodedNodeSet::iterator I,
    925                                    const UnaryOperator *U,
    926                                    StmtNodeBuilder &Bldr) {
    927   // FIXME: We can probably just have some magic in Environment::getSVal()
    928   // that propagates values, instead of creating a new node here.
    929   //
    930   // Unary "+" is a no-op, similar to a parentheses.  We still have places
    931   // where it may be a block-level expression, so we need to
    932   // generate an extra node that just propagates the value of the
    933   // subexpression.
    934   const Expr *Ex = U->getSubExpr()->IgnoreParens();
    935   ProgramStateRef state = (*I)->getState();
    936   const LocationContext *LCtx = (*I)->getLocationContext();
    937   Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
    938                                            state->getSVal(Ex, LCtx)));
    939 }
    940 
    941 void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
    942                                     ExplodedNodeSet &Dst) {
    943   // FIXME: Prechecks eventually go in ::Visit().
    944   ExplodedNodeSet CheckedSet;
    945   getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
    946 
    947   ExplodedNodeSet EvalSet;
    948   StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
    949 
    950   for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
    951        I != E; ++I) {
    952     switch (U->getOpcode()) {
    953     default: {
    954       Bldr.takeNodes(*I);
    955       ExplodedNodeSet Tmp;
    956       VisitIncrementDecrementOperator(U, *I, Tmp);
    957       Bldr.addNodes(Tmp);
    958       break;
    959     }
    960     case UO_Real: {
    961       const Expr *Ex = U->getSubExpr()->IgnoreParens();
    962 
    963       // FIXME: We don't have complex SValues yet.
    964       if (Ex->getType()->isAnyComplexType()) {
    965         // Just report "Unknown."
    966         break;
    967       }
    968 
    969       // For all other types, UO_Real is an identity operation.
    970       assert (U->getType() == Ex->getType());
    971       ProgramStateRef state = (*I)->getState();
    972       const LocationContext *LCtx = (*I)->getLocationContext();
    973       Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
    974                                                state->getSVal(Ex, LCtx)));
    975       break;
    976     }
    977 
    978     case UO_Imag: {
    979       const Expr *Ex = U->getSubExpr()->IgnoreParens();
    980       // FIXME: We don't have complex SValues yet.
    981       if (Ex->getType()->isAnyComplexType()) {
    982         // Just report "Unknown."
    983         break;
    984       }
    985       // For all other types, UO_Imag returns 0.
    986       ProgramStateRef state = (*I)->getState();
    987       const LocationContext *LCtx = (*I)->getLocationContext();
    988       SVal X = svalBuilder.makeZeroVal(Ex->getType());
    989       Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
    990       break;
    991     }
    992 
    993     case UO_AddrOf: {
    994       // Process pointer-to-member address operation.
    995       const Expr *Ex = U->getSubExpr()->IgnoreParens();
    996       if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
    997         const ValueDecl *VD = DRE->getDecl();
    998 
    999         if (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD) ||
   1000             isa<IndirectFieldDecl>(VD)) {
   1001           ProgramStateRef State = (*I)->getState();
   1002           const LocationContext *LCtx = (*I)->getLocationContext();
   1003           SVal SV = svalBuilder.getMemberPointer(cast<NamedDecl>(VD));
   1004           Bldr.generateNode(U, *I, State->BindExpr(U, LCtx, SV));
   1005           break;
   1006         }
   1007       }
   1008       // Explicitly proceed with default handler for this case cascade.
   1009       handleUOExtension(I, U, Bldr);
   1010       break;
   1011     }
   1012     case UO_Plus:
   1013       assert(!U->isGLValue());
   1014       LLVM_FALLTHROUGH;
   1015     case UO_Deref:
   1016     case UO_Extension: {
   1017       handleUOExtension(I, U, Bldr);
   1018       break;
   1019     }
   1020 
   1021     case UO_LNot:
   1022     case UO_Minus:
   1023     case UO_Not: {
   1024       assert (!U->isGLValue());
   1025       const Expr *Ex = U->getSubExpr()->IgnoreParens();
   1026       ProgramStateRef state = (*I)->getState();
   1027       const LocationContext *LCtx = (*I)->getLocationContext();
   1028 
   1029       // Get the value of the subexpression.
   1030       SVal V = state->getSVal(Ex, LCtx);
   1031 
   1032       if (V.isUnknownOrUndef()) {
   1033         Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
   1034         break;
   1035       }
   1036 
   1037       switch (U->getOpcode()) {
   1038         default:
   1039           llvm_unreachable("Invalid Opcode.");
   1040         case UO_Not:
   1041           // FIXME: Do we need to handle promotions?
   1042           state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>()));
   1043           break;
   1044         case UO_Minus:
   1045           // FIXME: Do we need to handle promotions?
   1046           state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>()));
   1047           break;
   1048         case UO_LNot:
   1049           // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
   1050           //
   1051           //  Note: technically we do "E == 0", but this is the same in the
   1052           //    transfer functions as "0 == E".
   1053           SVal Result;
   1054           if (Optional<Loc> LV = V.getAs<Loc>()) {
   1055             Loc X = svalBuilder.makeNullWithType(Ex->getType());
   1056             Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
   1057           } else if (Ex->getType()->isFloatingType()) {
   1058             // FIXME: handle floating point types.
   1059             Result = UnknownVal();
   1060           } else {
   1061             nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
   1062             Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X,
   1063                                U->getType());
   1064           }
   1065 
   1066           state = state->BindExpr(U, LCtx, Result);
   1067           break;
   1068       }
   1069       Bldr.generateNode(U, *I, state);
   1070       break;
   1071     }
   1072     }
   1073   }
   1074 
   1075   getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
   1076 }
   1077 
   1078 void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
   1079                                                  ExplodedNode *Pred,
   1080                                                  ExplodedNodeSet &Dst) {
   1081   // Handle ++ and -- (both pre- and post-increment).
   1082   assert (U->isIncrementDecrementOp());
   1083   const Expr *Ex = U->getSubExpr()->IgnoreParens();
   1084 
   1085   const LocationContext *LCtx = Pred->getLocationContext();
   1086   ProgramStateRef state = Pred->getState();
   1087   SVal loc = state->getSVal(Ex, LCtx);
   1088 
   1089   // Perform a load.
   1090   ExplodedNodeSet Tmp;
   1091   evalLoad(Tmp, U, Ex, Pred, state, loc);
   1092 
   1093   ExplodedNodeSet Dst2;
   1094   StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
   1095   for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
   1096 
   1097     state = (*I)->getState();
   1098     assert(LCtx == (*I)->getLocationContext());
   1099     SVal V2_untested = state->getSVal(Ex, LCtx);
   1100 
   1101     // Propagate unknown and undefined values.
   1102     if (V2_untested.isUnknownOrUndef()) {
   1103       state = state->BindExpr(U, LCtx, V2_untested);
   1104 
   1105       // Perform the store, so that the uninitialized value detection happens.
   1106       Bldr.takeNodes(*I);
   1107       ExplodedNodeSet Dst3;
   1108       evalStore(Dst3, U, Ex, *I, state, loc, V2_untested);
   1109       Bldr.addNodes(Dst3);
   1110 
   1111       continue;
   1112     }
   1113     DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
   1114 
   1115     // Handle all other values.
   1116     BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
   1117 
   1118     // If the UnaryOperator has non-location type, use its type to create the
   1119     // constant value. If the UnaryOperator has location type, create the
   1120     // constant with int type and pointer width.
   1121     SVal RHS;
   1122     SVal Result;
   1123 
   1124     if (U->getType()->isAnyPointerType())
   1125       RHS = svalBuilder.makeArrayIndex(1);
   1126     else if (U->getType()->isIntegralOrEnumerationType())
   1127       RHS = svalBuilder.makeIntVal(1, U->getType());
   1128     else
   1129       RHS = UnknownVal();
   1130 
   1131     // The use of an operand of type bool with the ++ operators is deprecated
   1132     // but valid until C++17. And if the operand of the ++ operator is of type
   1133     // bool, it is set to true until C++17. Note that for '_Bool', it is also
   1134     // set to true when it encounters ++ operator.
   1135     if (U->getType()->isBooleanType() && U->isIncrementOp())
   1136       Result = svalBuilder.makeTruthVal(true, U->getType());
   1137     else
   1138       Result = evalBinOp(state, Op, V2, RHS, U->getType());
   1139 
   1140     // Conjure a new symbol if necessary to recover precision.
   1141     if (Result.isUnknown()){
   1142       DefinedOrUnknownSVal SymVal =
   1143         svalBuilder.conjureSymbolVal(nullptr, U, LCtx,
   1144                                      currBldrCtx->blockCount());
   1145       Result = SymVal;
   1146 
   1147       // If the value is a location, ++/-- should always preserve
   1148       // non-nullness.  Check if the original value was non-null, and if so
   1149       // propagate that constraint.
   1150       if (Loc::isLocType(U->getType())) {
   1151         DefinedOrUnknownSVal Constraint =
   1152         svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
   1153 
   1154         if (!state->assume(Constraint, true)) {
   1155           // It isn't feasible for the original value to be null.
   1156           // Propagate this constraint.
   1157           Constraint = svalBuilder.evalEQ(state, SymVal,
   1158                                        svalBuilder.makeZeroVal(U->getType()));
   1159 
   1160           state = state->assume(Constraint, false);
   1161           assert(state);
   1162         }
   1163       }
   1164     }
   1165 
   1166     // Since the lvalue-to-rvalue conversion is explicit in the AST,
   1167     // we bind an l-value if the operator is prefix and an lvalue (in C++).
   1168     if (U->isGLValue())
   1169       state = state->BindExpr(U, LCtx, loc);
   1170     else
   1171       state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
   1172 
   1173     // Perform the store.
   1174     Bldr.takeNodes(*I);
   1175     ExplodedNodeSet Dst3;
   1176     evalStore(Dst3, U, Ex, *I, state, loc, Result);
   1177     Bldr.addNodes(Dst3);
   1178   }
   1179   Dst.insert(Dst2);
   1180 }
   1181