clang API Documentation
00001 //=-- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-= 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines a meta-engine for path-sensitive dataflow analysis that 00011 // is built on GREngine, but provides the boilerplate to execute transfer 00012 // functions and build the ExplodedGraph at the expression level. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 00017 #include "PrettyStackTraceLocationContext.h" 00018 #include "clang/AST/CharUnits.h" 00019 #include "clang/AST/ParentMap.h" 00020 #include "clang/AST/StmtCXX.h" 00021 #include "clang/AST/StmtObjC.h" 00022 #include "clang/Basic/Builtins.h" 00023 #include "clang/Basic/PrettyStackTrace.h" 00024 #include "clang/Basic/SourceManager.h" 00025 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 00026 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 00027 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 00028 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 00029 #include "llvm/ADT/ImmutableList.h" 00030 #include "llvm/ADT/Statistic.h" 00031 #include "llvm/Support/raw_ostream.h" 00032 00033 #ifndef NDEBUG 00034 #include "llvm/Support/GraphWriter.h" 00035 #endif 00036 00037 using namespace clang; 00038 using namespace ento; 00039 using llvm::APSInt; 00040 00041 #define DEBUG_TYPE "ExprEngine" 00042 00043 STATISTIC(NumRemoveDeadBindings, 00044 "The # of times RemoveDeadBindings is called"); 00045 STATISTIC(NumMaxBlockCountReached, 00046 "The # of aborted paths due to reaching the maximum block count in " 00047 "a top level function"); 00048 STATISTIC(NumMaxBlockCountReachedInInlined, 00049 "The # of aborted paths due to reaching the maximum block count in " 00050 "an inlined function"); 00051 STATISTIC(NumTimesRetriedWithoutInlining, 00052 "The # of times we re-evaluated a call without inlining"); 00053 00054 typedef std::pair<const CXXBindTemporaryExpr *, const StackFrameContext *> 00055 CXXBindTemporaryContext; 00056 00057 // Keeps track of whether CXXBindTemporaryExpr nodes have been evaluated. 00058 // The StackFrameContext assures that nested calls due to inlined recursive 00059 // functions do not interfere. 00060 REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedTemporariesSet, 00061 llvm::ImmutableSet<CXXBindTemporaryContext>) 00062 00063 //===----------------------------------------------------------------------===// 00064 // Engine construction and deletion. 00065 //===----------------------------------------------------------------------===// 00066 00067 static const char* TagProviderName = "ExprEngine"; 00068 00069 ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled, 00070 SetOfConstDecls *VisitedCalleesIn, 00071 FunctionSummariesTy *FS, 00072 InliningModes HowToInlineIn) 00073 : AMgr(mgr), 00074 AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()), 00075 Engine(*this, FS), 00076 G(Engine.getGraph()), 00077 StateMgr(getContext(), mgr.getStoreManagerCreator(), 00078 mgr.getConstraintManagerCreator(), G.getAllocator(), 00079 this), 00080 SymMgr(StateMgr.getSymbolManager()), 00081 svalBuilder(StateMgr.getSValBuilder()), 00082 currStmtIdx(0), currBldrCtx(nullptr), 00083 ObjCNoRet(mgr.getASTContext()), 00084 ObjCGCEnabled(gcEnabled), BR(mgr, *this), 00085 VisitedCallees(VisitedCalleesIn), 00086 HowToInline(HowToInlineIn) 00087 { 00088 unsigned TrimInterval = mgr.options.getGraphTrimInterval(); 00089 if (TrimInterval != 0) { 00090 // Enable eager node reclaimation when constructing the ExplodedGraph. 00091 G.enableNodeReclamation(TrimInterval); 00092 } 00093 } 00094 00095 ExprEngine::~ExprEngine() { 00096 BR.FlushReports(); 00097 } 00098 00099 //===----------------------------------------------------------------------===// 00100 // Utility methods. 00101 //===----------------------------------------------------------------------===// 00102 00103 ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { 00104 ProgramStateRef state = StateMgr.getInitialState(InitLoc); 00105 const Decl *D = InitLoc->getDecl(); 00106 00107 // Preconditions. 00108 // FIXME: It would be nice if we had a more general mechanism to add 00109 // such preconditions. Some day. 00110 do { 00111 00112 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 00113 // Precondition: the first argument of 'main' is an integer guaranteed 00114 // to be > 0. 00115 const IdentifierInfo *II = FD->getIdentifier(); 00116 if (!II || !(II->getName() == "main" && FD->getNumParams() > 0)) 00117 break; 00118 00119 const ParmVarDecl *PD = FD->getParamDecl(0); 00120 QualType T = PD->getType(); 00121 const BuiltinType *BT = dyn_cast<BuiltinType>(T); 00122 if (!BT || !BT->isInteger()) 00123 break; 00124 00125 const MemRegion *R = state->getRegion(PD, InitLoc); 00126 if (!R) 00127 break; 00128 00129 SVal V = state->getSVal(loc::MemRegionVal(R)); 00130 SVal Constraint_untested = evalBinOp(state, BO_GT, V, 00131 svalBuilder.makeZeroVal(T), 00132 svalBuilder.getConditionType()); 00133 00134 Optional<DefinedOrUnknownSVal> Constraint = 00135 Constraint_untested.getAs<DefinedOrUnknownSVal>(); 00136 00137 if (!Constraint) 00138 break; 00139 00140 if (ProgramStateRef newState = state->assume(*Constraint, true)) 00141 state = newState; 00142 } 00143 break; 00144 } 00145 while (0); 00146 00147 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 00148 // Precondition: 'self' is always non-null upon entry to an Objective-C 00149 // method. 00150 const ImplicitParamDecl *SelfD = MD->getSelfDecl(); 00151 const MemRegion *R = state->getRegion(SelfD, InitLoc); 00152 SVal V = state->getSVal(loc::MemRegionVal(R)); 00153 00154 if (Optional<Loc> LV = V.getAs<Loc>()) { 00155 // Assume that the pointer value in 'self' is non-null. 00156 state = state->assume(*LV, true); 00157 assert(state && "'self' cannot be null"); 00158 } 00159 } 00160 00161 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { 00162 if (!MD->isStatic()) { 00163 // Precondition: 'this' is always non-null upon entry to the 00164 // top-level function. This is our starting assumption for 00165 // analyzing an "open" program. 00166 const StackFrameContext *SFC = InitLoc->getCurrentStackFrame(); 00167 if (SFC->getParent() == nullptr) { 00168 loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC); 00169 SVal V = state->getSVal(L); 00170 if (Optional<Loc> LV = V.getAs<Loc>()) { 00171 state = state->assume(*LV, true); 00172 assert(state && "'this' cannot be null"); 00173 } 00174 } 00175 } 00176 } 00177 00178 return state; 00179 } 00180 00181 ProgramStateRef 00182 ExprEngine::createTemporaryRegionIfNeeded(ProgramStateRef State, 00183 const LocationContext *LC, 00184 const Expr *Ex, 00185 const Expr *Result) { 00186 SVal V = State->getSVal(Ex, LC); 00187 if (!Result) { 00188 // If we don't have an explicit result expression, we're in "if needed" 00189 // mode. Only create a region if the current value is a NonLoc. 00190 if (!V.getAs<NonLoc>()) 00191 return State; 00192 Result = Ex; 00193 } else { 00194 // We need to create a region no matter what. For sanity, make sure we don't 00195 // try to stuff a Loc into a non-pointer temporary region. 00196 assert(!V.getAs<Loc>() || Loc::isLocType(Result->getType()) || 00197 Result->getType()->isMemberPointerType()); 00198 } 00199 00200 ProgramStateManager &StateMgr = State->getStateManager(); 00201 MemRegionManager &MRMgr = StateMgr.getRegionManager(); 00202 StoreManager &StoreMgr = StateMgr.getStoreManager(); 00203 00204 // We need to be careful about treating a derived type's value as 00205 // bindings for a base type. Unless we're creating a temporary pointer region, 00206 // start by stripping and recording base casts. 00207 SmallVector<const CastExpr *, 4> Casts; 00208 const Expr *Inner = Ex->IgnoreParens(); 00209 if (!Loc::isLocType(Result->getType())) { 00210 while (const CastExpr *CE = dyn_cast<CastExpr>(Inner)) { 00211 if (CE->getCastKind() == CK_DerivedToBase || 00212 CE->getCastKind() == CK_UncheckedDerivedToBase) 00213 Casts.push_back(CE); 00214 else if (CE->getCastKind() != CK_NoOp) 00215 break; 00216 00217 Inner = CE->getSubExpr()->IgnoreParens(); 00218 } 00219 } 00220 00221 // Create a temporary object region for the inner expression (which may have 00222 // a more derived type) and bind the value into it. 00223 const TypedValueRegion *TR = nullptr; 00224 if (const MaterializeTemporaryExpr *MT = 00225 dyn_cast<MaterializeTemporaryExpr>(Result)) { 00226 StorageDuration SD = MT->getStorageDuration(); 00227 // If this object is bound to a reference with static storage duration, we 00228 // put it in a different region to prevent "address leakage" warnings. 00229 if (SD == SD_Static || SD == SD_Thread) 00230 TR = MRMgr.getCXXStaticTempObjectRegion(Inner); 00231 } 00232 if (!TR) 00233 TR = MRMgr.getCXXTempObjectRegion(Inner, LC); 00234 00235 SVal Reg = loc::MemRegionVal(TR); 00236 00237 if (V.isUnknown()) 00238 V = getSValBuilder().conjureSymbolVal(Result, LC, TR->getValueType(), 00239 currBldrCtx->blockCount()); 00240 State = State->bindLoc(Reg, V); 00241 00242 // Re-apply the casts (from innermost to outermost) for type sanity. 00243 for (SmallVectorImpl<const CastExpr *>::reverse_iterator I = Casts.rbegin(), 00244 E = Casts.rend(); 00245 I != E; ++I) { 00246 Reg = StoreMgr.evalDerivedToBase(Reg, *I); 00247 } 00248 00249 State = State->BindExpr(Result, LC, Reg); 00250 return State; 00251 } 00252 00253 //===----------------------------------------------------------------------===// 00254 // Top-level transfer function logic (Dispatcher). 00255 //===----------------------------------------------------------------------===// 00256 00257 /// evalAssume - Called by ConstraintManager. Used to call checker-specific 00258 /// logic for handling assumptions on symbolic values. 00259 ProgramStateRef ExprEngine::processAssume(ProgramStateRef state, 00260 SVal cond, bool assumption) { 00261 return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption); 00262 } 00263 00264 bool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state) { 00265 return getCheckerManager().wantsRegionChangeUpdate(state); 00266 } 00267 00268 ProgramStateRef 00269 ExprEngine::processRegionChanges(ProgramStateRef state, 00270 const InvalidatedSymbols *invalidated, 00271 ArrayRef<const MemRegion *> Explicits, 00272 ArrayRef<const MemRegion *> Regions, 00273 const CallEvent *Call) { 00274 return getCheckerManager().runCheckersForRegionChanges(state, invalidated, 00275 Explicits, Regions, Call); 00276 } 00277 00278 void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State, 00279 const char *NL, const char *Sep) { 00280 getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep); 00281 } 00282 00283 void ExprEngine::processEndWorklist(bool hasWorkRemaining) { 00284 getCheckerManager().runCheckersForEndAnalysis(G, BR, *this); 00285 } 00286 00287 void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred, 00288 unsigned StmtIdx, NodeBuilderContext *Ctx) { 00289 PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); 00290 currStmtIdx = StmtIdx; 00291 currBldrCtx = Ctx; 00292 00293 switch (E.getKind()) { 00294 case CFGElement::Statement: 00295 ProcessStmt(const_cast<Stmt*>(E.castAs<CFGStmt>().getStmt()), Pred); 00296 return; 00297 case CFGElement::Initializer: 00298 ProcessInitializer(E.castAs<CFGInitializer>().getInitializer(), Pred); 00299 return; 00300 case CFGElement::NewAllocator: 00301 ProcessNewAllocator(E.castAs<CFGNewAllocator>().getAllocatorExpr(), 00302 Pred); 00303 return; 00304 case CFGElement::AutomaticObjectDtor: 00305 case CFGElement::DeleteDtor: 00306 case CFGElement::BaseDtor: 00307 case CFGElement::MemberDtor: 00308 case CFGElement::TemporaryDtor: 00309 ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred); 00310 return; 00311 } 00312 } 00313 00314 static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, 00315 const CFGStmt S, 00316 const ExplodedNode *Pred, 00317 const LocationContext *LC) { 00318 00319 // Are we never purging state values? 00320 if (AMgr.options.AnalysisPurgeOpt == PurgeNone) 00321 return false; 00322 00323 // Is this the beginning of a basic block? 00324 if (Pred->getLocation().getAs<BlockEntrance>()) 00325 return true; 00326 00327 // Is this on a non-expression? 00328 if (!isa<Expr>(S.getStmt())) 00329 return true; 00330 00331 // Run before processing a call. 00332 if (CallEvent::isCallStmt(S.getStmt())) 00333 return true; 00334 00335 // Is this an expression that is consumed by another expression? If so, 00336 // postpone cleaning out the state. 00337 ParentMap &PM = LC->getAnalysisDeclContext()->getParentMap(); 00338 return !PM.isConsumedExpr(cast<Expr>(S.getStmt())); 00339 } 00340 00341 void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out, 00342 const Stmt *ReferenceStmt, 00343 const LocationContext *LC, 00344 const Stmt *DiagnosticStmt, 00345 ProgramPoint::Kind K) { 00346 assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind || 00347 ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt)) 00348 && "PostStmt is not generally supported by the SymbolReaper yet"); 00349 assert(LC && "Must pass the current (or expiring) LocationContext"); 00350 00351 if (!DiagnosticStmt) { 00352 DiagnosticStmt = ReferenceStmt; 00353 assert(DiagnosticStmt && "Required for clearing a LocationContext"); 00354 } 00355 00356 NumRemoveDeadBindings++; 00357 ProgramStateRef CleanedState = Pred->getState(); 00358 00359 // LC is the location context being destroyed, but SymbolReaper wants a 00360 // location context that is still live. (If this is the top-level stack 00361 // frame, this will be null.) 00362 if (!ReferenceStmt) { 00363 assert(K == ProgramPoint::PostStmtPurgeDeadSymbolsKind && 00364 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext"); 00365 LC = LC->getParent(); 00366 } 00367 00368 const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : nullptr; 00369 SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager()); 00370 00371 getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper); 00372 00373 // Create a state in which dead bindings are removed from the environment 00374 // and the store. TODO: The function should just return new env and store, 00375 // not a new state. 00376 CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper); 00377 00378 // Process any special transfer function for dead symbols. 00379 // A tag to track convenience transitions, which can be removed at cleanup. 00380 static SimpleProgramPointTag cleanupTag(TagProviderName, "Clean Node"); 00381 if (!SymReaper.hasDeadSymbols()) { 00382 // Generate a CleanedNode that has the environment and store cleaned 00383 // up. Since no symbols are dead, we can optimize and not clean out 00384 // the constraint manager. 00385 StmtNodeBuilder Bldr(Pred, Out, *currBldrCtx); 00386 Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K); 00387 00388 } else { 00389 // Call checkers with the non-cleaned state so that they could query the 00390 // values of the soon to be dead symbols. 00391 ExplodedNodeSet CheckedSet; 00392 getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper, 00393 DiagnosticStmt, *this, K); 00394 00395 // For each node in CheckedSet, generate CleanedNodes that have the 00396 // environment, the store, and the constraints cleaned up but have the 00397 // user-supplied states as the predecessors. 00398 StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx); 00399 for (ExplodedNodeSet::const_iterator 00400 I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) { 00401 ProgramStateRef CheckerState = (*I)->getState(); 00402 00403 // The constraint manager has not been cleaned up yet, so clean up now. 00404 CheckerState = getConstraintManager().removeDeadBindings(CheckerState, 00405 SymReaper); 00406 00407 assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->getState()) && 00408 "Checkers are not allowed to modify the Environment as a part of " 00409 "checkDeadSymbols processing."); 00410 assert(StateMgr.haveEqualStores(CheckerState, Pred->getState()) && 00411 "Checkers are not allowed to modify the Store as a part of " 00412 "checkDeadSymbols processing."); 00413 00414 // Create a state based on CleanedState with CheckerState GDM and 00415 // generate a transition to that state. 00416 ProgramStateRef CleanedCheckerSt = 00417 StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState); 00418 Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K); 00419 } 00420 } 00421 } 00422 00423 void ExprEngine::ProcessStmt(const CFGStmt S, 00424 ExplodedNode *Pred) { 00425 // Reclaim any unnecessary nodes in the ExplodedGraph. 00426 G.reclaimRecentlyAllocatedNodes(); 00427 00428 const Stmt *currStmt = S.getStmt(); 00429 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 00430 currStmt->getLocStart(), 00431 "Error evaluating statement"); 00432 00433 // Remove dead bindings and symbols. 00434 ExplodedNodeSet CleanedStates; 00435 if (shouldRemoveDeadBindings(AMgr, S, Pred, Pred->getLocationContext())){ 00436 removeDead(Pred, CleanedStates, currStmt, Pred->getLocationContext()); 00437 } else 00438 CleanedStates.Add(Pred); 00439 00440 // Visit the statement. 00441 ExplodedNodeSet Dst; 00442 for (ExplodedNodeSet::iterator I = CleanedStates.begin(), 00443 E = CleanedStates.end(); I != E; ++I) { 00444 ExplodedNodeSet DstI; 00445 // Visit the statement. 00446 Visit(currStmt, *I, DstI); 00447 Dst.insert(DstI); 00448 } 00449 00450 // Enqueue the new nodes onto the work list. 00451 Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 00452 } 00453 00454 void ExprEngine::ProcessInitializer(const CFGInitializer Init, 00455 ExplodedNode *Pred) { 00456 const CXXCtorInitializer *BMI = Init.getInitializer(); 00457 00458 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 00459 BMI->getSourceLocation(), 00460 "Error evaluating initializer"); 00461 00462 // We don't clean up dead bindings here. 00463 const StackFrameContext *stackFrame = 00464 cast<StackFrameContext>(Pred->getLocationContext()); 00465 const CXXConstructorDecl *decl = 00466 cast<CXXConstructorDecl>(stackFrame->getDecl()); 00467 00468 ProgramStateRef State = Pred->getState(); 00469 SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame)); 00470 00471 ExplodedNodeSet Tmp(Pred); 00472 SVal FieldLoc; 00473 00474 // Evaluate the initializer, if necessary 00475 if (BMI->isAnyMemberInitializer()) { 00476 // Constructors build the object directly in the field, 00477 // but non-objects must be copied in from the initializer. 00478 const Expr *Init = BMI->getInit()->IgnoreImplicit(); 00479 if (!isa<CXXConstructExpr>(Init)) { 00480 const ValueDecl *Field; 00481 if (BMI->isIndirectMemberInitializer()) { 00482 Field = BMI->getIndirectMember(); 00483 FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal); 00484 } else { 00485 Field = BMI->getMember(); 00486 FieldLoc = State->getLValue(BMI->getMember(), thisVal); 00487 } 00488 00489 SVal InitVal; 00490 if (BMI->getNumArrayIndices() > 0) { 00491 // Handle arrays of trivial type. We can represent this with a 00492 // primitive load/copy from the base array region. 00493 const ArraySubscriptExpr *ASE; 00494 while ((ASE = dyn_cast<ArraySubscriptExpr>(Init))) 00495 Init = ASE->getBase()->IgnoreImplicit(); 00496 00497 SVal LValue = State->getSVal(Init, stackFrame); 00498 if (Optional<Loc> LValueLoc = LValue.getAs<Loc>()) 00499 InitVal = State->getSVal(*LValueLoc); 00500 00501 // If we fail to get the value for some reason, use a symbolic value. 00502 if (InitVal.isUnknownOrUndef()) { 00503 SValBuilder &SVB = getSValBuilder(); 00504 InitVal = SVB.conjureSymbolVal(BMI->getInit(), stackFrame, 00505 Field->getType(), 00506 currBldrCtx->blockCount()); 00507 } 00508 } else { 00509 InitVal = State->getSVal(BMI->getInit(), stackFrame); 00510 } 00511 00512 assert(Tmp.size() == 1 && "have not generated any new nodes yet"); 00513 assert(*Tmp.begin() == Pred && "have not generated any new nodes yet"); 00514 Tmp.clear(); 00515 00516 PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame); 00517 evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP); 00518 } 00519 } else { 00520 assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer()); 00521 // We already did all the work when visiting the CXXConstructExpr. 00522 } 00523 00524 // Construct PostInitializer nodes whether the state changed or not, 00525 // so that the diagnostics don't get confused. 00526 PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame); 00527 ExplodedNodeSet Dst; 00528 NodeBuilder Bldr(Tmp, Dst, *currBldrCtx); 00529 for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) { 00530 ExplodedNode *N = *I; 00531 Bldr.generateNode(PP, N->getState(), N); 00532 } 00533 00534 // Enqueue the new nodes onto the work list. 00535 Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 00536 } 00537 00538 void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, 00539 ExplodedNode *Pred) { 00540 ExplodedNodeSet Dst; 00541 switch (D.getKind()) { 00542 case CFGElement::AutomaticObjectDtor: 00543 ProcessAutomaticObjDtor(D.castAs<CFGAutomaticObjDtor>(), Pred, Dst); 00544 break; 00545 case CFGElement::BaseDtor: 00546 ProcessBaseDtor(D.castAs<CFGBaseDtor>(), Pred, Dst); 00547 break; 00548 case CFGElement::MemberDtor: 00549 ProcessMemberDtor(D.castAs<CFGMemberDtor>(), Pred, Dst); 00550 break; 00551 case CFGElement::TemporaryDtor: 00552 ProcessTemporaryDtor(D.castAs<CFGTemporaryDtor>(), Pred, Dst); 00553 break; 00554 case CFGElement::DeleteDtor: 00555 ProcessDeleteDtor(D.castAs<CFGDeleteDtor>(), Pred, Dst); 00556 break; 00557 default: 00558 llvm_unreachable("Unexpected dtor kind."); 00559 } 00560 00561 // Enqueue the new nodes onto the work list. 00562 Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 00563 } 00564 00565 void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE, 00566 ExplodedNode *Pred) { 00567 ExplodedNodeSet Dst; 00568 AnalysisManager &AMgr = getAnalysisManager(); 00569 AnalyzerOptions &Opts = AMgr.options; 00570 // TODO: We're not evaluating allocators for all cases just yet as 00571 // we're not handling the return value correctly, which causes false 00572 // positives when the alpha.cplusplus.NewDeleteLeaks check is on. 00573 if (Opts.mayInlineCXXAllocator()) 00574 VisitCXXNewAllocatorCall(NE, Pred, Dst); 00575 else { 00576 NodeBuilder Bldr(Pred, Dst, *currBldrCtx); 00577 const LocationContext *LCtx = Pred->getLocationContext(); 00578 PostImplicitCall PP(NE->getOperatorNew(), NE->getLocStart(), LCtx); 00579 Bldr.generateNode(PP, Pred->getState(), Pred); 00580 } 00581 Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 00582 } 00583 00584 void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor, 00585 ExplodedNode *Pred, 00586 ExplodedNodeSet &Dst) { 00587 const VarDecl *varDecl = Dtor.getVarDecl(); 00588 QualType varType = varDecl->getType(); 00589 00590 ProgramStateRef state = Pred->getState(); 00591 SVal dest = state->getLValue(varDecl, Pred->getLocationContext()); 00592 const MemRegion *Region = dest.castAs<loc::MemRegionVal>().getRegion(); 00593 00594 if (const ReferenceType *refType = varType->getAs<ReferenceType>()) { 00595 varType = refType->getPointeeType(); 00596 Region = state->getSVal(Region).getAsRegion(); 00597 } 00598 00599 VisitCXXDestructor(varType, Region, Dtor.getTriggerStmt(), /*IsBase=*/ false, 00600 Pred, Dst); 00601 } 00602 00603 void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, 00604 ExplodedNode *Pred, 00605 ExplodedNodeSet &Dst) { 00606 ProgramStateRef State = Pred->getState(); 00607 const LocationContext *LCtx = Pred->getLocationContext(); 00608 const CXXDeleteExpr *DE = Dtor.getDeleteExpr(); 00609 const Stmt *Arg = DE->getArgument(); 00610 SVal ArgVal = State->getSVal(Arg, LCtx); 00611 00612 // If the argument to delete is known to be a null value, 00613 // don't run destructor. 00614 if (State->isNull(ArgVal).isConstrainedTrue()) { 00615 QualType DTy = DE->getDestroyedType(); 00616 QualType BTy = getContext().getBaseElementType(DTy); 00617 const CXXRecordDecl *RD = BTy->getAsCXXRecordDecl(); 00618 const CXXDestructorDecl *Dtor = RD->getDestructor(); 00619 00620 PostImplicitCall PP(Dtor, DE->getLocStart(), LCtx); 00621 NodeBuilder Bldr(Pred, Dst, *currBldrCtx); 00622 Bldr.generateNode(PP, Pred->getState(), Pred); 00623 return; 00624 } 00625 00626 VisitCXXDestructor(DE->getDestroyedType(), 00627 ArgVal.getAsRegion(), 00628 DE, /*IsBase=*/ false, 00629 Pred, Dst); 00630 } 00631 00632 void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, 00633 ExplodedNode *Pred, ExplodedNodeSet &Dst) { 00634 const LocationContext *LCtx = Pred->getLocationContext(); 00635 00636 const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 00637 Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, 00638 LCtx->getCurrentStackFrame()); 00639 SVal ThisVal = Pred->getState()->getSVal(ThisPtr); 00640 00641 // Create the base object region. 00642 const CXXBaseSpecifier *Base = D.getBaseSpecifier(); 00643 QualType BaseTy = Base->getType(); 00644 SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy, 00645 Base->isVirtual()); 00646 00647 VisitCXXDestructor(BaseTy, BaseVal.castAs<loc::MemRegionVal>().getRegion(), 00648 CurDtor->getBody(), /*IsBase=*/ true, Pred, Dst); 00649 } 00650 00651 void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, 00652 ExplodedNode *Pred, ExplodedNodeSet &Dst) { 00653 const FieldDecl *Member = D.getFieldDecl(); 00654 ProgramStateRef State = Pred->getState(); 00655 const LocationContext *LCtx = Pred->getLocationContext(); 00656 00657 const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 00658 Loc ThisVal = getSValBuilder().getCXXThis(CurDtor, 00659 LCtx->getCurrentStackFrame()); 00660 SVal FieldVal = 00661 State->getLValue(Member, State->getSVal(ThisVal).castAs<Loc>()); 00662 00663 VisitCXXDestructor(Member->getType(), 00664 FieldVal.castAs<loc::MemRegionVal>().getRegion(), 00665 CurDtor->getBody(), /*IsBase=*/false, Pred, Dst); 00666 } 00667 00668 void ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D, 00669 ExplodedNode *Pred, 00670 ExplodedNodeSet &Dst) { 00671 ExplodedNodeSet CleanDtorState; 00672 StmtNodeBuilder StmtBldr(Pred, CleanDtorState, *currBldrCtx); 00673 ProgramStateRef State = Pred->getState(); 00674 if (State->contains<InitializedTemporariesSet>( 00675 std::make_pair(D.getBindTemporaryExpr(), Pred->getStackFrame()))) { 00676 // FIXME: Currently we insert temporary destructors for default parameters, 00677 // but we don't insert the constructors. 00678 State = State->remove<InitializedTemporariesSet>( 00679 std::make_pair(D.getBindTemporaryExpr(), Pred->getStackFrame())); 00680 } 00681 StmtBldr.generateNode(D.getBindTemporaryExpr(), Pred, State); 00682 00683 QualType varType = D.getBindTemporaryExpr()->getSubExpr()->getType(); 00684 // FIXME: Currently CleanDtorState can be empty here due to temporaries being 00685 // bound to default parameters. 00686 assert(CleanDtorState.size() <= 1); 00687 ExplodedNode *CleanPred = 00688 CleanDtorState.empty() ? Pred : *CleanDtorState.begin(); 00689 // FIXME: Inlining of temporary destructors is not supported yet anyway, so 00690 // we just put a NULL region for now. This will need to be changed later. 00691 VisitCXXDestructor(varType, nullptr, D.getBindTemporaryExpr(), 00692 /*IsBase=*/false, CleanPred, Dst); 00693 } 00694 00695 void ExprEngine::processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, 00696 NodeBuilderContext &BldCtx, 00697 ExplodedNode *Pred, 00698 ExplodedNodeSet &Dst, 00699 const CFGBlock *DstT, 00700 const CFGBlock *DstF) { 00701 BranchNodeBuilder TempDtorBuilder(Pred, Dst, BldCtx, DstT, DstF); 00702 if (Pred->getState()->contains<InitializedTemporariesSet>( 00703 std::make_pair(BTE, Pred->getStackFrame()))) { 00704 TempDtorBuilder.markInfeasible(false); 00705 TempDtorBuilder.generateNode(Pred->getState(), true, Pred); 00706 } else { 00707 TempDtorBuilder.markInfeasible(true); 00708 TempDtorBuilder.generateNode(Pred->getState(), false, Pred); 00709 } 00710 } 00711 00712 void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, 00713 ExplodedNodeSet &PreVisit, 00714 ExplodedNodeSet &Dst) { 00715 if (!getAnalysisManager().options.includeTemporaryDtorsInCFG()) { 00716 // In case we don't have temporary destructors in the CFG, do not mark 00717 // the initialization - we would otherwise never clean it up. 00718 Dst = PreVisit; 00719 return; 00720 } 00721 StmtNodeBuilder StmtBldr(PreVisit, Dst, *currBldrCtx); 00722 for (ExplodedNode *Node : PreVisit) { 00723 ProgramStateRef State = Node->getState(); 00724 00725 if (!State->contains<InitializedTemporariesSet>( 00726 std::make_pair(BTE, Node->getStackFrame()))) { 00727 // FIXME: Currently the state might already contain the marker due to 00728 // incorrect handling of temporaries bound to default parameters; for 00729 // those, we currently skip the CXXBindTemporaryExpr but rely on adding 00730 // temporary destructor nodes. 00731 State = State->add<InitializedTemporariesSet>( 00732 std::make_pair(BTE, Node->getStackFrame())); 00733 } 00734 StmtBldr.generateNode(BTE, Node, State); 00735 } 00736 } 00737 00738 void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, 00739 ExplodedNodeSet &DstTop) { 00740 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 00741 S->getLocStart(), 00742 "Error evaluating statement"); 00743 ExplodedNodeSet Dst; 00744 StmtNodeBuilder Bldr(Pred, DstTop, *currBldrCtx); 00745 00746 assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens()); 00747 00748 switch (S->getStmtClass()) { 00749 // C++ and ARC stuff we don't support yet. 00750 case Expr::ObjCIndirectCopyRestoreExprClass: 00751 case Stmt::CXXDependentScopeMemberExprClass: 00752 case Stmt::CXXTryStmtClass: 00753 case Stmt::CXXTypeidExprClass: 00754 case Stmt::CXXUuidofExprClass: 00755 case Stmt::CXXFoldExprClass: 00756 case Stmt::MSPropertyRefExprClass: 00757 case Stmt::CXXUnresolvedConstructExprClass: 00758 case Stmt::DependentScopeDeclRefExprClass: 00759 case Stmt::TypeTraitExprClass: 00760 case Stmt::ArrayTypeTraitExprClass: 00761 case Stmt::ExpressionTraitExprClass: 00762 case Stmt::UnresolvedLookupExprClass: 00763 case Stmt::UnresolvedMemberExprClass: 00764 case Stmt::TypoExprClass: 00765 case Stmt::CXXNoexceptExprClass: 00766 case Stmt::PackExpansionExprClass: 00767 case Stmt::SubstNonTypeTemplateParmPackExprClass: 00768 case Stmt::FunctionParmPackExprClass: 00769 case Stmt::SEHTryStmtClass: 00770 case Stmt::SEHExceptStmtClass: 00771 case Stmt::SEHLeaveStmtClass: 00772 case Stmt::LambdaExprClass: 00773 case Stmt::SEHFinallyStmtClass: { 00774 const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); 00775 Engine.addAbortedBlock(node, currBldrCtx->getBlock()); 00776 break; 00777 } 00778 00779 case Stmt::ParenExprClass: 00780 llvm_unreachable("ParenExprs already handled."); 00781 case Stmt::GenericSelectionExprClass: 00782 llvm_unreachable("GenericSelectionExprs already handled."); 00783 // Cases that should never be evaluated simply because they shouldn't 00784 // appear in the CFG. 00785 case Stmt::BreakStmtClass: 00786 case Stmt::CaseStmtClass: 00787 case Stmt::CompoundStmtClass: 00788 case Stmt::ContinueStmtClass: 00789 case Stmt::CXXForRangeStmtClass: 00790 case Stmt::DefaultStmtClass: 00791 case Stmt::DoStmtClass: 00792 case Stmt::ForStmtClass: 00793 case Stmt::GotoStmtClass: 00794 case Stmt::IfStmtClass: 00795 case Stmt::IndirectGotoStmtClass: 00796 case Stmt::LabelStmtClass: 00797 case Stmt::NoStmtClass: 00798 case Stmt::NullStmtClass: 00799 case Stmt::SwitchStmtClass: 00800 case Stmt::WhileStmtClass: 00801 case Expr::MSDependentExistsStmtClass: 00802 case Stmt::CapturedStmtClass: 00803 case Stmt::OMPParallelDirectiveClass: 00804 case Stmt::OMPSimdDirectiveClass: 00805 case Stmt::OMPForDirectiveClass: 00806 case Stmt::OMPForSimdDirectiveClass: 00807 case Stmt::OMPSectionsDirectiveClass: 00808 case Stmt::OMPSectionDirectiveClass: 00809 case Stmt::OMPSingleDirectiveClass: 00810 case Stmt::OMPMasterDirectiveClass: 00811 case Stmt::OMPCriticalDirectiveClass: 00812 case Stmt::OMPParallelForDirectiveClass: 00813 case Stmt::OMPParallelForSimdDirectiveClass: 00814 case Stmt::OMPParallelSectionsDirectiveClass: 00815 case Stmt::OMPTaskDirectiveClass: 00816 case Stmt::OMPTaskyieldDirectiveClass: 00817 case Stmt::OMPBarrierDirectiveClass: 00818 case Stmt::OMPTaskwaitDirectiveClass: 00819 case Stmt::OMPFlushDirectiveClass: 00820 case Stmt::OMPOrderedDirectiveClass: 00821 case Stmt::OMPAtomicDirectiveClass: 00822 case Stmt::OMPTargetDirectiveClass: 00823 case Stmt::OMPTeamsDirectiveClass: 00824 llvm_unreachable("Stmt should not be in analyzer evaluation loop"); 00825 00826 case Stmt::ObjCSubscriptRefExprClass: 00827 case Stmt::ObjCPropertyRefExprClass: 00828 llvm_unreachable("These are handled by PseudoObjectExpr"); 00829 00830 case Stmt::GNUNullExprClass: { 00831 // GNU __null is a pointer-width integer, not an actual pointer. 00832 ProgramStateRef state = Pred->getState(); 00833 state = state->BindExpr(S, Pred->getLocationContext(), 00834 svalBuilder.makeIntValWithPtrWidth(0, false)); 00835 Bldr.generateNode(S, Pred, state); 00836 break; 00837 } 00838 00839 case Stmt::ObjCAtSynchronizedStmtClass: 00840 Bldr.takeNodes(Pred); 00841 VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst); 00842 Bldr.addNodes(Dst); 00843 break; 00844 00845 case Stmt::ExprWithCleanupsClass: 00846 // Handled due to fully linearised CFG. 00847 break; 00848 00849 case Stmt::CXXBindTemporaryExprClass: { 00850 Bldr.takeNodes(Pred); 00851 ExplodedNodeSet PreVisit; 00852 getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); 00853 ExplodedNodeSet Next; 00854 VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), PreVisit, Next); 00855 getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this); 00856 Bldr.addNodes(Dst); 00857 break; 00858 } 00859 00860 // Cases not handled yet; but will handle some day. 00861 case Stmt::DesignatedInitExprClass: 00862 case Stmt::ExtVectorElementExprClass: 00863 case Stmt::ImaginaryLiteralClass: 00864 case Stmt::ObjCAtCatchStmtClass: 00865 case Stmt::ObjCAtFinallyStmtClass: 00866 case Stmt::ObjCAtTryStmtClass: 00867 case Stmt::ObjCAutoreleasePoolStmtClass: 00868 case Stmt::ObjCEncodeExprClass: 00869 case Stmt::ObjCIsaExprClass: 00870 case Stmt::ObjCProtocolExprClass: 00871 case Stmt::ObjCSelectorExprClass: 00872 case Stmt::ParenListExprClass: 00873 case Stmt::ShuffleVectorExprClass: 00874 case Stmt::ConvertVectorExprClass: 00875 case Stmt::VAArgExprClass: 00876 case Stmt::CUDAKernelCallExprClass: 00877 case Stmt::OpaqueValueExprClass: 00878 case Stmt::AsTypeExprClass: 00879 case Stmt::AtomicExprClass: 00880 // Fall through. 00881 00882 // Cases we intentionally don't evaluate, since they don't need 00883 // to be explicitly evaluated. 00884 case Stmt::PredefinedExprClass: 00885 case Stmt::AddrLabelExprClass: 00886 case Stmt::AttributedStmtClass: 00887 case Stmt::IntegerLiteralClass: 00888 case Stmt::CharacterLiteralClass: 00889 case Stmt::ImplicitValueInitExprClass: 00890 case Stmt::CXXScalarValueInitExprClass: 00891 case Stmt::CXXBoolLiteralExprClass: 00892 case Stmt::ObjCBoolLiteralExprClass: 00893 case Stmt::FloatingLiteralClass: 00894 case Stmt::SizeOfPackExprClass: 00895 case Stmt::StringLiteralClass: 00896 case Stmt::ObjCStringLiteralClass: 00897 case Stmt::CXXPseudoDestructorExprClass: 00898 case Stmt::SubstNonTypeTemplateParmExprClass: 00899 case Stmt::CXXNullPtrLiteralExprClass: { 00900 Bldr.takeNodes(Pred); 00901 ExplodedNodeSet preVisit; 00902 getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); 00903 getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this); 00904 Bldr.addNodes(Dst); 00905 break; 00906 } 00907 00908 case Stmt::CXXDefaultArgExprClass: 00909 case Stmt::CXXDefaultInitExprClass: { 00910 Bldr.takeNodes(Pred); 00911 ExplodedNodeSet PreVisit; 00912 getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); 00913 00914 ExplodedNodeSet Tmp; 00915 StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx); 00916 00917 const Expr *ArgE; 00918 if (const CXXDefaultArgExpr *DefE = dyn_cast<CXXDefaultArgExpr>(S)) 00919 ArgE = DefE->getExpr(); 00920 else if (const CXXDefaultInitExpr *DefE = dyn_cast<CXXDefaultInitExpr>(S)) 00921 ArgE = DefE->getExpr(); 00922 else 00923 llvm_unreachable("unknown constant wrapper kind"); 00924 00925 bool IsTemporary = false; 00926 if (const MaterializeTemporaryExpr *MTE = 00927 dyn_cast<MaterializeTemporaryExpr>(ArgE)) { 00928 ArgE = MTE->GetTemporaryExpr(); 00929 IsTemporary = true; 00930 } 00931 00932 Optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE); 00933 if (!ConstantVal) 00934 ConstantVal = UnknownVal(); 00935 00936 const LocationContext *LCtx = Pred->getLocationContext(); 00937 for (ExplodedNodeSet::iterator I = PreVisit.begin(), E = PreVisit.end(); 00938 I != E; ++I) { 00939 ProgramStateRef State = (*I)->getState(); 00940 State = State->BindExpr(S, LCtx, *ConstantVal); 00941 if (IsTemporary) 00942 State = createTemporaryRegionIfNeeded(State, LCtx, 00943 cast<Expr>(S), 00944 cast<Expr>(S)); 00945 Bldr2.generateNode(S, *I, State); 00946 } 00947 00948 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); 00949 Bldr.addNodes(Dst); 00950 break; 00951 } 00952 00953 // Cases we evaluate as opaque expressions, conjuring a symbol. 00954 case Stmt::CXXStdInitializerListExprClass: 00955 case Expr::ObjCArrayLiteralClass: 00956 case Expr::ObjCDictionaryLiteralClass: 00957 case Expr::ObjCBoxedExprClass: { 00958 Bldr.takeNodes(Pred); 00959 00960 ExplodedNodeSet preVisit; 00961 getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); 00962 00963 ExplodedNodeSet Tmp; 00964 StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx); 00965 00966 const Expr *Ex = cast<Expr>(S); 00967 QualType resultType = Ex->getType(); 00968 00969 for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end(); 00970 it != et; ++it) { 00971 ExplodedNode *N = *it; 00972 const LocationContext *LCtx = N->getLocationContext(); 00973 SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, 00974 resultType, 00975 currBldrCtx->blockCount()); 00976 ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result); 00977 Bldr2.generateNode(S, N, state); 00978 } 00979 00980 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); 00981 Bldr.addNodes(Dst); 00982 break; 00983 } 00984 00985 case Stmt::ArraySubscriptExprClass: 00986 Bldr.takeNodes(Pred); 00987 VisitLvalArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst); 00988 Bldr.addNodes(Dst); 00989 break; 00990 00991 case Stmt::GCCAsmStmtClass: 00992 Bldr.takeNodes(Pred); 00993 VisitGCCAsmStmt(cast<GCCAsmStmt>(S), Pred, Dst); 00994 Bldr.addNodes(Dst); 00995 break; 00996 00997 case Stmt::MSAsmStmtClass: 00998 Bldr.takeNodes(Pred); 00999 VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst); 01000 Bldr.addNodes(Dst); 01001 break; 01002 01003 case Stmt::BlockExprClass: 01004 Bldr.takeNodes(Pred); 01005 VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst); 01006 Bldr.addNodes(Dst); 01007 break; 01008 01009 case Stmt::BinaryOperatorClass: { 01010 const BinaryOperator* B = cast<BinaryOperator>(S); 01011 if (B->isLogicalOp()) { 01012 Bldr.takeNodes(Pred); 01013 VisitLogicalExpr(B, Pred, Dst); 01014 Bldr.addNodes(Dst); 01015 break; 01016 } 01017 else if (B->getOpcode() == BO_Comma) { 01018 ProgramStateRef state = Pred->getState(); 01019 Bldr.generateNode(B, Pred, 01020 state->BindExpr(B, Pred->getLocationContext(), 01021 state->getSVal(B->getRHS(), 01022 Pred->getLocationContext()))); 01023 break; 01024 } 01025 01026 Bldr.takeNodes(Pred); 01027 01028 if (AMgr.options.eagerlyAssumeBinOpBifurcation && 01029 (B->isRelationalOp() || B->isEqualityOp())) { 01030 ExplodedNodeSet Tmp; 01031 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp); 01032 evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S)); 01033 } 01034 else 01035 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); 01036 01037 Bldr.addNodes(Dst); 01038 break; 01039 } 01040 01041 case Stmt::CXXOperatorCallExprClass: { 01042 const CXXOperatorCallExpr *OCE = cast<CXXOperatorCallExpr>(S); 01043 01044 // For instance method operators, make sure the 'this' argument has a 01045 // valid region. 01046 const Decl *Callee = OCE->getCalleeDecl(); 01047 if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) { 01048 if (MD->isInstance()) { 01049 ProgramStateRef State = Pred->getState(); 01050 const LocationContext *LCtx = Pred->getLocationContext(); 01051 ProgramStateRef NewState = 01052 createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0)); 01053 if (NewState != State) { 01054 Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/nullptr, 01055 ProgramPoint::PreStmtKind); 01056 // Did we cache out? 01057 if (!Pred) 01058 break; 01059 } 01060 } 01061 } 01062 // FALLTHROUGH 01063 } 01064 case Stmt::CallExprClass: 01065 case Stmt::CXXMemberCallExprClass: 01066 case Stmt::UserDefinedLiteralClass: { 01067 Bldr.takeNodes(Pred); 01068 VisitCallExpr(cast<CallExpr>(S), Pred, Dst); 01069 Bldr.addNodes(Dst); 01070 break; 01071 } 01072 01073 case Stmt::CXXCatchStmtClass: { 01074 Bldr.takeNodes(Pred); 01075 VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst); 01076 Bldr.addNodes(Dst); 01077 break; 01078 } 01079 01080 case Stmt::CXXTemporaryObjectExprClass: 01081 case Stmt::CXXConstructExprClass: { 01082 Bldr.takeNodes(Pred); 01083 VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst); 01084 Bldr.addNodes(Dst); 01085 break; 01086 } 01087 01088 case Stmt::CXXNewExprClass: { 01089 Bldr.takeNodes(Pred); 01090 ExplodedNodeSet PostVisit; 01091 VisitCXXNewExpr(cast<CXXNewExpr>(S), Pred, PostVisit); 01092 getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); 01093 Bldr.addNodes(Dst); 01094 break; 01095 } 01096 01097 case Stmt::CXXDeleteExprClass: { 01098 Bldr.takeNodes(Pred); 01099 ExplodedNodeSet PreVisit; 01100 const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S); 01101 getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); 01102 01103 for (ExplodedNodeSet::iterator i = PreVisit.begin(), 01104 e = PreVisit.end(); i != e ; ++i) 01105 VisitCXXDeleteExpr(CDE, *i, Dst); 01106 01107 Bldr.addNodes(Dst); 01108 break; 01109 } 01110 // FIXME: ChooseExpr is really a constant. We need to fix 01111 // the CFG do not model them as explicit control-flow. 01112 01113 case Stmt::ChooseExprClass: { // __builtin_choose_expr 01114 Bldr.takeNodes(Pred); 01115 const ChooseExpr *C = cast<ChooseExpr>(S); 01116 VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); 01117 Bldr.addNodes(Dst); 01118 break; 01119 } 01120 01121 case Stmt::CompoundAssignOperatorClass: 01122 Bldr.takeNodes(Pred); 01123 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); 01124 Bldr.addNodes(Dst); 01125 break; 01126 01127 case Stmt::CompoundLiteralExprClass: 01128 Bldr.takeNodes(Pred); 01129 VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst); 01130 Bldr.addNodes(Dst); 01131 break; 01132 01133 case Stmt::BinaryConditionalOperatorClass: 01134 case Stmt::ConditionalOperatorClass: { // '?' operator 01135 Bldr.takeNodes(Pred); 01136 const AbstractConditionalOperator *C 01137 = cast<AbstractConditionalOperator>(S); 01138 VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst); 01139 Bldr.addNodes(Dst); 01140 break; 01141 } 01142 01143 case Stmt::CXXThisExprClass: 01144 Bldr.takeNodes(Pred); 01145 VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst); 01146 Bldr.addNodes(Dst); 01147 break; 01148 01149 case Stmt::DeclRefExprClass: { 01150 Bldr.takeNodes(Pred); 01151 const DeclRefExpr *DE = cast<DeclRefExpr>(S); 01152 VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst); 01153 Bldr.addNodes(Dst); 01154 break; 01155 } 01156 01157 case Stmt::DeclStmtClass: 01158 Bldr.takeNodes(Pred); 01159 VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst); 01160 Bldr.addNodes(Dst); 01161 break; 01162 01163 case Stmt::ImplicitCastExprClass: 01164 case Stmt::CStyleCastExprClass: 01165 case Stmt::CXXStaticCastExprClass: 01166 case Stmt::CXXDynamicCastExprClass: 01167 case Stmt::CXXReinterpretCastExprClass: 01168 case Stmt::CXXConstCastExprClass: 01169 case Stmt::CXXFunctionalCastExprClass: 01170 case Stmt::ObjCBridgedCastExprClass: { 01171 Bldr.takeNodes(Pred); 01172 const CastExpr *C = cast<CastExpr>(S); 01173 // Handle the previsit checks. 01174 ExplodedNodeSet dstPrevisit; 01175 getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this); 01176 01177 // Handle the expression itself. 01178 ExplodedNodeSet dstExpr; 01179 for (ExplodedNodeSet::iterator i = dstPrevisit.begin(), 01180 e = dstPrevisit.end(); i != e ; ++i) { 01181 VisitCast(C, C->getSubExpr(), *i, dstExpr); 01182 } 01183 01184 // Handle the postvisit checks. 01185 getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this); 01186 Bldr.addNodes(Dst); 01187 break; 01188 } 01189 01190 case Expr::MaterializeTemporaryExprClass: { 01191 Bldr.takeNodes(Pred); 01192 const MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(S); 01193 CreateCXXTemporaryObject(MTE, Pred, Dst); 01194 Bldr.addNodes(Dst); 01195 break; 01196 } 01197 01198 case Stmt::InitListExprClass: 01199 Bldr.takeNodes(Pred); 01200 VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst); 01201 Bldr.addNodes(Dst); 01202 break; 01203 01204 case Stmt::MemberExprClass: 01205 Bldr.takeNodes(Pred); 01206 VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst); 01207 Bldr.addNodes(Dst); 01208 break; 01209 01210 case Stmt::ObjCIvarRefExprClass: 01211 Bldr.takeNodes(Pred); 01212 VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst); 01213 Bldr.addNodes(Dst); 01214 break; 01215 01216 case Stmt::ObjCForCollectionStmtClass: 01217 Bldr.takeNodes(Pred); 01218 VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst); 01219 Bldr.addNodes(Dst); 01220 break; 01221 01222 case Stmt::ObjCMessageExprClass: 01223 Bldr.takeNodes(Pred); 01224 VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst); 01225 Bldr.addNodes(Dst); 01226 break; 01227 01228 case Stmt::ObjCAtThrowStmtClass: 01229 case Stmt::CXXThrowExprClass: 01230 // FIXME: This is not complete. We basically treat @throw as 01231 // an abort. 01232 Bldr.generateSink(S, Pred, Pred->getState()); 01233 break; 01234 01235 case Stmt::ReturnStmtClass: 01236 Bldr.takeNodes(Pred); 01237 VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst); 01238 Bldr.addNodes(Dst); 01239 break; 01240 01241 case Stmt::OffsetOfExprClass: 01242 Bldr.takeNodes(Pred); 01243 VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst); 01244 Bldr.addNodes(Dst); 01245 break; 01246 01247 case Stmt::UnaryExprOrTypeTraitExprClass: 01248 Bldr.takeNodes(Pred); 01249 VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S), 01250 Pred, Dst); 01251 Bldr.addNodes(Dst); 01252 break; 01253 01254 case Stmt::StmtExprClass: { 01255 const StmtExpr *SE = cast<StmtExpr>(S); 01256 01257 if (SE->getSubStmt()->body_empty()) { 01258 // Empty statement expression. 01259 assert(SE->getType() == getContext().VoidTy 01260 && "Empty statement expression must have void type."); 01261 break; 01262 } 01263 01264 if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) { 01265 ProgramStateRef state = Pred->getState(); 01266 Bldr.generateNode(SE, Pred, 01267 state->BindExpr(SE, Pred->getLocationContext(), 01268 state->getSVal(LastExpr, 01269 Pred->getLocationContext()))); 01270 } 01271 break; 01272 } 01273 01274 case Stmt::UnaryOperatorClass: { 01275 Bldr.takeNodes(Pred); 01276 const UnaryOperator *U = cast<UnaryOperator>(S); 01277 if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->getOpcode() == UO_LNot)) { 01278 ExplodedNodeSet Tmp; 01279 VisitUnaryOperator(U, Pred, Tmp); 01280 evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U); 01281 } 01282 else 01283 VisitUnaryOperator(U, Pred, Dst); 01284 Bldr.addNodes(Dst); 01285 break; 01286 } 01287 01288 case Stmt::PseudoObjectExprClass: { 01289 Bldr.takeNodes(Pred); 01290 ProgramStateRef state = Pred->getState(); 01291 const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S); 01292 if (const Expr *Result = PE->getResultExpr()) { 01293 SVal V = state->getSVal(Result, Pred->getLocationContext()); 01294 Bldr.generateNode(S, Pred, 01295 state->BindExpr(S, Pred->getLocationContext(), V)); 01296 } 01297 else 01298 Bldr.generateNode(S, Pred, 01299 state->BindExpr(S, Pred->getLocationContext(), 01300 UnknownVal())); 01301 01302 Bldr.addNodes(Dst); 01303 break; 01304 } 01305 } 01306 } 01307 01308 bool ExprEngine::replayWithoutInlining(ExplodedNode *N, 01309 const LocationContext *CalleeLC) { 01310 const StackFrameContext *CalleeSF = CalleeLC->getCurrentStackFrame(); 01311 const StackFrameContext *CallerSF = CalleeSF->getParent()->getCurrentStackFrame(); 01312 assert(CalleeSF && CallerSF); 01313 ExplodedNode *BeforeProcessingCall = nullptr; 01314 const Stmt *CE = CalleeSF->getCallSite(); 01315 01316 // Find the first node before we started processing the call expression. 01317 while (N) { 01318 ProgramPoint L = N->getLocation(); 01319 BeforeProcessingCall = N; 01320 N = N->pred_empty() ? nullptr : *(N->pred_begin()); 01321 01322 // Skip the nodes corresponding to the inlined code. 01323 if (L.getLocationContext()->getCurrentStackFrame() != CallerSF) 01324 continue; 01325 // We reached the caller. Find the node right before we started 01326 // processing the call. 01327 if (L.isPurgeKind()) 01328 continue; 01329 if (L.getAs<PreImplicitCall>()) 01330 continue; 01331 if (L.getAs<CallEnter>()) 01332 continue; 01333 if (Optional<StmtPoint> SP = L.getAs<StmtPoint>()) 01334 if (SP->getStmt() == CE) 01335 continue; 01336 break; 01337 } 01338 01339 if (!BeforeProcessingCall) 01340 return false; 01341 01342 // TODO: Clean up the unneeded nodes. 01343 01344 // Build an Epsilon node from which we will restart the analyzes. 01345 // Note that CE is permitted to be NULL! 01346 ProgramPoint NewNodeLoc = 01347 EpsilonPoint(BeforeProcessingCall->getLocationContext(), CE); 01348 // Add the special flag to GDM to signal retrying with no inlining. 01349 // Note, changing the state ensures that we are not going to cache out. 01350 ProgramStateRef NewNodeState = BeforeProcessingCall->getState(); 01351 NewNodeState = 01352 NewNodeState->set<ReplayWithoutInlining>(const_cast<Stmt *>(CE)); 01353 01354 // Make the new node a successor of BeforeProcessingCall. 01355 bool IsNew = false; 01356 ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState, false, &IsNew); 01357 // We cached out at this point. Caching out is common due to us backtracking 01358 // from the inlined function, which might spawn several paths. 01359 if (!IsNew) 01360 return true; 01361 01362 NewNode->addPredecessor(BeforeProcessingCall, G); 01363 01364 // Add the new node to the work list. 01365 Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(), 01366 CalleeSF->getIndex()); 01367 NumTimesRetriedWithoutInlining++; 01368 return true; 01369 } 01370 01371 /// Block entrance. (Update counters). 01372 void ExprEngine::processCFGBlockEntrance(const BlockEdge &L, 01373 NodeBuilderWithSinks &nodeBuilder, 01374 ExplodedNode *Pred) { 01375 PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); 01376 01377 // FIXME: Refactor this into a checker. 01378 if (nodeBuilder.getContext().blockCount() >= AMgr.options.maxBlockVisitOnPath) { 01379 static SimpleProgramPointTag tag(TagProviderName, "Block count exceeded"); 01380 const ExplodedNode *Sink = 01381 nodeBuilder.generateSink(Pred->getState(), Pred, &tag); 01382 01383 // Check if we stopped at the top level function or not. 01384 // Root node should have the location context of the top most function. 01385 const LocationContext *CalleeLC = Pred->getLocation().getLocationContext(); 01386 const LocationContext *CalleeSF = CalleeLC->getCurrentStackFrame(); 01387 const LocationContext *RootLC = 01388 (*G.roots_begin())->getLocation().getLocationContext(); 01389 if (RootLC->getCurrentStackFrame() != CalleeSF) { 01390 Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl()); 01391 01392 // Re-run the call evaluation without inlining it, by storing the 01393 // no-inlining policy in the state and enqueuing the new work item on 01394 // the list. Replay should almost never fail. Use the stats to catch it 01395 // if it does. 01396 if ((!AMgr.options.NoRetryExhausted && 01397 replayWithoutInlining(Pred, CalleeLC))) 01398 return; 01399 NumMaxBlockCountReachedInInlined++; 01400 } else 01401 NumMaxBlockCountReached++; 01402 01403 // Make sink nodes as exhausted(for stats) only if retry failed. 01404 Engine.blocksExhausted.push_back(std::make_pair(L, Sink)); 01405 } 01406 } 01407 01408 //===----------------------------------------------------------------------===// 01409 // Branch processing. 01410 //===----------------------------------------------------------------------===// 01411 01412 /// RecoverCastedSymbol - A helper function for ProcessBranch that is used 01413 /// to try to recover some path-sensitivity for casts of symbolic 01414 /// integers that promote their values (which are currently not tracked well). 01415 /// This function returns the SVal bound to Condition->IgnoreCasts if all the 01416 // cast(s) did was sign-extend the original value. 01417 static SVal RecoverCastedSymbol(ProgramStateManager& StateMgr, 01418 ProgramStateRef state, 01419 const Stmt *Condition, 01420 const LocationContext *LCtx, 01421 ASTContext &Ctx) { 01422 01423 const Expr *Ex = dyn_cast<Expr>(Condition); 01424 if (!Ex) 01425 return UnknownVal(); 01426 01427 uint64_t bits = 0; 01428 bool bitsInit = false; 01429 01430 while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) { 01431 QualType T = CE->getType(); 01432 01433 if (!T->isIntegralOrEnumerationType()) 01434 return UnknownVal(); 01435 01436 uint64_t newBits = Ctx.getTypeSize(T); 01437 if (!bitsInit || newBits < bits) { 01438 bitsInit = true; 01439 bits = newBits; 01440 } 01441 01442 Ex = CE->getSubExpr(); 01443 } 01444 01445 // We reached a non-cast. Is it a symbolic value? 01446 QualType T = Ex->getType(); 01447 01448 if (!bitsInit || !T->isIntegralOrEnumerationType() || 01449 Ctx.getTypeSize(T) > bits) 01450 return UnknownVal(); 01451 01452 return state->getSVal(Ex, LCtx); 01453 } 01454 01455 #ifndef NDEBUG 01456 static const Stmt *getRightmostLeaf(const Stmt *Condition) { 01457 while (Condition) { 01458 const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition); 01459 if (!BO || !BO->isLogicalOp()) { 01460 return Condition; 01461 } 01462 Condition = BO->getRHS()->IgnoreParens(); 01463 } 01464 return nullptr; 01465 } 01466 #endif 01467 01468 // Returns the condition the branch at the end of 'B' depends on and whose value 01469 // has been evaluated within 'B'. 01470 // In most cases, the terminator condition of 'B' will be evaluated fully in 01471 // the last statement of 'B'; in those cases, the resolved condition is the 01472 // given 'Condition'. 01473 // If the condition of the branch is a logical binary operator tree, the CFG is 01474 // optimized: in that case, we know that the expression formed by all but the 01475 // rightmost leaf of the logical binary operator tree must be true, and thus 01476 // the branch condition is at this point equivalent to the truth value of that 01477 // rightmost leaf; the CFG block thus only evaluates this rightmost leaf 01478 // expression in its final statement. As the full condition in that case was 01479 // not evaluated, and is thus not in the SVal cache, we need to use that leaf 01480 // expression to evaluate the truth value of the condition in the current state 01481 // space. 01482 static const Stmt *ResolveCondition(const Stmt *Condition, 01483 const CFGBlock *B) { 01484 if (const Expr *Ex = dyn_cast<Expr>(Condition)) 01485 Condition = Ex->IgnoreParens(); 01486 01487 const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition); 01488 if (!BO || !BO->isLogicalOp()) 01489 return Condition; 01490 01491 assert(!B->getTerminator().isTemporaryDtorsBranch() && 01492 "Temporary destructor branches handled by processBindTemporary."); 01493 01494 // For logical operations, we still have the case where some branches 01495 // use the traditional "merge" approach and others sink the branch 01496 // directly into the basic blocks representing the logical operation. 01497 // We need to distinguish between those two cases here. 01498 01499 // The invariants are still shifting, but it is possible that the 01500 // last element in a CFGBlock is not a CFGStmt. Look for the last 01501 // CFGStmt as the value of the condition. 01502 CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend(); 01503 for (; I != E; ++I) { 01504 CFGElement Elem = *I; 01505 Optional<CFGStmt> CS = Elem.getAs<CFGStmt>(); 01506 if (!CS) 01507 continue; 01508 const Stmt *LastStmt = CS->getStmt(); 01509 assert(LastStmt == Condition || LastStmt == getRightmostLeaf(Condition)); 01510 return LastStmt; 01511 } 01512 llvm_unreachable("could not resolve condition"); 01513 } 01514 01515 void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, 01516 NodeBuilderContext& BldCtx, 01517 ExplodedNode *Pred, 01518 ExplodedNodeSet &Dst, 01519 const CFGBlock *DstT, 01520 const CFGBlock *DstF) { 01521 assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) && 01522 "CXXBindTemporaryExprs are handled by processBindTemporary."); 01523 const LocationContext *LCtx = Pred->getLocationContext(); 01524 PrettyStackTraceLocationContext StackCrashInfo(LCtx); 01525 currBldrCtx = &BldCtx; 01526 01527 // Check for NULL conditions; e.g. "for(;;)" 01528 if (!Condition) { 01529 BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF); 01530 NullCondBldr.markInfeasible(false); 01531 NullCondBldr.generateNode(Pred->getState(), true, Pred); 01532 return; 01533 } 01534 01535 01536 if (const Expr *Ex = dyn_cast<Expr>(Condition)) 01537 Condition = Ex->IgnoreParens(); 01538 01539 Condition = ResolveCondition(Condition, BldCtx.getBlock()); 01540 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 01541 Condition->getLocStart(), 01542 "Error evaluating branch"); 01543 01544 ExplodedNodeSet CheckersOutSet; 01545 getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet, 01546 Pred, *this); 01547 // We generated only sinks. 01548 if (CheckersOutSet.empty()) 01549 return; 01550 01551 BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF); 01552 for (NodeBuilder::iterator I = CheckersOutSet.begin(), 01553 E = CheckersOutSet.end(); E != I; ++I) { 01554 ExplodedNode *PredI = *I; 01555 01556 if (PredI->isSink()) 01557 continue; 01558 01559 ProgramStateRef PrevState = PredI->getState(); 01560 SVal X = PrevState->getSVal(Condition, PredI->getLocationContext()); 01561 01562 if (X.isUnknownOrUndef()) { 01563 // Give it a chance to recover from unknown. 01564 if (const Expr *Ex = dyn_cast<Expr>(Condition)) { 01565 if (Ex->getType()->isIntegralOrEnumerationType()) { 01566 // Try to recover some path-sensitivity. Right now casts of symbolic 01567 // integers that promote their values are currently not tracked well. 01568 // If 'Condition' is such an expression, try and recover the 01569 // underlying value and use that instead. 01570 SVal recovered = RecoverCastedSymbol(getStateManager(), 01571 PrevState, Condition, 01572 PredI->getLocationContext(), 01573 getContext()); 01574 01575 if (!recovered.isUnknown()) { 01576 X = recovered; 01577 } 01578 } 01579 } 01580 } 01581 01582 // If the condition is still unknown, give up. 01583 if (X.isUnknownOrUndef()) { 01584 builder.generateNode(PrevState, true, PredI); 01585 builder.generateNode(PrevState, false, PredI); 01586 continue; 01587 } 01588 01589 DefinedSVal V = X.castAs<DefinedSVal>(); 01590 01591 ProgramStateRef StTrue, StFalse; 01592 std::tie(StTrue, StFalse) = PrevState->assume(V); 01593 01594 // Process the true branch. 01595 if (builder.isFeasible(true)) { 01596 if (StTrue) 01597 builder.generateNode(StTrue, true, PredI); 01598 else 01599 builder.markInfeasible(true); 01600 } 01601 01602 // Process the false branch. 01603 if (builder.isFeasible(false)) { 01604 if (StFalse) 01605 builder.generateNode(StFalse, false, PredI); 01606 else 01607 builder.markInfeasible(false); 01608 } 01609 } 01610 currBldrCtx = nullptr; 01611 } 01612 01613 /// The GDM component containing the set of global variables which have been 01614 /// previously initialized with explicit initializers. 01615 REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedGlobalsSet, 01616 llvm::ImmutableSet<const VarDecl *>) 01617 01618 void ExprEngine::processStaticInitializer(const DeclStmt *DS, 01619 NodeBuilderContext &BuilderCtx, 01620 ExplodedNode *Pred, 01621 clang::ento::ExplodedNodeSet &Dst, 01622 const CFGBlock *DstT, 01623 const CFGBlock *DstF) { 01624 PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); 01625 currBldrCtx = &BuilderCtx; 01626 01627 const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl()); 01628 ProgramStateRef state = Pred->getState(); 01629 bool initHasRun = state->contains<InitializedGlobalsSet>(VD); 01630 BranchNodeBuilder builder(Pred, Dst, BuilderCtx, DstT, DstF); 01631 01632 if (!initHasRun) { 01633 state = state->add<InitializedGlobalsSet>(VD); 01634 } 01635 01636 builder.generateNode(state, initHasRun, Pred); 01637 builder.markInfeasible(!initHasRun); 01638 01639 currBldrCtx = nullptr; 01640 } 01641 01642 /// processIndirectGoto - Called by CoreEngine. Used to generate successor 01643 /// nodes by processing the 'effects' of a computed goto jump. 01644 void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { 01645 01646 ProgramStateRef state = builder.getState(); 01647 SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext()); 01648 01649 // Three possibilities: 01650 // 01651 // (1) We know the computed label. 01652 // (2) The label is NULL (or some other constant), or Undefined. 01653 // (3) We have no clue about the label. Dispatch to all targets. 01654 // 01655 01656 typedef IndirectGotoNodeBuilder::iterator iterator; 01657 01658 if (Optional<loc::GotoLabel> LV = V.getAs<loc::GotoLabel>()) { 01659 const LabelDecl *L = LV->getLabel(); 01660 01661 for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) { 01662 if (I.getLabel() == L) { 01663 builder.generateNode(I, state); 01664 return; 01665 } 01666 } 01667 01668 llvm_unreachable("No block with label."); 01669 } 01670 01671 if (V.getAs<loc::ConcreteInt>() || V.getAs<UndefinedVal>()) { 01672 // Dispatch to the first target and mark it as a sink. 01673 //ExplodedNode* N = builder.generateNode(builder.begin(), state, true); 01674 // FIXME: add checker visit. 01675 // UndefBranches.insert(N); 01676 return; 01677 } 01678 01679 // This is really a catch-all. We don't support symbolics yet. 01680 // FIXME: Implement dispatch for symbolic pointers. 01681 01682 for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) 01683 builder.generateNode(I, state); 01684 } 01685 01686 #if 0 01687 static bool stackFrameDoesNotContainInitializedTemporaries(ExplodedNode &Pred) { 01688 const StackFrameContext* Frame = Pred.getStackFrame(); 01689 const llvm::ImmutableSet<CXXBindTemporaryContext> &Set = 01690 Pred.getState()->get<InitializedTemporariesSet>(); 01691 return std::find_if(Set.begin(), Set.end(), 01692 [&](const CXXBindTemporaryContext &Ctx) { 01693 if (Ctx.second == Frame) { 01694 Ctx.first->dump(); 01695 llvm::errs() << "\n"; 01696 } 01697 return Ctx.second == Frame; 01698 }) == Set.end(); 01699 } 01700 #endif 01701 01702 /// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path 01703 /// nodes when the control reaches the end of a function. 01704 void ExprEngine::processEndOfFunction(NodeBuilderContext& BC, 01705 ExplodedNode *Pred) { 01706 // FIXME: Assert that stackFrameDoesNotContainInitializedTemporaries(*Pred)). 01707 // We currently cannot enable this assert, as lifetime extended temporaries 01708 // are not modelled correctly. 01709 PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); 01710 StateMgr.EndPath(Pred->getState()); 01711 01712 ExplodedNodeSet Dst; 01713 if (Pred->getLocationContext()->inTopFrame()) { 01714 // Remove dead symbols. 01715 ExplodedNodeSet AfterRemovedDead; 01716 removeDeadOnEndOfFunction(BC, Pred, AfterRemovedDead); 01717 01718 // Notify checkers. 01719 for (ExplodedNodeSet::iterator I = AfterRemovedDead.begin(), 01720 E = AfterRemovedDead.end(); I != E; ++I) { 01721 getCheckerManager().runCheckersForEndFunction(BC, Dst, *I, *this); 01722 } 01723 } else { 01724 getCheckerManager().runCheckersForEndFunction(BC, Dst, Pred, *this); 01725 } 01726 01727 Engine.enqueueEndOfFunction(Dst); 01728 } 01729 01730 /// ProcessSwitch - Called by CoreEngine. Used to generate successor 01731 /// nodes by processing the 'effects' of a switch statement. 01732 void ExprEngine::processSwitch(SwitchNodeBuilder& builder) { 01733 typedef SwitchNodeBuilder::iterator iterator; 01734 ProgramStateRef state = builder.getState(); 01735 const Expr *CondE = builder.getCondition(); 01736 SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext()); 01737 01738 if (CondV_untested.isUndef()) { 01739 //ExplodedNode* N = builder.generateDefaultCaseNode(state, true); 01740 // FIXME: add checker 01741 //UndefBranches.insert(N); 01742 01743 return; 01744 } 01745 DefinedOrUnknownSVal CondV = CondV_untested.castAs<DefinedOrUnknownSVal>(); 01746 01747 ProgramStateRef DefaultSt = state; 01748 01749 iterator I = builder.begin(), EI = builder.end(); 01750 bool defaultIsFeasible = I == EI; 01751 01752 for ( ; I != EI; ++I) { 01753 // Successor may be pruned out during CFG construction. 01754 if (!I.getBlock()) 01755 continue; 01756 01757 const CaseStmt *Case = I.getCase(); 01758 01759 // Evaluate the LHS of the case value. 01760 llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext()); 01761 assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType())); 01762 01763 // Get the RHS of the case, if it exists. 01764 llvm::APSInt V2; 01765 if (const Expr *E = Case->getRHS()) 01766 V2 = E->EvaluateKnownConstInt(getContext()); 01767 else 01768 V2 = V1; 01769 01770 // FIXME: Eventually we should replace the logic below with a range 01771 // comparison, rather than concretize the values within the range. 01772 // This should be easy once we have "ranges" for NonLVals. 01773 01774 do { 01775 nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1)); 01776 DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state, 01777 CondV, CaseVal); 01778 01779 // Now "assume" that the case matches. 01780 if (ProgramStateRef stateNew = state->assume(Res, true)) { 01781 builder.generateCaseStmtNode(I, stateNew); 01782 01783 // If CondV evaluates to a constant, then we know that this 01784 // is the *only* case that we can take, so stop evaluating the 01785 // others. 01786 if (CondV.getAs<nonloc::ConcreteInt>()) 01787 return; 01788 } 01789 01790 // Now "assume" that the case doesn't match. Add this state 01791 // to the default state (if it is feasible). 01792 if (DefaultSt) { 01793 if (ProgramStateRef stateNew = DefaultSt->assume(Res, false)) { 01794 defaultIsFeasible = true; 01795 DefaultSt = stateNew; 01796 } 01797 else { 01798 defaultIsFeasible = false; 01799 DefaultSt = nullptr; 01800 } 01801 } 01802 01803 // Concretize the next value in the range. 01804 if (V1 == V2) 01805 break; 01806 01807 ++V1; 01808 assert (V1 <= V2); 01809 01810 } while (true); 01811 } 01812 01813 if (!defaultIsFeasible) 01814 return; 01815 01816 // If we have switch(enum value), the default branch is not 01817 // feasible if all of the enum constants not covered by 'case:' statements 01818 // are not feasible values for the switch condition. 01819 // 01820 // Note that this isn't as accurate as it could be. Even if there isn't 01821 // a case for a particular enum value as long as that enum value isn't 01822 // feasible then it shouldn't be considered for making 'default:' reachable. 01823 const SwitchStmt *SS = builder.getSwitch(); 01824 const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts(); 01825 if (CondExpr->getType()->getAs<EnumType>()) { 01826 if (SS->isAllEnumCasesCovered()) 01827 return; 01828 } 01829 01830 builder.generateDefaultCaseNode(DefaultSt); 01831 } 01832 01833 //===----------------------------------------------------------------------===// 01834 // Transfer functions: Loads and stores. 01835 //===----------------------------------------------------------------------===// 01836 01837 void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, 01838 ExplodedNode *Pred, 01839 ExplodedNodeSet &Dst) { 01840 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 01841 01842 ProgramStateRef state = Pred->getState(); 01843 const LocationContext *LCtx = Pred->getLocationContext(); 01844 01845 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 01846 // C permits "extern void v", and if you cast the address to a valid type, 01847 // you can even do things with it. We simply pretend 01848 assert(Ex->isGLValue() || VD->getType()->isVoidType()); 01849 SVal V = state->getLValue(VD, Pred->getLocationContext()); 01850 01851 // For references, the 'lvalue' is the pointer address stored in the 01852 // reference region. 01853 if (VD->getType()->isReferenceType()) { 01854 if (const MemRegion *R = V.getAsRegion()) 01855 V = state->getSVal(R); 01856 else 01857 V = UnknownVal(); 01858 } 01859 01860 Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr, 01861 ProgramPoint::PostLValueKind); 01862 return; 01863 } 01864 if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) { 01865 assert(!Ex->isGLValue()); 01866 SVal V = svalBuilder.makeIntVal(ED->getInitVal()); 01867 Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V)); 01868 return; 01869 } 01870 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 01871 SVal V = svalBuilder.getFunctionPointer(FD); 01872 Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr, 01873 ProgramPoint::PostLValueKind); 01874 return; 01875 } 01876 if (isa<FieldDecl>(D)) { 01877 // FIXME: Compute lvalue of field pointers-to-member. 01878 // Right now we just use a non-null void pointer, so that it gives proper 01879 // results in boolean contexts. 01880 SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy, 01881 currBldrCtx->blockCount()); 01882 state = state->assume(V.castAs<DefinedOrUnknownSVal>(), true); 01883 Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr, 01884 ProgramPoint::PostLValueKind); 01885 return; 01886 } 01887 01888 llvm_unreachable("Support for this Decl not implemented."); 01889 } 01890 01891 /// VisitArraySubscriptExpr - Transfer function for array accesses 01892 void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A, 01893 ExplodedNode *Pred, 01894 ExplodedNodeSet &Dst){ 01895 01896 const Expr *Base = A->getBase()->IgnoreParens(); 01897 const Expr *Idx = A->getIdx()->IgnoreParens(); 01898 01899 01900 ExplodedNodeSet checkerPreStmt; 01901 getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this); 01902 01903 StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currBldrCtx); 01904 01905 for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(), 01906 ei = checkerPreStmt.end(); it != ei; ++it) { 01907 const LocationContext *LCtx = (*it)->getLocationContext(); 01908 ProgramStateRef state = (*it)->getState(); 01909 SVal V = state->getLValue(A->getType(), 01910 state->getSVal(Idx, LCtx), 01911 state->getSVal(Base, LCtx)); 01912 assert(A->isGLValue()); 01913 Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), nullptr, 01914 ProgramPoint::PostLValueKind); 01915 } 01916 } 01917 01918 /// VisitMemberExpr - Transfer function for member expressions. 01919 void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 01920 ExplodedNodeSet &Dst) { 01921 01922 // FIXME: Prechecks eventually go in ::Visit(). 01923 ExplodedNodeSet CheckedSet; 01924 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, M, *this); 01925 01926 ExplodedNodeSet EvalSet; 01927 ValueDecl *Member = M->getMemberDecl(); 01928 01929 // Handle static member variables and enum constants accessed via 01930 // member syntax. 01931 if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) { 01932 ExplodedNodeSet Dst; 01933 for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 01934 I != E; ++I) { 01935 VisitCommonDeclRefExpr(M, Member, Pred, EvalSet); 01936 } 01937 } else { 01938 StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx); 01939 ExplodedNodeSet Tmp; 01940 01941 for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 01942 I != E; ++I) { 01943 ProgramStateRef state = (*I)->getState(); 01944 const LocationContext *LCtx = (*I)->getLocationContext(); 01945 Expr *BaseExpr = M->getBase(); 01946 01947 // Handle C++ method calls. 01948 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) { 01949 if (MD->isInstance()) 01950 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); 01951 01952 SVal MDVal = svalBuilder.getFunctionPointer(MD); 01953 state = state->BindExpr(M, LCtx, MDVal); 01954 01955 Bldr.generateNode(M, *I, state); 01956 continue; 01957 } 01958 01959 // Handle regular struct fields / member variables. 01960 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); 01961 SVal baseExprVal = state->getSVal(BaseExpr, LCtx); 01962 01963 FieldDecl *field = cast<FieldDecl>(Member); 01964 SVal L = state->getLValue(field, baseExprVal); 01965 01966 if (M->isGLValue() || M->getType()->isArrayType()) { 01967 // We special-case rvalues of array type because the analyzer cannot 01968 // reason about them, since we expect all regions to be wrapped in Locs. 01969 // We instead treat these as lvalues and assume that they will decay to 01970 // pointers as soon as they are used. 01971 if (!M->isGLValue()) { 01972 assert(M->getType()->isArrayType()); 01973 const ImplicitCastExpr *PE = 01974 dyn_cast<ImplicitCastExpr>((*I)->getParentMap().getParent(M)); 01975 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) { 01976 llvm_unreachable("should always be wrapped in ArrayToPointerDecay"); 01977 } 01978 } 01979 01980 if (field->getType()->isReferenceType()) { 01981 if (const MemRegion *R = L.getAsRegion()) 01982 L = state->getSVal(R); 01983 else 01984 L = UnknownVal(); 01985 } 01986 01987 Bldr.generateNode(M, *I, state->BindExpr(M, LCtx, L), nullptr, 01988 ProgramPoint::PostLValueKind); 01989 } else { 01990 Bldr.takeNodes(*I); 01991 evalLoad(Tmp, M, M, *I, state, L); 01992 Bldr.addNodes(Tmp); 01993 } 01994 } 01995 } 01996 01997 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, M, *this); 01998 } 01999 02000 namespace { 02001 class CollectReachableSymbolsCallback : public SymbolVisitor { 02002 InvalidatedSymbols Symbols; 02003 public: 02004 CollectReachableSymbolsCallback(ProgramStateRef State) {} 02005 const InvalidatedSymbols &getSymbols() const { return Symbols; } 02006 02007 bool VisitSymbol(SymbolRef Sym) override { 02008 Symbols.insert(Sym); 02009 return true; 02010 } 02011 }; 02012 } // end anonymous namespace 02013 02014 // A value escapes in three possible cases: 02015 // (1) We are binding to something that is not a memory region. 02016 // (2) We are binding to a MemrRegion that does not have stack storage. 02017 // (3) We are binding to a MemRegion with stack storage that the store 02018 // does not understand. 02019 ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State, 02020 SVal Loc, SVal Val) { 02021 // Are we storing to something that causes the value to "escape"? 02022 bool escapes = true; 02023 02024 // TODO: Move to StoreManager. 02025 if (Optional<loc::MemRegionVal> regionLoc = Loc.getAs<loc::MemRegionVal>()) { 02026 escapes = !regionLoc->getRegion()->hasStackStorage(); 02027 02028 if (!escapes) { 02029 // To test (3), generate a new state with the binding added. If it is 02030 // the same state, then it escapes (since the store cannot represent 02031 // the binding). 02032 // Do this only if we know that the store is not supposed to generate the 02033 // same state. 02034 SVal StoredVal = State->getSVal(regionLoc->getRegion()); 02035 if (StoredVal != Val) 02036 escapes = (State == (State->bindLoc(*regionLoc, Val))); 02037 } 02038 } 02039 02040 // If our store can represent the binding and we aren't storing to something 02041 // that doesn't have local storage then just return and have the simulation 02042 // state continue as is. 02043 if (!escapes) 02044 return State; 02045 02046 // Otherwise, find all symbols referenced by 'val' that we are tracking 02047 // and stop tracking them. 02048 CollectReachableSymbolsCallback Scanner = 02049 State->scanReachableSymbols<CollectReachableSymbolsCallback>(Val); 02050 const InvalidatedSymbols &EscapedSymbols = Scanner.getSymbols(); 02051 State = getCheckerManager().runCheckersForPointerEscape(State, 02052 EscapedSymbols, 02053 /*CallEvent*/ nullptr, 02054 PSK_EscapeOnBind, 02055 nullptr); 02056 02057 return State; 02058 } 02059 02060 ProgramStateRef 02061 ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State, 02062 const InvalidatedSymbols *Invalidated, 02063 ArrayRef<const MemRegion *> ExplicitRegions, 02064 ArrayRef<const MemRegion *> Regions, 02065 const CallEvent *Call, 02066 RegionAndSymbolInvalidationTraits &ITraits) { 02067 02068 if (!Invalidated || Invalidated->empty()) 02069 return State; 02070 02071 if (!Call) 02072 return getCheckerManager().runCheckersForPointerEscape(State, 02073 *Invalidated, 02074 nullptr, 02075 PSK_EscapeOther, 02076 &ITraits); 02077 02078 // If the symbols were invalidated by a call, we want to find out which ones 02079 // were invalidated directly due to being arguments to the call. 02080 InvalidatedSymbols SymbolsDirectlyInvalidated; 02081 for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(), 02082 E = ExplicitRegions.end(); I != E; ++I) { 02083 if (const SymbolicRegion *R = (*I)->StripCasts()->getAs<SymbolicRegion>()) 02084 SymbolsDirectlyInvalidated.insert(R->getSymbol()); 02085 } 02086 02087 InvalidatedSymbols SymbolsIndirectlyInvalidated; 02088 for (InvalidatedSymbols::const_iterator I=Invalidated->begin(), 02089 E = Invalidated->end(); I!=E; ++I) { 02090 SymbolRef sym = *I; 02091 if (SymbolsDirectlyInvalidated.count(sym)) 02092 continue; 02093 SymbolsIndirectlyInvalidated.insert(sym); 02094 } 02095 02096 if (!SymbolsDirectlyInvalidated.empty()) 02097 State = getCheckerManager().runCheckersForPointerEscape(State, 02098 SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall, &ITraits); 02099 02100 // Notify about the symbols that get indirectly invalidated by the call. 02101 if (!SymbolsIndirectlyInvalidated.empty()) 02102 State = getCheckerManager().runCheckersForPointerEscape(State, 02103 SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall, &ITraits); 02104 02105 return State; 02106 } 02107 02108 /// evalBind - Handle the semantics of binding a value to a specific location. 02109 /// This method is used by evalStore and (soon) VisitDeclStmt, and others. 02110 void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, 02111 ExplodedNode *Pred, 02112 SVal location, SVal Val, 02113 bool atDeclInit, const ProgramPoint *PP) { 02114 02115 const LocationContext *LC = Pred->getLocationContext(); 02116 PostStmt PS(StoreE, LC); 02117 if (!PP) 02118 PP = &PS; 02119 02120 // Do a previsit of the bind. 02121 ExplodedNodeSet CheckedSet; 02122 getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val, 02123 StoreE, *this, *PP); 02124 02125 02126 StmtNodeBuilder Bldr(CheckedSet, Dst, *currBldrCtx); 02127 02128 // If the location is not a 'Loc', it will already be handled by 02129 // the checkers. There is nothing left to do. 02130 if (!location.getAs<Loc>()) { 02131 const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr, 02132 /*tag*/nullptr); 02133 ProgramStateRef state = Pred->getState(); 02134 state = processPointerEscapedOnBind(state, location, Val); 02135 Bldr.generateNode(L, state, Pred); 02136 return; 02137 } 02138 02139 02140 for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 02141 I!=E; ++I) { 02142 ExplodedNode *PredI = *I; 02143 ProgramStateRef state = PredI->getState(); 02144 02145 state = processPointerEscapedOnBind(state, location, Val); 02146 02147 // When binding the value, pass on the hint that this is a initialization. 02148 // For initializations, we do not need to inform clients of region 02149 // changes. 02150 state = state->bindLoc(location.castAs<Loc>(), 02151 Val, /* notifyChanges = */ !atDeclInit); 02152 02153 const MemRegion *LocReg = nullptr; 02154 if (Optional<loc::MemRegionVal> LocRegVal = 02155 location.getAs<loc::MemRegionVal>()) { 02156 LocReg = LocRegVal->getRegion(); 02157 } 02158 02159 const ProgramPoint L = PostStore(StoreE, LC, LocReg, nullptr); 02160 Bldr.generateNode(L, state, PredI); 02161 } 02162 } 02163 02164 /// evalStore - Handle the semantics of a store via an assignment. 02165 /// @param Dst The node set to store generated state nodes 02166 /// @param AssignE The assignment expression if the store happens in an 02167 /// assignment. 02168 /// @param LocationE The location expression that is stored to. 02169 /// @param state The current simulation state 02170 /// @param location The location to store the value 02171 /// @param Val The value to be stored 02172 void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, 02173 const Expr *LocationE, 02174 ExplodedNode *Pred, 02175 ProgramStateRef state, SVal location, SVal Val, 02176 const ProgramPointTag *tag) { 02177 // Proceed with the store. We use AssignE as the anchor for the PostStore 02178 // ProgramPoint if it is non-NULL, and LocationE otherwise. 02179 const Expr *StoreE = AssignE ? AssignE : LocationE; 02180 02181 // Evaluate the location (checks for bad dereferences). 02182 ExplodedNodeSet Tmp; 02183 evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag, false); 02184 02185 if (Tmp.empty()) 02186 return; 02187 02188 if (location.isUndef()) 02189 return; 02190 02191 for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) 02192 evalBind(Dst, StoreE, *NI, location, Val, false); 02193 } 02194 02195 void ExprEngine::evalLoad(ExplodedNodeSet &Dst, 02196 const Expr *NodeEx, 02197 const Expr *BoundEx, 02198 ExplodedNode *Pred, 02199 ProgramStateRef state, 02200 SVal location, 02201 const ProgramPointTag *tag, 02202 QualType LoadTy) 02203 { 02204 assert(!location.getAs<NonLoc>() && "location cannot be a NonLoc."); 02205 02206 // Are we loading from a region? This actually results in two loads; one 02207 // to fetch the address of the referenced value and one to fetch the 02208 // referenced value. 02209 if (const TypedValueRegion *TR = 02210 dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) { 02211 02212 QualType ValTy = TR->getValueType(); 02213 if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) { 02214 static SimpleProgramPointTag 02215 loadReferenceTag(TagProviderName, "Load Reference"); 02216 ExplodedNodeSet Tmp; 02217 evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state, 02218 location, &loadReferenceTag, 02219 getContext().getPointerType(RT->getPointeeType())); 02220 02221 // Perform the load from the referenced value. 02222 for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) { 02223 state = (*I)->getState(); 02224 location = state->getSVal(BoundEx, (*I)->getLocationContext()); 02225 evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy); 02226 } 02227 return; 02228 } 02229 } 02230 02231 evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy); 02232 } 02233 02234 void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, 02235 const Expr *NodeEx, 02236 const Expr *BoundEx, 02237 ExplodedNode *Pred, 02238 ProgramStateRef state, 02239 SVal location, 02240 const ProgramPointTag *tag, 02241 QualType LoadTy) { 02242 assert(NodeEx); 02243 assert(BoundEx); 02244 // Evaluate the location (checks for bad dereferences). 02245 ExplodedNodeSet Tmp; 02246 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag, true); 02247 if (Tmp.empty()) 02248 return; 02249 02250 StmtNodeBuilder Bldr(Tmp, Dst, *currBldrCtx); 02251 if (location.isUndef()) 02252 return; 02253 02254 // Proceed with the load. 02255 for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) { 02256 state = (*NI)->getState(); 02257 const LocationContext *LCtx = (*NI)->getLocationContext(); 02258 02259 SVal V = UnknownVal(); 02260 if (location.isValid()) { 02261 if (LoadTy.isNull()) 02262 LoadTy = BoundEx->getType(); 02263 V = state->getSVal(location.castAs<Loc>(), LoadTy); 02264 } 02265 02266 Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag, 02267 ProgramPoint::PostLoadKind); 02268 } 02269 } 02270 02271 void ExprEngine::evalLocation(ExplodedNodeSet &Dst, 02272 const Stmt *NodeEx, 02273 const Stmt *BoundEx, 02274 ExplodedNode *Pred, 02275 ProgramStateRef state, 02276 SVal location, 02277 const ProgramPointTag *tag, 02278 bool isLoad) { 02279 StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx); 02280 // Early checks for performance reason. 02281 if (location.isUnknown()) { 02282 return; 02283 } 02284 02285 ExplodedNodeSet Src; 02286 BldrTop.takeNodes(Pred); 02287 StmtNodeBuilder Bldr(Pred, Src, *currBldrCtx); 02288 if (Pred->getState() != state) { 02289 // Associate this new state with an ExplodedNode. 02290 // FIXME: If I pass null tag, the graph is incorrect, e.g for 02291 // int *p; 02292 // p = 0; 02293 // *p = 0xDEADBEEF; 02294 // "p = 0" is not noted as "Null pointer value stored to 'p'" but 02295 // instead "int *p" is noted as 02296 // "Variable 'p' initialized to a null pointer value" 02297 02298 static SimpleProgramPointTag tag(TagProviderName, "Location"); 02299 Bldr.generateNode(NodeEx, Pred, state, &tag); 02300 } 02301 ExplodedNodeSet Tmp; 02302 getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad, 02303 NodeEx, BoundEx, *this); 02304 BldrTop.addNodes(Tmp); 02305 } 02306 02307 std::pair<const ProgramPointTag *, const ProgramPointTag*> 02308 ExprEngine::geteagerlyAssumeBinOpBifurcationTags() { 02309 static SimpleProgramPointTag 02310 eagerlyAssumeBinOpBifurcationTrue(TagProviderName, 02311 "Eagerly Assume True"), 02312 eagerlyAssumeBinOpBifurcationFalse(TagProviderName, 02313 "Eagerly Assume False"); 02314 return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue, 02315 &eagerlyAssumeBinOpBifurcationFalse); 02316 } 02317 02318 void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, 02319 ExplodedNodeSet &Src, 02320 const Expr *Ex) { 02321 StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx); 02322 02323 for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) { 02324 ExplodedNode *Pred = *I; 02325 // Test if the previous node was as the same expression. This can happen 02326 // when the expression fails to evaluate to anything meaningful and 02327 // (as an optimization) we don't generate a node. 02328 ProgramPoint P = Pred->getLocation(); 02329 if (!P.getAs<PostStmt>() || P.castAs<PostStmt>().getStmt() != Ex) { 02330 continue; 02331 } 02332 02333 ProgramStateRef state = Pred->getState(); 02334 SVal V = state->getSVal(Ex, Pred->getLocationContext()); 02335 Optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>(); 02336 if (SEV && SEV->isExpression()) { 02337 const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags = 02338 geteagerlyAssumeBinOpBifurcationTags(); 02339 02340 ProgramStateRef StateTrue, StateFalse; 02341 std::tie(StateTrue, StateFalse) = state->assume(*SEV); 02342 02343 // First assume that the condition is true. 02344 if (StateTrue) { 02345 SVal Val = svalBuilder.makeIntVal(1U, Ex->getType()); 02346 StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val); 02347 Bldr.generateNode(Ex, Pred, StateTrue, tags.first); 02348 } 02349 02350 // Next, assume that the condition is false. 02351 if (StateFalse) { 02352 SVal Val = svalBuilder.makeIntVal(0U, Ex->getType()); 02353 StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val); 02354 Bldr.generateNode(Ex, Pred, StateFalse, tags.second); 02355 } 02356 } 02357 } 02358 } 02359 02360 void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, 02361 ExplodedNodeSet &Dst) { 02362 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 02363 // We have processed both the inputs and the outputs. All of the outputs 02364 // should evaluate to Locs. Nuke all of their values. 02365 02366 // FIXME: Some day in the future it would be nice to allow a "plug-in" 02367 // which interprets the inline asm and stores proper results in the 02368 // outputs. 02369 02370 ProgramStateRef state = Pred->getState(); 02371 02372 for (const Expr *O : A->outputs()) { 02373 SVal X = state->getSVal(O, Pred->getLocationContext()); 02374 assert (!X.getAs<NonLoc>()); // Should be an Lval, or unknown, undef. 02375 02376 if (Optional<Loc> LV = X.getAs<Loc>()) 02377 state = state->bindLoc(*LV, UnknownVal()); 02378 } 02379 02380 Bldr.generateNode(A, Pred, state); 02381 } 02382 02383 void ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, 02384 ExplodedNodeSet &Dst) { 02385 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 02386 Bldr.generateNode(A, Pred, Pred->getState()); 02387 } 02388 02389 //===----------------------------------------------------------------------===// 02390 // Visualization. 02391 //===----------------------------------------------------------------------===// 02392 02393 #ifndef NDEBUG 02394 static ExprEngine* GraphPrintCheckerState; 02395 static SourceManager* GraphPrintSourceManager; 02396 02397 namespace llvm { 02398 template<> 02399 struct DOTGraphTraits<ExplodedNode*> : 02400 public DefaultDOTGraphTraits { 02401 02402 DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 02403 02404 // FIXME: Since we do not cache error nodes in ExprEngine now, this does not 02405 // work. 02406 static std::string getNodeAttributes(const ExplodedNode *N, void*) { 02407 02408 #if 0 02409 // FIXME: Replace with a general scheme to tell if the node is 02410 // an error node. 02411 if (GraphPrintCheckerState->isImplicitNullDeref(N) || 02412 GraphPrintCheckerState->isExplicitNullDeref(N) || 02413 GraphPrintCheckerState->isUndefDeref(N) || 02414 GraphPrintCheckerState->isUndefStore(N) || 02415 GraphPrintCheckerState->isUndefControlFlow(N) || 02416 GraphPrintCheckerState->isUndefResult(N) || 02417 GraphPrintCheckerState->isBadCall(N) || 02418 GraphPrintCheckerState->isUndefArg(N)) 02419 return "color=\"red\",style=\"filled\""; 02420 02421 if (GraphPrintCheckerState->isNoReturnCall(N)) 02422 return "color=\"blue\",style=\"filled\""; 02423 #endif 02424 return ""; 02425 } 02426 02427 static void printLocation(raw_ostream &Out, SourceLocation SLoc) { 02428 if (SLoc.isFileID()) { 02429 Out << "\\lline=" 02430 << GraphPrintSourceManager->getExpansionLineNumber(SLoc) 02431 << " col=" 02432 << GraphPrintSourceManager->getExpansionColumnNumber(SLoc) 02433 << "\\l"; 02434 } 02435 } 02436 02437 static std::string getNodeLabel(const ExplodedNode *N, void*){ 02438 02439 std::string sbuf; 02440 llvm::raw_string_ostream Out(sbuf); 02441 02442 // Program Location. 02443 ProgramPoint Loc = N->getLocation(); 02444 02445 switch (Loc.getKind()) { 02446 case ProgramPoint::BlockEntranceKind: { 02447 Out << "Block Entrance: B" 02448 << Loc.castAs<BlockEntrance>().getBlock()->getBlockID(); 02449 if (const NamedDecl *ND = 02450 dyn_cast<NamedDecl>(Loc.getLocationContext()->getDecl())) { 02451 Out << " ("; 02452 ND->printName(Out); 02453 Out << ")"; 02454 } 02455 break; 02456 } 02457 02458 case ProgramPoint::BlockExitKind: 02459 assert (false); 02460 break; 02461 02462 case ProgramPoint::CallEnterKind: 02463 Out << "CallEnter"; 02464 break; 02465 02466 case ProgramPoint::CallExitBeginKind: 02467 Out << "CallExitBegin"; 02468 break; 02469 02470 case ProgramPoint::CallExitEndKind: 02471 Out << "CallExitEnd"; 02472 break; 02473 02474 case ProgramPoint::PostStmtPurgeDeadSymbolsKind: 02475 Out << "PostStmtPurgeDeadSymbols"; 02476 break; 02477 02478 case ProgramPoint::PreStmtPurgeDeadSymbolsKind: 02479 Out << "PreStmtPurgeDeadSymbols"; 02480 break; 02481 02482 case ProgramPoint::EpsilonKind: 02483 Out << "Epsilon Point"; 02484 break; 02485 02486 case ProgramPoint::PreImplicitCallKind: { 02487 ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>(); 02488 Out << "PreCall: "; 02489 02490 // FIXME: Get proper printing options. 02491 PC.getDecl()->print(Out, LangOptions()); 02492 printLocation(Out, PC.getLocation()); 02493 break; 02494 } 02495 02496 case ProgramPoint::PostImplicitCallKind: { 02497 ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>(); 02498 Out << "PostCall: "; 02499 02500 // FIXME: Get proper printing options. 02501 PC.getDecl()->print(Out, LangOptions()); 02502 printLocation(Out, PC.getLocation()); 02503 break; 02504 } 02505 02506 case ProgramPoint::PostInitializerKind: { 02507 Out << "PostInitializer: "; 02508 const CXXCtorInitializer *Init = 02509 Loc.castAs<PostInitializer>().getInitializer(); 02510 if (const FieldDecl *FD = Init->getAnyMember()) 02511 Out << *FD; 02512 else { 02513 QualType Ty = Init->getTypeSourceInfo()->getType(); 02514 Ty = Ty.getLocalUnqualifiedType(); 02515 LangOptions LO; // FIXME. 02516 Ty.print(Out, LO); 02517 } 02518 break; 02519 } 02520 02521 case ProgramPoint::BlockEdgeKind: { 02522 const BlockEdge &E = Loc.castAs<BlockEdge>(); 02523 Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B" 02524 << E.getDst()->getBlockID() << ')'; 02525 02526 if (const Stmt *T = E.getSrc()->getTerminator()) { 02527 SourceLocation SLoc = T->getLocStart(); 02528 02529 Out << "\\|Terminator: "; 02530 LangOptions LO; // FIXME. 02531 E.getSrc()->printTerminator(Out, LO); 02532 02533 if (SLoc.isFileID()) { 02534 Out << "\\lline=" 02535 << GraphPrintSourceManager->getExpansionLineNumber(SLoc) 02536 << " col=" 02537 << GraphPrintSourceManager->getExpansionColumnNumber(SLoc); 02538 } 02539 02540 if (isa<SwitchStmt>(T)) { 02541 const Stmt *Label = E.getDst()->getLabel(); 02542 02543 if (Label) { 02544 if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) { 02545 Out << "\\lcase "; 02546 LangOptions LO; // FIXME. 02547 if (C->getLHS()) 02548 C->getLHS()->printPretty(Out, nullptr, PrintingPolicy(LO)); 02549 02550 if (const Stmt *RHS = C->getRHS()) { 02551 Out << " .. "; 02552 RHS->printPretty(Out, nullptr, PrintingPolicy(LO)); 02553 } 02554 02555 Out << ":"; 02556 } 02557 else { 02558 assert (isa<DefaultStmt>(Label)); 02559 Out << "\\ldefault:"; 02560 } 02561 } 02562 else 02563 Out << "\\l(implicit) default:"; 02564 } 02565 else if (isa<IndirectGotoStmt>(T)) { 02566 // FIXME 02567 } 02568 else { 02569 Out << "\\lCondition: "; 02570 if (*E.getSrc()->succ_begin() == E.getDst()) 02571 Out << "true"; 02572 else 02573 Out << "false"; 02574 } 02575 02576 Out << "\\l"; 02577 } 02578 02579 #if 0 02580 // FIXME: Replace with a general scheme to determine 02581 // the name of the check. 02582 if (GraphPrintCheckerState->isUndefControlFlow(N)) { 02583 Out << "\\|Control-flow based on\\lUndefined value.\\l"; 02584 } 02585 #endif 02586 break; 02587 } 02588 02589 default: { 02590 const Stmt *S = Loc.castAs<StmtPoint>().getStmt(); 02591 assert(S != nullptr && "Expecting non-null Stmt"); 02592 02593 Out << S->getStmtClassName() << ' ' << (const void*) S << ' '; 02594 LangOptions LO; // FIXME. 02595 S->printPretty(Out, nullptr, PrintingPolicy(LO)); 02596 printLocation(Out, S->getLocStart()); 02597 02598 if (Loc.getAs<PreStmt>()) 02599 Out << "\\lPreStmt\\l;"; 02600 else if (Loc.getAs<PostLoad>()) 02601 Out << "\\lPostLoad\\l;"; 02602 else if (Loc.getAs<PostStore>()) 02603 Out << "\\lPostStore\\l"; 02604 else if (Loc.getAs<PostLValue>()) 02605 Out << "\\lPostLValue\\l"; 02606 02607 #if 0 02608 // FIXME: Replace with a general scheme to determine 02609 // the name of the check. 02610 if (GraphPrintCheckerState->isImplicitNullDeref(N)) 02611 Out << "\\|Implicit-Null Dereference.\\l"; 02612 else if (GraphPrintCheckerState->isExplicitNullDeref(N)) 02613 Out << "\\|Explicit-Null Dereference.\\l"; 02614 else if (GraphPrintCheckerState->isUndefDeref(N)) 02615 Out << "\\|Dereference of undefialied value.\\l"; 02616 else if (GraphPrintCheckerState->isUndefStore(N)) 02617 Out << "\\|Store to Undefined Loc."; 02618 else if (GraphPrintCheckerState->isUndefResult(N)) 02619 Out << "\\|Result of operation is undefined."; 02620 else if (GraphPrintCheckerState->isNoReturnCall(N)) 02621 Out << "\\|Call to function marked \"noreturn\"."; 02622 else if (GraphPrintCheckerState->isBadCall(N)) 02623 Out << "\\|Call to NULL/Undefined."; 02624 else if (GraphPrintCheckerState->isUndefArg(N)) 02625 Out << "\\|Argument in call is undefined"; 02626 #endif 02627 02628 break; 02629 } 02630 } 02631 02632 ProgramStateRef state = N->getState(); 02633 Out << "\\|StateID: " << (const void*) state.get() 02634 << " NodeID: " << (const void*) N << "\\|"; 02635 state->printDOT(Out); 02636 02637 Out << "\\l"; 02638 02639 if (const ProgramPointTag *tag = Loc.getTag()) { 02640 Out << "\\|Tag: " << tag->getTagDescription(); 02641 Out << "\\l"; 02642 } 02643 return Out.str(); 02644 } 02645 }; 02646 } // end llvm namespace 02647 #endif 02648 02649 #ifndef NDEBUG 02650 template <typename ITERATOR> 02651 ExplodedNode *GetGraphNode(ITERATOR I) { return *I; } 02652 02653 template <> ExplodedNode* 02654 GetGraphNode<llvm::DenseMap<ExplodedNode*, Expr*>::iterator> 02655 (llvm::DenseMap<ExplodedNode*, Expr*>::iterator I) { 02656 return I->first; 02657 } 02658 #endif 02659 02660 void ExprEngine::ViewGraph(bool trim) { 02661 #ifndef NDEBUG 02662 if (trim) { 02663 std::vector<const ExplodedNode*> Src; 02664 02665 // Flush any outstanding reports to make sure we cover all the nodes. 02666 // This does not cause them to get displayed. 02667 for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I) 02668 const_cast<BugType*>(*I)->FlushReports(BR); 02669 02670 // Iterate through the reports and get their nodes. 02671 for (BugReporter::EQClasses_iterator 02672 EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) { 02673 ExplodedNode *N = const_cast<ExplodedNode*>(EI->begin()->getErrorNode()); 02674 if (N) Src.push_back(N); 02675 } 02676 02677 ViewGraph(Src); 02678 } 02679 else { 02680 GraphPrintCheckerState = this; 02681 GraphPrintSourceManager = &getContext().getSourceManager(); 02682 02683 llvm::ViewGraph(*G.roots_begin(), "ExprEngine"); 02684 02685 GraphPrintCheckerState = nullptr; 02686 GraphPrintSourceManager = nullptr; 02687 } 02688 #endif 02689 } 02690 02691 void ExprEngine::ViewGraph(ArrayRef<const ExplodedNode*> Nodes) { 02692 #ifndef NDEBUG 02693 GraphPrintCheckerState = this; 02694 GraphPrintSourceManager = &getContext().getSourceManager(); 02695 02696 std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes)); 02697 02698 if (!TrimmedG.get()) 02699 llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n"; 02700 else 02701 llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine"); 02702 02703 GraphPrintCheckerState = nullptr; 02704 GraphPrintSourceManager = nullptr; 02705 #endif 02706 }