1226586Sdim//=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- C++ -*-===// 2226586Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6226586Sdim// 7226586Sdim//===----------------------------------------------------------------------===// 8226586Sdim// 9226586Sdim// This file defines ExprEngine's support for C expressions. 10226586Sdim// 11226586Sdim//===----------------------------------------------------------------------===// 12226586Sdim 13249423Sdim#include "clang/AST/ExprCXX.h" 14314564Sdim#include "clang/AST/DeclCXX.h" 15226586Sdim#include "clang/StaticAnalyzer/Core/CheckerManager.h" 16226586Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 17226586Sdim 18226586Sdimusing namespace clang; 19226586Sdimusing namespace ento; 20226586Sdimusing llvm::APSInt; 21226586Sdim 22341825Sdim/// Optionally conjure and return a symbol for offset when processing 23327952Sdim/// an expression \p Expression. 24327952Sdim/// If \p Other is a location, conjure a symbol for \p Symbol 25327952Sdim/// (offset) if it is unknown so that memory arithmetic always 26327952Sdim/// results in an ElementRegion. 27327952Sdim/// \p Count The number of times the current basic block was visited. 28327952Sdimstatic SVal conjureOffsetSymbolOnLocation( 29327952Sdim SVal Symbol, SVal Other, Expr* Expression, SValBuilder &svalBuilder, 30327952Sdim unsigned Count, const LocationContext *LCtx) { 31327952Sdim QualType Ty = Expression->getType(); 32327952Sdim if (Other.getAs<Loc>() && 33327952Sdim Ty->isIntegralOrEnumerationType() && 34327952Sdim Symbol.isUnknown()) { 35327952Sdim return svalBuilder.conjureSymbolVal(Expression, LCtx, Ty, Count); 36327952Sdim } 37327952Sdim return Symbol; 38327952Sdim} 39327952Sdim 40226586Sdimvoid ExprEngine::VisitBinaryOperator(const BinaryOperator* B, 41226586Sdim ExplodedNode *Pred, 42226586Sdim ExplodedNodeSet &Dst) { 43226586Sdim 44226586Sdim Expr *LHS = B->getLHS()->IgnoreParens(); 45226586Sdim Expr *RHS = B->getRHS()->IgnoreParens(); 46296417Sdim 47226586Sdim // FIXME: Prechecks eventually go in ::Visit(). 48226586Sdim ExplodedNodeSet CheckedSet; 49226586Sdim ExplodedNodeSet Tmp2; 50226586Sdim getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this); 51296417Sdim 52288943Sdim // With both the LHS and RHS evaluated, process the operation itself. 53226586Sdim for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end(); 54226586Sdim it != ei; ++it) { 55296417Sdim 56234353Sdim ProgramStateRef state = (*it)->getState(); 57234353Sdim const LocationContext *LCtx = (*it)->getLocationContext(); 58234353Sdim SVal LeftV = state->getSVal(LHS, LCtx); 59234353Sdim SVal RightV = state->getSVal(RHS, LCtx); 60296417Sdim 61226586Sdim BinaryOperator::Opcode Op = B->getOpcode(); 62296417Sdim 63226586Sdim if (Op == BO_Assign) { 64226586Sdim // EXPERIMENTAL: "Conjured" symbols. 65226586Sdim // FIXME: Handle structs. 66234353Sdim if (RightV.isUnknown()) { 67243830Sdim unsigned Count = currBldrCtx->blockCount(); 68276479Sdim RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, 69276479Sdim Count); 70226586Sdim } 71226586Sdim // Simulate the effects of a "store": bind the value of the RHS 72226586Sdim // to the L-Value represented by the LHS. 73239462Sdim SVal ExprVal = B->isGLValue() ? LeftV : RightV; 74234353Sdim evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal), 75234353Sdim LeftV, RightV); 76226586Sdim continue; 77226586Sdim } 78296417Sdim 79226586Sdim if (!B->isAssignmentOp()) { 80243830Sdim StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx); 81239462Sdim 82239462Sdim if (B->isAdditiveOp()) { 83239462Sdim // TODO: This can be removed after we enable history tracking with 84239462Sdim // SymSymExpr. 85243830Sdim unsigned Count = currBldrCtx->blockCount(); 86327952Sdim RightV = conjureOffsetSymbolOnLocation( 87327952Sdim RightV, LeftV, RHS, svalBuilder, Count, LCtx); 88327952Sdim LeftV = conjureOffsetSymbolOnLocation( 89327952Sdim LeftV, RightV, LHS, svalBuilder, Count, LCtx); 90239462Sdim } 91239462Sdim 92276479Sdim // Although we don't yet model pointers-to-members, we do need to make 93276479Sdim // sure that the members of temporaries have a valid 'this' pointer for 94276479Sdim // other checks. 95276479Sdim if (B->getOpcode() == BO_PtrMemD) 96276479Sdim state = createTemporaryRegionIfNeeded(state, LCtx, LHS); 97276479Sdim 98226586Sdim // Process non-assignments except commas or short-circuited 99226586Sdim // logical expressions (LAnd and LOr). 100296417Sdim SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType()); 101327952Sdim if (!Result.isUnknown()) { 102327952Sdim state = state->BindExpr(B, LCtx, Result); 103353358Sdim } else { 104353358Sdim // If we cannot evaluate the operation escape the operands. 105360784Sdim state = escapeValues(state, LeftV, PSK_EscapeOther); 106360784Sdim state = escapeValues(state, RightV, PSK_EscapeOther); 107296417Sdim } 108226586Sdim 109234353Sdim Bldr.generateNode(B, *it, state); 110226586Sdim continue; 111226586Sdim } 112296417Sdim 113226586Sdim assert (B->isCompoundAssignmentOp()); 114296417Sdim 115226586Sdim switch (Op) { 116226586Sdim default: 117226586Sdim llvm_unreachable("Invalid opcode for compound assignment."); 118226586Sdim case BO_MulAssign: Op = BO_Mul; break; 119226586Sdim case BO_DivAssign: Op = BO_Div; break; 120226586Sdim case BO_RemAssign: Op = BO_Rem; break; 121226586Sdim case BO_AddAssign: Op = BO_Add; break; 122226586Sdim case BO_SubAssign: Op = BO_Sub; break; 123226586Sdim case BO_ShlAssign: Op = BO_Shl; break; 124226586Sdim case BO_ShrAssign: Op = BO_Shr; break; 125226586Sdim case BO_AndAssign: Op = BO_And; break; 126226586Sdim case BO_XorAssign: Op = BO_Xor; break; 127226586Sdim case BO_OrAssign: Op = BO_Or; break; 128226586Sdim } 129296417Sdim 130226586Sdim // Perform a load (the LHS). This performs the checks for 131226586Sdim // null dereferences, and so on. 132226586Sdim ExplodedNodeSet Tmp; 133226586Sdim SVal location = LeftV; 134234353Sdim evalLoad(Tmp, B, LHS, *it, state, location); 135296417Sdim 136226586Sdim for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; 137226586Sdim ++I) { 138226586Sdim 139226586Sdim state = (*I)->getState(); 140234353Sdim const LocationContext *LCtx = (*I)->getLocationContext(); 141234353Sdim SVal V = state->getSVal(LHS, LCtx); 142296417Sdim 143226586Sdim // Get the computation type. 144226586Sdim QualType CTy = 145226586Sdim cast<CompoundAssignOperator>(B)->getComputationResultType(); 146226586Sdim CTy = getContext().getCanonicalType(CTy); 147296417Sdim 148226586Sdim QualType CLHSTy = 149226586Sdim cast<CompoundAssignOperator>(B)->getComputationLHSType(); 150226586Sdim CLHSTy = getContext().getCanonicalType(CLHSTy); 151296417Sdim 152226586Sdim QualType LTy = getContext().getCanonicalType(LHS->getType()); 153296417Sdim 154226586Sdim // Promote LHS. 155226586Sdim V = svalBuilder.evalCast(V, CLHSTy, LTy); 156296417Sdim 157226586Sdim // Compute the result of the operation. 158226586Sdim SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy), 159226586Sdim B->getType(), CTy); 160296417Sdim 161226586Sdim // EXPERIMENTAL: "Conjured" symbols. 162226586Sdim // FIXME: Handle structs. 163296417Sdim 164226586Sdim SVal LHSVal; 165296417Sdim 166234353Sdim if (Result.isUnknown()) { 167226586Sdim // The symbolic value is actually for the type of the left-hand side 168226586Sdim // expression, not the computation type, as this is the value the 169226586Sdim // LValue on the LHS will bind to. 170276479Sdim LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy, 171243830Sdim currBldrCtx->blockCount()); 172226586Sdim // However, we need to convert the symbol to the computation type. 173226586Sdim Result = svalBuilder.evalCast(LHSVal, CTy, LTy); 174226586Sdim } 175226586Sdim else { 176226586Sdim // The left-hand side may bind to a different value then the 177226586Sdim // computation type. 178226586Sdim LHSVal = svalBuilder.evalCast(Result, LTy, CTy); 179226586Sdim } 180296417Sdim 181296417Sdim // In C++, assignment and compound assignment operators return an 182226586Sdim // lvalue. 183239462Sdim if (B->isGLValue()) 184234353Sdim state = state->BindExpr(B, LCtx, location); 185226586Sdim else 186234353Sdim state = state->BindExpr(B, LCtx, Result); 187296417Sdim 188226586Sdim evalStore(Tmp2, B, LHS, *I, state, location, LHSVal); 189226586Sdim } 190226586Sdim } 191296417Sdim 192226586Sdim // FIXME: postvisits eventually go in ::Visit() 193226586Sdim getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this); 194226586Sdim} 195226586Sdim 196226586Sdimvoid ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 197226586Sdim ExplodedNodeSet &Dst) { 198296417Sdim 199226586Sdim CanQualType T = getContext().getCanonicalType(BE->getType()); 200239462Sdim 201296417Sdim const BlockDecl *BD = BE->getBlockDecl(); 202239462Sdim // Get the value of the block itself. 203296417Sdim SVal V = svalBuilder.getBlockPointer(BD, T, 204261991Sdim Pred->getLocationContext(), 205261991Sdim currBldrCtx->blockCount()); 206296417Sdim 207239462Sdim ProgramStateRef State = Pred->getState(); 208296417Sdim 209239462Sdim // If we created a new MemRegion for the block, we should explicitly bind 210239462Sdim // the captured variables. 211239462Sdim if (const BlockDataRegion *BDR = 212239462Sdim dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) { 213296417Sdim 214239462Sdim BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(), 215239462Sdim E = BDR->referenced_vars_end(); 216296417Sdim 217296417Sdim auto CI = BD->capture_begin(); 218296417Sdim auto CE = BD->capture_end(); 219239462Sdim for (; I != E; ++I) { 220296417Sdim const VarRegion *capturedR = I.getCapturedRegion(); 221296417Sdim const VarRegion *originalR = I.getOriginalRegion(); 222296417Sdim 223296417Sdim // If the capture had a copy expression, use the result of evaluating 224296417Sdim // that expression, otherwise use the original value. 225296417Sdim // We rely on the invariant that the block declaration's capture variables 226296417Sdim // are a prefix of the BlockDataRegion's referenced vars (which may include 227296417Sdim // referenced globals, etc.) to enable fast lookup of the capture for a 228296417Sdim // given referenced var. 229296417Sdim const Expr *copyExpr = nullptr; 230296417Sdim if (CI != CE) { 231296417Sdim assert(CI->getVariable() == capturedR->getDecl()); 232296417Sdim copyExpr = CI->getCopyExpr(); 233296417Sdim CI++; 234296417Sdim } 235296417Sdim 236239462Sdim if (capturedR != originalR) { 237296417Sdim SVal originalV; 238321369Sdim const LocationContext *LCtx = Pred->getLocationContext(); 239296417Sdim if (copyExpr) { 240321369Sdim originalV = State->getSVal(copyExpr, LCtx); 241296417Sdim } else { 242296417Sdim originalV = State->getSVal(loc::MemRegionVal(originalR)); 243296417Sdim } 244321369Sdim State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx); 245239462Sdim } 246239462Sdim } 247239462Sdim } 248296417Sdim 249226586Sdim ExplodedNodeSet Tmp; 250243830Sdim StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx); 251234353Sdim Bldr.generateNode(BE, Pred, 252239462Sdim State->BindExpr(BE, Pred->getLocationContext(), V), 253276479Sdim nullptr, ProgramPoint::PostLValueKind); 254276479Sdim 255226586Sdim // FIXME: Move all post/pre visits to ::Visit(). 256226586Sdim getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this); 257226586Sdim} 258226586Sdim 259314564SdimProgramStateRef ExprEngine::handleLValueBitCast( 260314564Sdim ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx, 261314564Sdim QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr, 262314564Sdim ExplodedNode* Pred) { 263341825Sdim if (T->isLValueReferenceType()) { 264341825Sdim assert(!CastE->getType()->isLValueReferenceType()); 265341825Sdim ExTy = getContext().getLValueReferenceType(ExTy); 266341825Sdim } else if (T->isRValueReferenceType()) { 267341825Sdim assert(!CastE->getType()->isRValueReferenceType()); 268341825Sdim ExTy = getContext().getRValueReferenceType(ExTy); 269341825Sdim } 270314564Sdim // Delegate to SValBuilder to process. 271341825Sdim SVal OrigV = state->getSVal(Ex, LCtx); 272341825Sdim SVal V = svalBuilder.evalCast(OrigV, T, ExTy); 273314564Sdim // Negate the result if we're treating the boolean as a signed i1 274314564Sdim if (CastE->getCastKind() == CK_BooleanToSignedIntegral) 275314564Sdim V = evalMinus(V); 276314564Sdim state = state->BindExpr(CastE, LCtx, V); 277341825Sdim if (V.isUnknown() && !OrigV.isUnknown()) { 278360784Sdim state = escapeValues(state, OrigV, PSK_EscapeOther); 279341825Sdim } 280314564Sdim Bldr.generateNode(CastE, Pred, state); 281314564Sdim 282314564Sdim return state; 283314564Sdim} 284314564Sdim 285314564SdimProgramStateRef ExprEngine::handleLVectorSplat( 286314564Sdim ProgramStateRef state, const LocationContext* LCtx, const CastExpr* CastE, 287314564Sdim StmtNodeBuilder &Bldr, ExplodedNode* Pred) { 288314564Sdim // Recover some path sensitivity by conjuring a new value. 289314564Sdim QualType resultType = CastE->getType(); 290314564Sdim if (CastE->isGLValue()) 291314564Sdim resultType = getContext().getPointerType(resultType); 292314564Sdim SVal result = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, 293314564Sdim resultType, 294314564Sdim currBldrCtx->blockCount()); 295314564Sdim state = state->BindExpr(CastE, LCtx, result); 296314564Sdim Bldr.generateNode(CastE, Pred, state); 297314564Sdim 298314564Sdim return state; 299314564Sdim} 300314564Sdim 301296417Sdimvoid ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, 302226586Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst) { 303296417Sdim 304226586Sdim ExplodedNodeSet dstPreStmt; 305226586Sdim getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this); 306296417Sdim 307234353Sdim if (CastE->getCastKind() == CK_LValueToRValue) { 308226586Sdim for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end(); 309226586Sdim I!=E; ++I) { 310226586Sdim ExplodedNode *subExprNode = *I; 311234353Sdim ProgramStateRef state = subExprNode->getState(); 312234353Sdim const LocationContext *LCtx = subExprNode->getLocationContext(); 313234353Sdim evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx)); 314226586Sdim } 315226586Sdim return; 316226586Sdim } 317296417Sdim 318296417Sdim // All other casts. 319226586Sdim QualType T = CastE->getType(); 320226586Sdim QualType ExTy = Ex->getType(); 321296417Sdim 322226586Sdim if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE)) 323226586Sdim T = ExCast->getTypeAsWritten(); 324296417Sdim 325243830Sdim StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx); 326226586Sdim for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end(); 327226586Sdim I != E; ++I) { 328296417Sdim 329226586Sdim Pred = *I; 330243830Sdim ProgramStateRef state = Pred->getState(); 331243830Sdim const LocationContext *LCtx = Pred->getLocationContext(); 332243830Sdim 333226586Sdim switch (CastE->getCastKind()) { 334226586Sdim case CK_LValueToRValue: 335226586Sdim llvm_unreachable("LValueToRValue casts handled earlier."); 336226586Sdim case CK_ToVoid: 337226586Sdim continue; 338226586Sdim // The analyzer doesn't do anything special with these casts, 339226586Sdim // since it understands retain/release semantics already. 340226586Sdim case CK_ARCProduceObject: 341226586Sdim case CK_ARCConsumeObject: 342226586Sdim case CK_ARCReclaimReturnedObject: 343226586Sdim case CK_ARCExtendBlockObject: // Fall-through. 344234353Sdim case CK_CopyAndAutoreleaseBlockObject: 345234353Sdim // The analyser can ignore atomic casts for now, although some future 346234353Sdim // checkers may want to make certain that you're not modifying the same 347234353Sdim // value through atomic and nonatomic pointers. 348234353Sdim case CK_AtomicToNonAtomic: 349234353Sdim case CK_NonAtomicToAtomic: 350226586Sdim // True no-ops. 351226586Sdim case CK_NoOp: 352243830Sdim case CK_ConstructorConversion: 353243830Sdim case CK_UserDefinedConversion: 354243830Sdim case CK_FunctionToPointerDecay: 355243830Sdim case CK_BuiltinFnToFnPtr: { 356226586Sdim // Copy the SVal of Ex to CastE. 357234353Sdim ProgramStateRef state = Pred->getState(); 358234353Sdim const LocationContext *LCtx = Pred->getLocationContext(); 359234353Sdim SVal V = state->getSVal(Ex, LCtx); 360234353Sdim state = state->BindExpr(CastE, LCtx, V); 361234353Sdim Bldr.generateNode(CastE, Pred, state); 362226586Sdim continue; 363226586Sdim } 364243830Sdim case CK_MemberPointerToBoolean: 365314564Sdim case CK_PointerToBoolean: { 366314564Sdim SVal V = state->getSVal(Ex, LCtx); 367314564Sdim auto PTMSV = V.getAs<nonloc::PointerToMember>(); 368314564Sdim if (PTMSV) 369314564Sdim V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy); 370314564Sdim if (V.isUndef() || PTMSV) { 371314564Sdim state = state->BindExpr(CastE, LCtx, V); 372314564Sdim Bldr.generateNode(CastE, Pred, state); 373314564Sdim continue; 374314564Sdim } 375314564Sdim // Explicitly proceed with default handler for this case cascade. 376314564Sdim state = 377314564Sdim handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); 378314564Sdim continue; 379314564Sdim } 380226586Sdim case CK_Dependent: 381226586Sdim case CK_ArrayToPointerDecay: 382226586Sdim case CK_BitCast: 383353358Sdim case CK_LValueToRValueBitCast: 384276479Sdim case CK_AddressSpaceConversion: 385296417Sdim case CK_BooleanToSignedIntegral: 386226586Sdim case CK_IntegralToPointer: 387314564Sdim case CK_PointerToIntegral: { 388314564Sdim SVal V = state->getSVal(Ex, LCtx); 389314564Sdim if (V.getAs<nonloc::PointerToMember>()) { 390314564Sdim state = state->BindExpr(CastE, LCtx, UnknownVal()); 391314564Sdim Bldr.generateNode(CastE, Pred, state); 392314564Sdim continue; 393314564Sdim } 394314564Sdim // Explicitly proceed with default handler for this case cascade. 395314564Sdim state = 396314564Sdim handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); 397314564Sdim continue; 398314564Sdim } 399226586Sdim case CK_IntegralToBoolean: 400226586Sdim case CK_IntegralToFloating: 401226586Sdim case CK_FloatingToIntegral: 402226586Sdim case CK_FloatingToBoolean: 403226586Sdim case CK_FloatingCast: 404226586Sdim case CK_FloatingRealToComplex: 405226586Sdim case CK_FloatingComplexToReal: 406226586Sdim case CK_FloatingComplexToBoolean: 407226586Sdim case CK_FloatingComplexCast: 408226586Sdim case CK_FloatingComplexToIntegralComplex: 409226586Sdim case CK_IntegralRealToComplex: 410226586Sdim case CK_IntegralComplexToReal: 411226586Sdim case CK_IntegralComplexToBoolean: 412226586Sdim case CK_IntegralComplexCast: 413226586Sdim case CK_IntegralComplexToFloatingComplex: 414226586Sdim case CK_CPointerToObjCPointerCast: 415226586Sdim case CK_BlockPointerToObjCPointerCast: 416296417Sdim case CK_AnyPointerToBlockPointerCast: 417296417Sdim case CK_ObjCObjectLValueCast: 418344779Sdim case CK_ZeroToOCLOpaqueType: 419314564Sdim case CK_IntToOCLSampler: 420344779Sdim case CK_LValueBitCast: 421344779Sdim case CK_FixedPointCast: 422353358Sdim case CK_FixedPointToBoolean: 423353358Sdim case CK_FixedPointToIntegral: 424353358Sdim case CK_IntegralToFixedPoint: { 425314564Sdim state = 426314564Sdim handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); 427226586Sdim continue; 428226586Sdim } 429296417Sdim case CK_IntegralCast: { 430296417Sdim // Delegate to SValBuilder to process. 431296417Sdim SVal V = state->getSVal(Ex, LCtx); 432296417Sdim V = svalBuilder.evalIntegralCast(state, V, T, ExTy); 433296417Sdim state = state->BindExpr(CastE, LCtx, V); 434296417Sdim Bldr.generateNode(CastE, Pred, state); 435296417Sdim continue; 436296417Sdim } 437226586Sdim case CK_DerivedToBase: 438226586Sdim case CK_UncheckedDerivedToBase: { 439226586Sdim // For DerivedToBase cast, delegate to the store manager. 440234353Sdim SVal val = state->getSVal(Ex, LCtx); 441239462Sdim val = getStoreManager().evalDerivedToBase(val, CastE); 442234353Sdim state = state->BindExpr(CastE, LCtx, val); 443234353Sdim Bldr.generateNode(CastE, Pred, state); 444226586Sdim continue; 445226586Sdim } 446234353Sdim // Handle C++ dyn_cast. 447234353Sdim case CK_Dynamic: { 448234353Sdim SVal val = state->getSVal(Ex, LCtx); 449234353Sdim 450234353Sdim // Compute the type of the result. 451234353Sdim QualType resultType = CastE->getType(); 452239462Sdim if (CastE->isGLValue()) 453234353Sdim resultType = getContext().getPointerType(resultType); 454234353Sdim 455234353Sdim bool Failed = false; 456234353Sdim 457234353Sdim // Check if the value being cast evaluates to 0. 458234353Sdim if (val.isZeroConstant()) 459234353Sdim Failed = true; 460234353Sdim // Else, evaluate the cast. 461234353Sdim else 462314564Sdim val = getStoreManager().attemptDownCast(val, T, Failed); 463234353Sdim 464234353Sdim if (Failed) { 465234353Sdim if (T->isReferenceType()) { 466234353Sdim // A bad_cast exception is thrown if input value is a reference. 467234353Sdim // Currently, we model this, by generating a sink. 468243830Sdim Bldr.generateSink(CastE, Pred, state); 469234353Sdim continue; 470234353Sdim } else { 471234353Sdim // If the cast fails on a pointer, bind to 0. 472234353Sdim state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull()); 473234353Sdim } 474234353Sdim } else { 475234353Sdim // If we don't know if the cast succeeded, conjure a new symbol. 476234353Sdim if (val.isUnknown()) { 477243830Sdim DefinedOrUnknownSVal NewSym = 478276479Sdim svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType, 479243830Sdim currBldrCtx->blockCount()); 480234353Sdim state = state->BindExpr(CastE, LCtx, NewSym); 481296417Sdim } else 482234353Sdim // Else, bind to the derived region value. 483234353Sdim state = state->BindExpr(CastE, LCtx, val); 484234353Sdim } 485234353Sdim Bldr.generateNode(CastE, Pred, state); 486234353Sdim continue; 487234353Sdim } 488314564Sdim case CK_BaseToDerived: { 489314564Sdim SVal val = state->getSVal(Ex, LCtx); 490314564Sdim QualType resultType = CastE->getType(); 491314564Sdim if (CastE->isGLValue()) 492314564Sdim resultType = getContext().getPointerType(resultType); 493314564Sdim 494314564Sdim bool Failed = false; 495314564Sdim 496314564Sdim if (!val.isConstant()) { 497314564Sdim val = getStoreManager().attemptDownCast(val, T, Failed); 498314564Sdim } 499314564Sdim 500314564Sdim // Failed to cast or the result is unknown, fall back to conservative. 501314564Sdim if (Failed || val.isUnknown()) { 502314564Sdim val = 503314564Sdim svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType, 504314564Sdim currBldrCtx->blockCount()); 505314564Sdim } 506314564Sdim state = state->BindExpr(CastE, LCtx, val); 507314564Sdim Bldr.generateNode(CastE, Pred, state); 508314564Sdim continue; 509314564Sdim } 510353358Sdim case CK_NullToPointer: { 511353358Sdim SVal V = svalBuilder.makeNull(); 512353358Sdim state = state->BindExpr(CastE, LCtx, V); 513353358Sdim Bldr.generateNode(CastE, Pred, state); 514353358Sdim continue; 515353358Sdim } 516243830Sdim case CK_NullToMemberPointer: { 517314564Sdim SVal V = svalBuilder.getMemberPointer(nullptr); 518243830Sdim state = state->BindExpr(CastE, LCtx, V); 519243830Sdim Bldr.generateNode(CastE, Pred, state); 520243830Sdim continue; 521243830Sdim } 522314564Sdim case CK_DerivedToBaseMemberPointer: 523314564Sdim case CK_BaseToDerivedMemberPointer: 524314564Sdim case CK_ReinterpretMemberPointer: { 525314564Sdim SVal V = state->getSVal(Ex, LCtx); 526314564Sdim if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) { 527314564Sdim SVal CastedPTMSV = svalBuilder.makePointerToMember( 528314564Sdim getBasicVals().accumCXXBase( 529314564Sdim llvm::make_range<CastExpr::path_const_iterator>( 530314564Sdim CastE->path_begin(), CastE->path_end()), *PTMSV)); 531314564Sdim state = state->BindExpr(CastE, LCtx, CastedPTMSV); 532314564Sdim Bldr.generateNode(CastE, Pred, state); 533314564Sdim continue; 534314564Sdim } 535314564Sdim // Explicitly proceed with default handler for this case cascade. 536314564Sdim state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred); 537314564Sdim continue; 538314564Sdim } 539234353Sdim // Various C++ casts that are not handled yet. 540226586Sdim case CK_ToUnion: 541261991Sdim case CK_VectorSplat: { 542314564Sdim state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred); 543226586Sdim continue; 544226586Sdim } 545226586Sdim } 546226586Sdim } 547226586Sdim} 548226586Sdim 549226586Sdimvoid ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 550226586Sdim ExplodedNode *Pred, 551226586Sdim ExplodedNodeSet &Dst) { 552243830Sdim StmtNodeBuilder B(Pred, Dst, *currBldrCtx); 553234353Sdim 554251662Sdim ProgramStateRef State = Pred->getState(); 555251662Sdim const LocationContext *LCtx = Pred->getLocationContext(); 556251662Sdim 557251662Sdim const Expr *Init = CL->getInitializer(); 558251662Sdim SVal V = State->getSVal(CL->getInitializer(), LCtx); 559296417Sdim 560327952Sdim if (isa<CXXConstructExpr>(Init) || isa<CXXStdInitializerListExpr>(Init)) { 561251662Sdim // No work needed. Just pass the value up to this expression. 562251662Sdim } else { 563251662Sdim assert(isa<InitListExpr>(Init)); 564251662Sdim Loc CLLoc = State->getLValue(CL, LCtx); 565321369Sdim State = State->bindLoc(CLLoc, V, LCtx); 566239462Sdim 567314564Sdim if (CL->isGLValue()) 568251662Sdim V = CLLoc; 569251662Sdim } 570251662Sdim 571251662Sdim B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V)); 572226586Sdim} 573226586Sdim 574226586Sdimvoid ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 575226586Sdim ExplodedNodeSet &Dst) { 576226586Sdim // Assumption: The CFG has one DeclStmt per Decl. 577249423Sdim const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin()); 578249423Sdim 579249423Sdim if (!VD) { 580234353Sdim //TODO:AZ: remove explicit insertion after refactoring is done. 581234353Sdim Dst.insert(Pred); 582226586Sdim return; 583234353Sdim } 584296417Sdim 585226586Sdim // FIXME: all pre/post visits should eventually be handled by ::Visit(). 586226586Sdim ExplodedNodeSet dstPreVisit; 587226586Sdim getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this); 588296417Sdim 589261991Sdim ExplodedNodeSet dstEvaluated; 590261991Sdim StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx); 591226586Sdim for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end(); 592226586Sdim I!=E; ++I) { 593226586Sdim ExplodedNode *N = *I; 594234353Sdim ProgramStateRef state = N->getState(); 595249423Sdim const LocationContext *LC = N->getLocationContext(); 596249423Sdim 597226586Sdim // Decls without InitExpr are not initialized explicitly. 598226586Sdim if (const Expr *InitEx = VD->getInit()) { 599249423Sdim 600249423Sdim // Note in the state that the initialization has occurred. 601249423Sdim ExplodedNode *UpdatedN = N; 602239462Sdim SVal InitVal = state->getSVal(InitEx, LC); 603234353Sdim 604296417Sdim assert(DS->isSingleDecl()); 605341825Sdim if (getObjectUnderConstruction(state, DS, LC)) { 606341825Sdim state = finishObjectConstruction(state, DS, LC); 607239462Sdim // We constructed the object directly in the variable. 608239462Sdim // No need to bind anything. 609249423Sdim B.generateNode(DS, UpdatedN, state); 610239462Sdim } else { 611239462Sdim // Recover some path-sensitivity if a scalar value evaluated to 612239462Sdim // UnknownVal. 613239462Sdim if (InitVal.isUnknown()) { 614239462Sdim QualType Ty = InitEx->getType(); 615239462Sdim if (InitEx->isGLValue()) { 616239462Sdim Ty = getContext().getPointerType(Ty); 617239462Sdim } 618239462Sdim 619276479Sdim InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty, 620243830Sdim currBldrCtx->blockCount()); 621239462Sdim } 622249423Sdim 623249423Sdim 624249423Sdim B.takeNodes(UpdatedN); 625239462Sdim ExplodedNodeSet Dst2; 626249423Sdim evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true); 627239462Sdim B.addNodes(Dst2); 628226586Sdim } 629226586Sdim } 630226586Sdim else { 631243830Sdim B.generateNode(DS, N, state); 632226586Sdim } 633226586Sdim } 634261991Sdim 635261991Sdim getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this); 636226586Sdim} 637226586Sdim 638226586Sdimvoid ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, 639226586Sdim ExplodedNodeSet &Dst) { 640353358Sdim // This method acts upon CFG elements for logical operators && and || 641353358Sdim // and attaches the value (true or false) to them as expressions. 642353358Sdim // It doesn't produce any state splits. 643353358Sdim // If we made it that far, we're past the point when we modeled the short 644353358Sdim // circuit. It means that we should have precise knowledge about whether 645353358Sdim // we've short-circuited. If we did, we already know the value we need to 646353358Sdim // bind. If we didn't, the value of the RHS (casted to the boolean type) 647353358Sdim // is the answer. 648353358Sdim // Currently this method tries to figure out whether we've short-circuited 649353358Sdim // by looking at the ExplodedGraph. This method is imperfect because there 650353358Sdim // could inevitably have been merges that would have resulted in multiple 651353358Sdim // potential path traversal histories. We bail out when we fail. 652353358Sdim // Due to this ambiguity, a more reliable solution would have been to 653353358Sdim // track the short circuit operation history path-sensitively until 654353358Sdim // we evaluate the respective logical operator. 655226586Sdim assert(B->getOpcode() == BO_LAnd || 656226586Sdim B->getOpcode() == BO_LOr); 657234353Sdim 658243830Sdim StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 659234353Sdim ProgramStateRef state = Pred->getState(); 660239462Sdim 661327952Sdim if (B->getType()->isVectorType()) { 662327952Sdim // FIXME: We do not model vector arithmetic yet. When adding support for 663327952Sdim // that, note that the CFG-based reasoning below does not apply, because 664327952Sdim // logical operators on vectors are not short-circuit. Currently they are 665327952Sdim // modeled as short-circuit in Clang CFG but this is incorrect. 666327952Sdim // Do not set the value for the expression. It'd be UnknownVal by default. 667327952Sdim Bldr.generateNode(B, Pred, state); 668327952Sdim return; 669327952Sdim } 670327952Sdim 671239462Sdim ExplodedNode *N = Pred; 672249423Sdim while (!N->getLocation().getAs<BlockEntrance>()) { 673239462Sdim ProgramPoint P = N->getLocation(); 674249423Sdim assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>()); 675239462Sdim (void) P; 676353358Sdim if (N->pred_size() != 1) { 677353358Sdim // We failed to track back where we came from. 678353358Sdim Bldr.generateNode(B, Pred, state); 679353358Sdim return; 680353358Sdim } 681239462Sdim N = *N->pred_begin(); 682226586Sdim } 683353358Sdim 684353358Sdim if (N->pred_size() != 1) { 685353358Sdim // We failed to track back where we came from. 686353358Sdim Bldr.generateNode(B, Pred, state); 687353358Sdim return; 688353358Sdim } 689353358Sdim 690239462Sdim N = *N->pred_begin(); 691249423Sdim BlockEdge BE = N->getLocation().castAs<BlockEdge>(); 692239462Sdim SVal X; 693239462Sdim 694239462Sdim // Determine the value of the expression by introspecting how we 695239462Sdim // got this location in the CFG. This requires looking at the previous 696239462Sdim // block we were in and what kind of control-flow transfer was involved. 697239462Sdim const CFGBlock *SrcBlock = BE.getSrc(); 698239462Sdim // The only terminator (if there is one) that makes sense is a logical op. 699239462Sdim CFGTerminator T = SrcBlock->getTerminator(); 700239462Sdim if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) { 701239462Sdim (void) Term; 702239462Sdim assert(Term->isLogicalOp()); 703239462Sdim assert(SrcBlock->succ_size() == 2); 704239462Sdim // Did we take the true or false branch? 705239462Sdim unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0; 706239462Sdim X = svalBuilder.makeIntVal(constant, B->getType()); 707239462Sdim } 708226586Sdim else { 709239462Sdim // If there is no terminator, by construction the last statement 710239462Sdim // in SrcBlock is the value of the enclosing expression. 711243830Sdim // However, we still need to constrain that value to be 0 or 1. 712239462Sdim assert(!SrcBlock->empty()); 713249423Sdim CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>(); 714243830Sdim const Expr *RHS = cast<Expr>(Elem.getStmt()); 715243830Sdim SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext()); 716243830Sdim 717249423Sdim if (RHSVal.isUndef()) { 718249423Sdim X = RHSVal; 719249423Sdim } else { 720314564Sdim // We evaluate "RHSVal != 0" expression which result in 0 if the value is 721314564Sdim // known to be false, 1 if the value is known to be true and a new symbol 722314564Sdim // when the assumption is unknown. 723314564Sdim nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType())); 724341825Sdim X = evalBinOp(N->getState(), BO_NE, 725314564Sdim svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()), 726314564Sdim Zero, B->getType()); 727243830Sdim } 728226586Sdim } 729239462Sdim Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X)); 730226586Sdim} 731226586Sdim 732226586Sdimvoid ExprEngine::VisitInitListExpr(const InitListExpr *IE, 733226586Sdim ExplodedNode *Pred, 734226586Sdim ExplodedNodeSet &Dst) { 735243830Sdim StmtNodeBuilder B(Pred, Dst, *currBldrCtx); 736226586Sdim 737234353Sdim ProgramStateRef state = Pred->getState(); 738234353Sdim const LocationContext *LCtx = Pred->getLocationContext(); 739226586Sdim QualType T = getContext().getCanonicalType(IE->getType()); 740226586Sdim unsigned NumInitElements = IE->getNumInits(); 741261991Sdim 742353358Sdim if (!IE->isGLValue() && !IE->isTransparent() && 743261991Sdim (T->isArrayType() || T->isRecordType() || T->isVectorType() || 744261991Sdim T->isAnyComplexType())) { 745226586Sdim llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList(); 746296417Sdim 747226586Sdim // Handle base case where the initializer has no elements. 748226586Sdim // e.g: static int* myArray[] = {}; 749226586Sdim if (NumInitElements == 0) { 750226586Sdim SVal V = svalBuilder.makeCompoundVal(T, vals); 751234353Sdim B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V)); 752226586Sdim return; 753226586Sdim } 754296417Sdim 755226586Sdim for (InitListExpr::const_reverse_iterator it = IE->rbegin(), 756226586Sdim ei = IE->rend(); it != ei; ++it) { 757249423Sdim SVal V = state->getSVal(cast<Expr>(*it), LCtx); 758314564Sdim vals = getBasicVals().prependSVal(V, vals); 759226586Sdim } 760296417Sdim 761234353Sdim B.generateNode(IE, Pred, 762234353Sdim state->BindExpr(IE, LCtx, 763234353Sdim svalBuilder.makeCompoundVal(T, vals))); 764226586Sdim return; 765226586Sdim } 766239462Sdim 767261991Sdim // Handle scalars: int{5} and int{} and GLvalues. 768261991Sdim // Note, if the InitListExpr is a GLvalue, it means that there is an address 769261991Sdim // representing it, so it must have a single init element. 770239462Sdim assert(NumInitElements <= 1); 771239462Sdim 772239462Sdim SVal V; 773239462Sdim if (NumInitElements == 0) 774239462Sdim V = getSValBuilder().makeZeroVal(T); 775239462Sdim else 776239462Sdim V = state->getSVal(IE->getInit(0), LCtx); 777239462Sdim 778239462Sdim B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V)); 779226586Sdim} 780226586Sdim 781226586Sdimvoid ExprEngine::VisitGuardedExpr(const Expr *Ex, 782296417Sdim const Expr *L, 783226586Sdim const Expr *R, 784226586Sdim ExplodedNode *Pred, 785226586Sdim ExplodedNodeSet &Dst) { 786251662Sdim assert(L && R); 787251662Sdim 788243830Sdim StmtNodeBuilder B(Pred, Dst, *currBldrCtx); 789234353Sdim ProgramStateRef state = Pred->getState(); 790234353Sdim const LocationContext *LCtx = Pred->getLocationContext(); 791276479Sdim const CFGBlock *SrcBlock = nullptr; 792239462Sdim 793251662Sdim // Find the predecessor block. 794251662Sdim ProgramStateRef SrcState = state; 795239462Sdim for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) { 796239462Sdim ProgramPoint PP = N->getLocation(); 797249423Sdim if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) { 798341825Sdim // If the state N has multiple predecessors P, it means that successors 799341825Sdim // of P are all equivalent. 800341825Sdim // In turn, that means that all nodes at P are equivalent in terms 801341825Sdim // of observable behavior at N, and we can follow any of them. 802341825Sdim // FIXME: a more robust solution which does not walk up the tree. 803239462Sdim continue; 804239462Sdim } 805249423Sdim SrcBlock = PP.castAs<BlockEdge>().getSrc(); 806251662Sdim SrcState = N->getState(); 807239462Sdim break; 808239462Sdim } 809239462Sdim 810249423Sdim assert(SrcBlock && "missing function entry"); 811249423Sdim 812239462Sdim // Find the last expression in the predecessor block. That is the 813239462Sdim // expression that is used for the value of the ternary expression. 814239462Sdim bool hasValue = false; 815239462Sdim SVal V; 816239462Sdim 817296417Sdim for (CFGElement CE : llvm::reverse(*SrcBlock)) { 818249423Sdim if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) { 819239462Sdim const Expr *ValEx = cast<Expr>(CS->getStmt()); 820251662Sdim ValEx = ValEx->IgnoreParens(); 821251662Sdim 822251662Sdim // For GNU extension '?:' operator, the left hand side will be an 823251662Sdim // OpaqueValueExpr, so get the underlying expression. 824251662Sdim if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L)) 825251662Sdim L = OpaqueEx->getSourceExpr(); 826251662Sdim 827251662Sdim // If the last expression in the predecessor block matches true or false 828251662Sdim // subexpression, get its the value. 829251662Sdim if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) { 830251662Sdim hasValue = true; 831251662Sdim V = SrcState->getSVal(ValEx, LCtx); 832251662Sdim } 833239462Sdim break; 834239462Sdim } 835239462Sdim } 836239462Sdim 837251662Sdim if (!hasValue) 838276479Sdim V = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, 839276479Sdim currBldrCtx->blockCount()); 840239462Sdim 841239462Sdim // Generate a new node with the binding from the appropriate path. 842239462Sdim B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true)); 843226586Sdim} 844226586Sdim 845226586Sdimvoid ExprEngine:: 846296417SdimVisitOffsetOfExpr(const OffsetOfExpr *OOE, 847226586Sdim ExplodedNode *Pred, ExplodedNodeSet &Dst) { 848243830Sdim StmtNodeBuilder B(Pred, Dst, *currBldrCtx); 849344779Sdim Expr::EvalResult Result; 850344779Sdim if (OOE->EvaluateAsInt(Result, getContext())) { 851344779Sdim APSInt IV = Result.Val.getInt(); 852226586Sdim assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType())); 853360784Sdim assert(OOE->getType()->castAs<BuiltinType>()->isInteger()); 854251662Sdim assert(IV.isSigned() == OOE->getType()->isSignedIntegerType()); 855226586Sdim SVal X = svalBuilder.makeIntVal(IV); 856234353Sdim B.generateNode(OOE, Pred, 857234353Sdim Pred->getState()->BindExpr(OOE, Pred->getLocationContext(), 858234353Sdim X)); 859226586Sdim } 860226586Sdim // FIXME: Handle the case where __builtin_offsetof is not a constant. 861226586Sdim} 862226586Sdim 863226586Sdim 864226586Sdimvoid ExprEngine:: 865226586SdimVisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, 866226586Sdim ExplodedNode *Pred, 867226586Sdim ExplodedNodeSet &Dst) { 868276479Sdim // FIXME: Prechecks eventually go in ::Visit(). 869276479Sdim ExplodedNodeSet CheckedSet; 870276479Sdim getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this); 871226586Sdim 872276479Sdim ExplodedNodeSet EvalSet; 873276479Sdim StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx); 874276479Sdim 875226586Sdim QualType T = Ex->getTypeOfArgument(); 876276479Sdim 877276479Sdim for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 878276479Sdim I != E; ++I) { 879276479Sdim if (Ex->getKind() == UETT_SizeOf) { 880276479Sdim if (!T->isIncompleteType() && !T->isConstantSizeType()) { 881276479Sdim assert(T->isVariableArrayType() && "Unknown non-constant-sized type."); 882296417Sdim 883276479Sdim // FIXME: Add support for VLA type arguments and VLA expressions. 884276479Sdim // When that happens, we should probably refactor VLASizeChecker's code. 885276479Sdim continue; 886276479Sdim } else if (T->getAs<ObjCObjectType>()) { 887276479Sdim // Some code tries to take the sizeof an ObjCObjectType, relying that 888276479Sdim // the compiler has laid out its representation. Just report Unknown 889276479Sdim // for these. 890276479Sdim continue; 891276479Sdim } 892226586Sdim } 893296417Sdim 894276479Sdim APSInt Value = Ex->EvaluateKnownConstInt(getContext()); 895276479Sdim CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue()); 896296417Sdim 897276479Sdim ProgramStateRef state = (*I)->getState(); 898276479Sdim state = state->BindExpr(Ex, (*I)->getLocationContext(), 899276479Sdim svalBuilder.makeIntVal(amt.getQuantity(), 900276479Sdim Ex->getType())); 901276479Sdim Bldr.generateNode(Ex, *I, state); 902226586Sdim } 903276479Sdim 904276479Sdim getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this); 905226586Sdim} 906226586Sdim 907314564Sdimvoid ExprEngine::handleUOExtension(ExplodedNodeSet::iterator I, 908314564Sdim const UnaryOperator *U, 909314564Sdim StmtNodeBuilder &Bldr) { 910314564Sdim // FIXME: We can probably just have some magic in Environment::getSVal() 911314564Sdim // that propagates values, instead of creating a new node here. 912314564Sdim // 913314564Sdim // Unary "+" is a no-op, similar to a parentheses. We still have places 914314564Sdim // where it may be a block-level expression, so we need to 915314564Sdim // generate an extra node that just propagates the value of the 916314564Sdim // subexpression. 917314564Sdim const Expr *Ex = U->getSubExpr()->IgnoreParens(); 918314564Sdim ProgramStateRef state = (*I)->getState(); 919314564Sdim const LocationContext *LCtx = (*I)->getLocationContext(); 920314564Sdim Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, 921314564Sdim state->getSVal(Ex, LCtx))); 922314564Sdim} 923314564Sdim 924314564Sdimvoid ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred, 925234353Sdim ExplodedNodeSet &Dst) { 926261991Sdim // FIXME: Prechecks eventually go in ::Visit(). 927261991Sdim ExplodedNodeSet CheckedSet; 928261991Sdim getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this); 929261991Sdim 930261991Sdim ExplodedNodeSet EvalSet; 931261991Sdim StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx); 932261991Sdim 933261991Sdim for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 934261991Sdim I != E; ++I) { 935261991Sdim switch (U->getOpcode()) { 936234353Sdim default: { 937261991Sdim Bldr.takeNodes(*I); 938234353Sdim ExplodedNodeSet Tmp; 939261991Sdim VisitIncrementDecrementOperator(U, *I, Tmp); 940234353Sdim Bldr.addNodes(Tmp); 941261991Sdim break; 942234353Sdim } 943226586Sdim case UO_Real: { 944226586Sdim const Expr *Ex = U->getSubExpr()->IgnoreParens(); 945296417Sdim 946234353Sdim // FIXME: We don't have complex SValues yet. 947234353Sdim if (Ex->getType()->isAnyComplexType()) { 948234353Sdim // Just report "Unknown." 949234353Sdim break; 950234353Sdim } 951296417Sdim 952234353Sdim // For all other types, UO_Real is an identity operation. 953234353Sdim assert (U->getType() == Ex->getType()); 954261991Sdim ProgramStateRef state = (*I)->getState(); 955261991Sdim const LocationContext *LCtx = (*I)->getLocationContext(); 956261991Sdim Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, 957261991Sdim state->getSVal(Ex, LCtx))); 958234353Sdim break; 959226586Sdim } 960296417Sdim 961296417Sdim case UO_Imag: { 962226586Sdim const Expr *Ex = U->getSubExpr()->IgnoreParens(); 963234353Sdim // FIXME: We don't have complex SValues yet. 964234353Sdim if (Ex->getType()->isAnyComplexType()) { 965234353Sdim // Just report "Unknown." 966234353Sdim break; 967226586Sdim } 968234353Sdim // For all other types, UO_Imag returns 0. 969261991Sdim ProgramStateRef state = (*I)->getState(); 970261991Sdim const LocationContext *LCtx = (*I)->getLocationContext(); 971234353Sdim SVal X = svalBuilder.makeZeroVal(Ex->getType()); 972261991Sdim Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X)); 973234353Sdim break; 974226586Sdim } 975296417Sdim 976314564Sdim case UO_AddrOf: { 977314564Sdim // Process pointer-to-member address operation. 978314564Sdim const Expr *Ex = U->getSubExpr()->IgnoreParens(); 979314564Sdim if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) { 980314564Sdim const ValueDecl *VD = DRE->getDecl(); 981314564Sdim 982314564Sdim if (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD)) { 983314564Sdim ProgramStateRef State = (*I)->getState(); 984314564Sdim const LocationContext *LCtx = (*I)->getLocationContext(); 985314564Sdim SVal SV = svalBuilder.getMemberPointer(cast<DeclaratorDecl>(VD)); 986314564Sdim Bldr.generateNode(U, *I, State->BindExpr(U, LCtx, SV)); 987314564Sdim break; 988314564Sdim } 989314564Sdim } 990314564Sdim // Explicitly proceed with default handler for this case cascade. 991314564Sdim handleUOExtension(I, U, Bldr); 992314564Sdim break; 993314564Sdim } 994226586Sdim case UO_Plus: 995239462Sdim assert(!U->isGLValue()); 996344779Sdim LLVM_FALLTHROUGH; 997226586Sdim case UO_Deref: 998226586Sdim case UO_Extension: { 999314564Sdim handleUOExtension(I, U, Bldr); 1000234353Sdim break; 1001226586Sdim } 1002296417Sdim 1003226586Sdim case UO_LNot: 1004226586Sdim case UO_Minus: 1005226586Sdim case UO_Not: { 1006239462Sdim assert (!U->isGLValue()); 1007226586Sdim const Expr *Ex = U->getSubExpr()->IgnoreParens(); 1008261991Sdim ProgramStateRef state = (*I)->getState(); 1009261991Sdim const LocationContext *LCtx = (*I)->getLocationContext(); 1010296417Sdim 1011234353Sdim // Get the value of the subexpression. 1012234353Sdim SVal V = state->getSVal(Ex, LCtx); 1013296417Sdim 1014234353Sdim if (V.isUnknownOrUndef()) { 1015261991Sdim Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V)); 1016234353Sdim break; 1017234353Sdim } 1018296417Sdim 1019234353Sdim switch (U->getOpcode()) { 1020234353Sdim default: 1021234353Sdim llvm_unreachable("Invalid Opcode."); 1022234353Sdim case UO_Not: 1023234353Sdim // FIXME: Do we need to handle promotions? 1024249423Sdim state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>())); 1025234353Sdim break; 1026234353Sdim case UO_Minus: 1027234353Sdim // FIXME: Do we need to handle promotions? 1028249423Sdim state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>())); 1029234353Sdim break; 1030234353Sdim case UO_LNot: 1031234353Sdim // C99 6.5.3.3: "The expression !E is equivalent to (0==E)." 1032234353Sdim // 1033234353Sdim // Note: technically we do "E == 0", but this is the same in the 1034234353Sdim // transfer functions as "0 == E". 1035296417Sdim SVal Result; 1036249423Sdim if (Optional<Loc> LV = V.getAs<Loc>()) { 1037321369Sdim Loc X = svalBuilder.makeNullWithType(Ex->getType()); 1038249423Sdim Result = evalBinOp(state, BO_EQ, *LV, X, U->getType()); 1039321369Sdim } else if (Ex->getType()->isFloatingType()) { 1040249423Sdim // FIXME: handle floating point types. 1041249423Sdim Result = UnknownVal(); 1042249423Sdim } else { 1043234353Sdim nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); 1044249423Sdim Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X, 1045234353Sdim U->getType()); 1046234353Sdim } 1047296417Sdim 1048296417Sdim state = state->BindExpr(U, LCtx, Result); 1049234353Sdim break; 1050226586Sdim } 1051261991Sdim Bldr.generateNode(U, *I, state); 1052234353Sdim break; 1053226586Sdim } 1054261991Sdim } 1055226586Sdim } 1056234353Sdim 1057261991Sdim getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this); 1058234353Sdim} 1059234353Sdim 1060234353Sdimvoid ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U, 1061234353Sdim ExplodedNode *Pred, 1062234353Sdim ExplodedNodeSet &Dst) { 1063226586Sdim // Handle ++ and -- (both pre- and post-increment). 1064226586Sdim assert (U->isIncrementDecrementOp()); 1065226586Sdim const Expr *Ex = U->getSubExpr()->IgnoreParens(); 1066296417Sdim 1067234353Sdim const LocationContext *LCtx = Pred->getLocationContext(); 1068234353Sdim ProgramStateRef state = Pred->getState(); 1069234353Sdim SVal loc = state->getSVal(Ex, LCtx); 1070296417Sdim 1071234353Sdim // Perform a load. 1072234353Sdim ExplodedNodeSet Tmp; 1073234353Sdim evalLoad(Tmp, U, Ex, Pred, state, loc); 1074296417Sdim 1075234353Sdim ExplodedNodeSet Dst2; 1076243830Sdim StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx); 1077234353Sdim for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) { 1078296417Sdim 1079234353Sdim state = (*I)->getState(); 1080234353Sdim assert(LCtx == (*I)->getLocationContext()); 1081234353Sdim SVal V2_untested = state->getSVal(Ex, LCtx); 1082296417Sdim 1083234353Sdim // Propagate unknown and undefined values. 1084234353Sdim if (V2_untested.isUnknownOrUndef()) { 1085327952Sdim state = state->BindExpr(U, LCtx, V2_untested); 1086327952Sdim 1087327952Sdim // Perform the store, so that the uninitialized value detection happens. 1088327952Sdim Bldr.takeNodes(*I); 1089327952Sdim ExplodedNodeSet Dst3; 1090344779Sdim evalStore(Dst3, U, Ex, *I, state, loc, V2_untested); 1091327952Sdim Bldr.addNodes(Dst3); 1092327952Sdim 1093234353Sdim continue; 1094234353Sdim } 1095249423Sdim DefinedSVal V2 = V2_untested.castAs<DefinedSVal>(); 1096296417Sdim 1097234353Sdim // Handle all other values. 1098234353Sdim BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub; 1099296417Sdim 1100234353Sdim // If the UnaryOperator has non-location type, use its type to create the 1101234353Sdim // constant value. If the UnaryOperator has location type, create the 1102234353Sdim // constant with int type and pointer width. 1103234353Sdim SVal RHS; 1104341825Sdim SVal Result; 1105296417Sdim 1106234353Sdim if (U->getType()->isAnyPointerType()) 1107234353Sdim RHS = svalBuilder.makeArrayIndex(1); 1108243830Sdim else if (U->getType()->isIntegralOrEnumerationType()) 1109243830Sdim RHS = svalBuilder.makeIntVal(1, U->getType()); 1110234353Sdim else 1111243830Sdim RHS = UnknownVal(); 1112296417Sdim 1113341825Sdim // The use of an operand of type bool with the ++ operators is deprecated 1114341825Sdim // but valid until C++17. And if the operand of the ++ operator is of type 1115341825Sdim // bool, it is set to true until C++17. Note that for '_Bool', it is also 1116341825Sdim // set to true when it encounters ++ operator. 1117341825Sdim if (U->getType()->isBooleanType() && U->isIncrementOp()) 1118341825Sdim Result = svalBuilder.makeTruthVal(true, U->getType()); 1119341825Sdim else 1120341825Sdim Result = evalBinOp(state, Op, V2, RHS, U->getType()); 1121296417Sdim 1122234353Sdim // Conjure a new symbol if necessary to recover precision. 1123234353Sdim if (Result.isUnknown()){ 1124234353Sdim DefinedOrUnknownSVal SymVal = 1125321369Sdim svalBuilder.conjureSymbolVal(nullptr, U, LCtx, 1126276479Sdim currBldrCtx->blockCount()); 1127234353Sdim Result = SymVal; 1128296417Sdim 1129234353Sdim // If the value is a location, ++/-- should always preserve 1130234353Sdim // non-nullness. Check if the original value was non-null, and if so 1131234353Sdim // propagate that constraint. 1132234353Sdim if (Loc::isLocType(U->getType())) { 1133234353Sdim DefinedOrUnknownSVal Constraint = 1134234353Sdim svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType())); 1135296417Sdim 1136234353Sdim if (!state->assume(Constraint, true)) { 1137234353Sdim // It isn't feasible for the original value to be null. 1138234353Sdim // Propagate this constraint. 1139234353Sdim Constraint = svalBuilder.evalEQ(state, SymVal, 1140234353Sdim svalBuilder.makeZeroVal(U->getType())); 1141296417Sdim 1142234353Sdim state = state->assume(Constraint, false); 1143234353Sdim assert(state); 1144226586Sdim } 1145226586Sdim } 1146226586Sdim } 1147296417Sdim 1148234353Sdim // Since the lvalue-to-rvalue conversion is explicit in the AST, 1149234353Sdim // we bind an l-value if the operator is prefix and an lvalue (in C++). 1150239462Sdim if (U->isGLValue()) 1151234353Sdim state = state->BindExpr(U, LCtx, loc); 1152234353Sdim else 1153234353Sdim state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result); 1154296417Sdim 1155234353Sdim // Perform the store. 1156234353Sdim Bldr.takeNodes(*I); 1157234353Sdim ExplodedNodeSet Dst3; 1158344779Sdim evalStore(Dst3, U, Ex, *I, state, loc, Result); 1159234353Sdim Bldr.addNodes(Dst3); 1160226586Sdim } 1161234353Sdim Dst.insert(Dst2); 1162226586Sdim} 1163