clang  7.0.0svn
ExprEngine.cpp
Go to the documentation of this file.
1 //===- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a meta-engine for path-sensitive dataflow analysis that
11 // is built on GREngine, but provides the boilerplate to execute transfer
12 // functions and build the ExplodedGraph at the expression level.
13 //
14 //===----------------------------------------------------------------------===//
15 
18 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclBase.h"
21 #include "clang/AST/DeclCXX.h"
22 #include "clang/AST/DeclObjC.h"
23 #include "clang/AST/Expr.h"
24 #include "clang/AST/ExprCXX.h"
25 #include "clang/AST/ExprObjC.h"
26 #include "clang/AST/ParentMap.h"
28 #include "clang/AST/Stmt.h"
29 #include "clang/AST/StmtCXX.h"
30 #include "clang/AST/StmtObjC.h"
31 #include "clang/AST/Type.h"
33 #include "clang/Analysis/CFG.h"
37 #include "clang/Basic/LLVM.h"
42 #include "clang/Basic/Specifiers.h"
63 #include "llvm/ADT/APSInt.h"
64 #include "llvm/ADT/DenseMap.h"
65 #include "llvm/ADT/ImmutableMap.h"
66 #include "llvm/ADT/ImmutableSet.h"
67 #include "llvm/ADT/Optional.h"
68 #include "llvm/ADT/SmallVector.h"
69 #include "llvm/ADT/Statistic.h"
70 #include "llvm/Support/Casting.h"
71 #include "llvm/Support/Compiler.h"
72 #include "llvm/Support/DOTGraphTraits.h"
73 #include "llvm/Support/ErrorHandling.h"
74 #include "llvm/Support/GraphWriter.h"
75 #include "llvm/Support/SaveAndRestore.h"
76 #include "llvm/Support/raw_ostream.h"
77 #include <cassert>
78 #include <cstdint>
79 #include <memory>
80 #include <string>
81 #include <tuple>
82 #include <utility>
83 #include <vector>
84 
85 using namespace clang;
86 using namespace ento;
87 
88 #define DEBUG_TYPE "ExprEngine"
89 
90 STATISTIC(NumRemoveDeadBindings,
91  "The # of times RemoveDeadBindings is called");
92 STATISTIC(NumMaxBlockCountReached,
93  "The # of aborted paths due to reaching the maximum block count in "
94  "a top level function");
95 STATISTIC(NumMaxBlockCountReachedInInlined,
96  "The # of aborted paths due to reaching the maximum block count in "
97  "an inlined function");
98 STATISTIC(NumTimesRetriedWithoutInlining,
99  "The # of times we re-evaluated a call without inlining");
100 
101 
102 //===----------------------------------------------------------------------===//
103 // Internal program state traits.
104 //===----------------------------------------------------------------------===//
105 
106 // When modeling a C++ constructor, for a variety of reasons we need to track
107 // the location of the object for the duration of its ConstructionContext.
108 // ObjectsUnderConstruction maps statements within the construction context
109 // to the object's location, so that on every such statement the location
110 // could have been retrieved.
111 
112 /// ConstructedObjectKey is used for being able to find the path-sensitive
113 /// memory region of a freshly constructed object while modeling the AST node
114 /// that syntactically represents the object that is being constructed.
115 /// Semantics of such nodes may sometimes require access to the region that's
116 /// not otherwise present in the program state, or to the very fact that
117 /// the construction context was present and contained references to these
118 /// AST nodes.
120  typedef std::pair<
121  llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *>,
122  const LocationContext *> ConstructedObjectKeyImpl;
123 
124  ConstructedObjectKeyImpl Impl;
125 
126  const void *getAnyASTNodePtr() const {
127  if (const Stmt *S = getStmt())
128  return S;
129  else
130  return getCXXCtorInitializer();
131  }
132 
133 public:
135  llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P,
136  const LocationContext *LC)
137  : Impl(P, LC) {
138  // This is the full list of statements that require additional actions when
139  // encountered. This list may be expanded when new actions are implemented.
140  assert(getCXXCtorInitializer() || isa<DeclStmt>(getStmt()) ||
141  isa<CXXNewExpr>(getStmt()) || isa<CXXBindTemporaryExpr>(getStmt()) ||
142  isa<MaterializeTemporaryExpr>(getStmt()));
143  }
144 
145  const Stmt *getStmt() const {
146  return Impl.first.dyn_cast<const Stmt *>();
147  }
148 
150  return Impl.first.dyn_cast<const CXXCtorInitializer *>();
151  }
152 
154  return Impl.second;
155  }
156 
157  void print(llvm::raw_ostream &OS, PrinterHelper *Helper, PrintingPolicy &PP) {
158  OS << '(' << getLocationContext() << ',' << getAnyASTNodePtr() << ") ";
159  if (const Stmt *S = getStmt()) {
160  S->printPretty(OS, Helper, PP);
161  } else {
162  const CXXCtorInitializer *I = getCXXCtorInitializer();
163  OS << I->getAnyMember()->getNameAsString();
164  }
165  }
166 
167  void Profile(llvm::FoldingSetNodeID &ID) const {
168  ID.AddPointer(Impl.first.getOpaqueValue());
169  ID.AddPointer(Impl.second);
170  }
171 
172  bool operator==(const ConstructedObjectKey &RHS) const {
173  return Impl == RHS.Impl;
174  }
175 
176  bool operator<(const ConstructedObjectKey &RHS) const {
177  return Impl < RHS.Impl;
178  }
179 };
180 
181 typedef llvm::ImmutableMap<ConstructedObjectKey, SVal>
183 REGISTER_TRAIT_WITH_PROGRAMSTATE(ObjectsUnderConstruction,
185 
186 
187 //===----------------------------------------------------------------------===//
188 // Engine construction and deletion.
189 //===----------------------------------------------------------------------===//
190 
191 static const char* TagProviderName = "ExprEngine";
192 
194  AnalysisManager &mgr, bool gcEnabled,
195  SetOfConstDecls *VisitedCalleesIn,
197  InliningModes HowToInlineIn)
198  : CTU(CTU), AMgr(mgr),
199  AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
200  Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.getGraph()),
201  StateMgr(getContext(), mgr.getStoreManagerCreator(),
202  mgr.getConstraintManagerCreator(), G.getAllocator(),
203  this),
204  SymMgr(StateMgr.getSymbolManager()),
205  svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
206  ObjCGCEnabled(gcEnabled), BR(mgr, *this),
207  VisitedCallees(VisitedCalleesIn), HowToInline(HowToInlineIn) {
208  unsigned TrimInterval = mgr.options.getGraphTrimInterval();
209  if (TrimInterval != 0) {
210  // Enable eager node reclaimation when constructing the ExplodedGraph.
211  G.enableNodeReclamation(TrimInterval);
212  }
213 }
214 
216  BR.FlushReports();
217 }
218 
219 //===----------------------------------------------------------------------===//
220 // Utility methods.
221 //===----------------------------------------------------------------------===//
222 
224  ProgramStateRef state = StateMgr.getInitialState(InitLoc);
225  const Decl *D = InitLoc->getDecl();
226 
227  // Preconditions.
228  // FIXME: It would be nice if we had a more general mechanism to add
229  // such preconditions. Some day.
230  do {
231  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
232  // Precondition: the first argument of 'main' is an integer guaranteed
233  // to be > 0.
234  const IdentifierInfo *II = FD->getIdentifier();
235  if (!II || !(II->getName() == "main" && FD->getNumParams() > 0))
236  break;
237 
238  const ParmVarDecl *PD = FD->getParamDecl(0);
239  QualType T = PD->getType();
240  const auto *BT = dyn_cast<BuiltinType>(T);
241  if (!BT || !BT->isInteger())
242  break;
243 
244  const MemRegion *R = state->getRegion(PD, InitLoc);
245  if (!R)
246  break;
247 
248  SVal V = state->getSVal(loc::MemRegionVal(R));
249  SVal Constraint_untested = evalBinOp(state, BO_GT, V,
250  svalBuilder.makeZeroVal(T),
251  svalBuilder.getConditionType());
252 
253  Optional<DefinedOrUnknownSVal> Constraint =
254  Constraint_untested.getAs<DefinedOrUnknownSVal>();
255 
256  if (!Constraint)
257  break;
258 
259  if (ProgramStateRef newState = state->assume(*Constraint, true))
260  state = newState;
261  }
262  break;
263  }
264  while (false);
265 
266  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
267  // Precondition: 'self' is always non-null upon entry to an Objective-C
268  // method.
269  const ImplicitParamDecl *SelfD = MD->getSelfDecl();
270  const MemRegion *R = state->getRegion(SelfD, InitLoc);
271  SVal V = state->getSVal(loc::MemRegionVal(R));
272 
273  if (Optional<Loc> LV = V.getAs<Loc>()) {
274  // Assume that the pointer value in 'self' is non-null.
275  state = state->assume(*LV, true);
276  assert(state && "'self' cannot be null");
277  }
278  }
279 
280  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
281  if (!MD->isStatic()) {
282  // Precondition: 'this' is always non-null upon entry to the
283  // top-level function. This is our starting assumption for
284  // analyzing an "open" program.
285  const StackFrameContext *SFC = InitLoc->getCurrentStackFrame();
286  if (SFC->getParent() == nullptr) {
287  loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC);
288  SVal V = state->getSVal(L);
289  if (Optional<Loc> LV = V.getAs<Loc>()) {
290  state = state->assume(*LV, true);
291  assert(state && "'this' cannot be null");
292  }
293  }
294  }
295  }
296 
297  return state;
298 }
299 
301 ExprEngine::createTemporaryRegionIfNeeded(ProgramStateRef State,
302  const LocationContext *LC,
303  const Expr *InitWithAdjustments,
304  const Expr *Result) {
305  // FIXME: This function is a hack that works around the quirky AST
306  // we're often having with respect to C++ temporaries. If only we modelled
307  // the actual execution order of statements properly in the CFG,
308  // all the hassle with adjustments would not be necessary,
309  // and perhaps the whole function would be removed.
310  SVal InitValWithAdjustments = State->getSVal(InitWithAdjustments, LC);
311  if (!Result) {
312  // If we don't have an explicit result expression, we're in "if needed"
313  // mode. Only create a region if the current value is a NonLoc.
314  if (!InitValWithAdjustments.getAs<NonLoc>())
315  return State;
316  Result = InitWithAdjustments;
317  } else {
318  // We need to create a region no matter what. For sanity, make sure we don't
319  // try to stuff a Loc into a non-pointer temporary region.
320  assert(!InitValWithAdjustments.getAs<Loc>() ||
321  Loc::isLocType(Result->getType()) ||
322  Result->getType()->isMemberPointerType());
323  }
324 
325  ProgramStateManager &StateMgr = State->getStateManager();
326  MemRegionManager &MRMgr = StateMgr.getRegionManager();
327  StoreManager &StoreMgr = StateMgr.getStoreManager();
328 
329  // MaterializeTemporaryExpr may appear out of place, after a few field and
330  // base-class accesses have been made to the object, even though semantically
331  // it is the whole object that gets materialized and lifetime-extended.
332  //
333  // For example:
334  //
335  // `-MaterializeTemporaryExpr
336  // `-MemberExpr
337  // `-CXXTemporaryObjectExpr
338  //
339  // instead of the more natural
340  //
341  // `-MemberExpr
342  // `-MaterializeTemporaryExpr
343  // `-CXXTemporaryObjectExpr
344  //
345  // Use the usual methods for obtaining the expression of the base object,
346  // and record the adjustments that we need to make to obtain the sub-object
347  // that the whole expression 'Ex' refers to. This trick is usual,
348  // in the sense that CodeGen takes a similar route.
349 
352 
353  const Expr *Init = InitWithAdjustments->skipRValueSubobjectAdjustments(
354  CommaLHSs, Adjustments);
355 
356  // Take the region for Init, i.e. for the whole object. If we do not remember
357  // the region in which the object originally was constructed, come up with
358  // a new temporary region out of thin air and copy the contents of the object
359  // (which are currently present in the Environment, because Init is an rvalue)
360  // into that region. This is not correct, but it is better than nothing.
361  bool FoundOriginalMaterializationRegion = false;
362  const TypedValueRegion *TR = nullptr;
363  if (const auto *MT = dyn_cast<MaterializeTemporaryExpr>(Result)) {
364  if (Optional<SVal> V = getObjectUnderConstruction(State, MT, LC)) {
365  FoundOriginalMaterializationRegion = true;
366  TR = cast<CXXTempObjectRegion>(V->getAsRegion());
367  assert(TR);
368  State = finishObjectConstruction(State, MT, LC);
369  } else {
370  StorageDuration SD = MT->getStorageDuration();
371  // If this object is bound to a reference with static storage duration, we
372  // put it in a different region to prevent "address leakage" warnings.
373  if (SD == SD_Static || SD == SD_Thread) {
374  TR = MRMgr.getCXXStaticTempObjectRegion(Init);
375  } else {
376  TR = MRMgr.getCXXTempObjectRegion(Init, LC);
377  }
378  }
379  } else {
380  TR = MRMgr.getCXXTempObjectRegion(Init, LC);
381  }
382 
383  SVal Reg = loc::MemRegionVal(TR);
384  SVal BaseReg = Reg;
385 
386  // Make the necessary adjustments to obtain the sub-object.
387  for (auto I = Adjustments.rbegin(), E = Adjustments.rend(); I != E; ++I) {
388  const SubobjectAdjustment &Adj = *I;
389  switch (Adj.Kind) {
391  Reg = StoreMgr.evalDerivedToBase(Reg, Adj.DerivedToBase.BasePath);
392  break;
394  Reg = StoreMgr.getLValueField(Adj.Field, Reg);
395  break;
397  // FIXME: Unimplemented.
398  State = State->invalidateRegions(Reg, InitWithAdjustments,
399  currBldrCtx->blockCount(), LC, true,
400  nullptr, nullptr, nullptr);
401  return State;
402  }
403  }
404 
405  if (!FoundOriginalMaterializationRegion) {
406  // What remains is to copy the value of the object to the new region.
407  // FIXME: In other words, what we should always do is copy value of the
408  // Init expression (which corresponds to the bigger object) to the whole
409  // temporary region TR. However, this value is often no longer present
410  // in the Environment. If it has disappeared, we instead invalidate TR.
411  // Still, what we can do is assign the value of expression Ex (which
412  // corresponds to the sub-object) to the TR's sub-region Reg. At least,
413  // values inside Reg would be correct.
414  SVal InitVal = State->getSVal(Init, LC);
415  if (InitVal.isUnknown()) {
416  InitVal = getSValBuilder().conjureSymbolVal(Result, LC, Init->getType(),
417  currBldrCtx->blockCount());
418  State = State->bindLoc(BaseReg.castAs<Loc>(), InitVal, LC, false);
419 
420  // Then we'd need to take the value that certainly exists and bind it
421  // over.
422  if (InitValWithAdjustments.isUnknown()) {
423  // Try to recover some path sensitivity in case we couldn't
424  // compute the value.
425  InitValWithAdjustments = getSValBuilder().conjureSymbolVal(
426  Result, LC, InitWithAdjustments->getType(),
427  currBldrCtx->blockCount());
428  }
429  State =
430  State->bindLoc(Reg.castAs<Loc>(), InitValWithAdjustments, LC, false);
431  } else {
432  State = State->bindLoc(BaseReg.castAs<Loc>(), InitVal, LC, false);
433  }
434  }
435 
436  // The result expression would now point to the correct sub-region of the
437  // newly created temporary region. Do this last in order to getSVal of Init
438  // correctly in case (Result == Init).
439  State = State->BindExpr(Result, LC, Reg);
440 
441  if (!FoundOriginalMaterializationRegion) {
442  // Notify checkers once for two bindLoc()s.
443  State = processRegionChange(State, TR, LC);
444  }
445 
446  return State;
447 }
448 
449 ProgramStateRef ExprEngine::addObjectUnderConstruction(
450  ProgramStateRef State,
451  llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P,
452  const LocationContext *LC, SVal V) {
454  // FIXME: Currently the state might already contain the marker due to
455  // incorrect handling of temporaries bound to default parameters.
456  assert(!State->get<ObjectsUnderConstruction>(Key) ||
457  isa<CXXBindTemporaryExpr>(Key.getStmt()));
458  return State->set<ObjectsUnderConstruction>(Key, V);
459 }
460 
461 Optional<SVal> ExprEngine::getObjectUnderConstruction(
462  ProgramStateRef State,
463  llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P,
464  const LocationContext *LC) {
466  return Optional<SVal>::create(State->get<ObjectsUnderConstruction>(Key));
467 }
468 
469 ProgramStateRef ExprEngine::finishObjectConstruction(
470  ProgramStateRef State,
471  llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P,
472  const LocationContext *LC) {
474  assert(State->contains<ObjectsUnderConstruction>(Key));
475  return State->remove<ObjectsUnderConstruction>(Key);
476 }
477 
478 bool ExprEngine::areAllObjectsFullyConstructed(ProgramStateRef State,
479  const LocationContext *FromLC,
480  const LocationContext *ToLC) {
481  const LocationContext *LC = FromLC;
482  while (LC != ToLC) {
483  assert(LC && "ToLC must be a parent of FromLC!");
484  for (auto I : State->get<ObjectsUnderConstruction>())
485  if (I.first.getLocationContext() == LC)
486  return false;
487 
488  LC = LC->getParent();
489  }
490  return true;
491 }
492 
493 
494 //===----------------------------------------------------------------------===//
495 // Top-level transfer function logic (Dispatcher).
496 //===----------------------------------------------------------------------===//
497 
498 /// evalAssume - Called by ConstraintManager. Used to call checker-specific
499 /// logic for handling assumptions on symbolic values.
501  SVal cond, bool assumption) {
502  return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption);
503 }
504 
507  const InvalidatedSymbols *invalidated,
508  ArrayRef<const MemRegion *> Explicits,
510  const LocationContext *LCtx,
511  const CallEvent *Call) {
512  return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
513  Explicits, Regions,
514  LCtx, Call);
515 }
516 
517 static void printObjectsUnderConstructionForContext(raw_ostream &Out,
518  ProgramStateRef State,
519  const char *NL,
520  const char *Sep,
521  const LocationContext *LC) {
522  PrintingPolicy PP =
524  for (auto I : State->get<ObjectsUnderConstruction>()) {
525  ConstructedObjectKey Key = I.first;
526  SVal Value = I.second;
527  if (Key.getLocationContext() != LC)
528  continue;
529  Key.print(Out, nullptr, PP);
530  Out << " : " << Value << NL;
531  }
532 }
533 
534 void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
535  const char *NL, const char *Sep,
536  const LocationContext *LCtx) {
537  if (LCtx) {
538  if (!State->get<ObjectsUnderConstruction>().isEmpty()) {
539  Out << Sep << "Objects under construction:" << NL;
540 
541  LCtx->dumpStack(Out, "", NL, Sep, [&](const LocationContext *LC) {
542  printObjectsUnderConstructionForContext(Out, State, NL, Sep, LC);
543  });
544  }
545  }
546 
547  getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep);
548 }
549 
552 }
553 
555  unsigned StmtIdx, NodeBuilderContext *Ctx) {
557  currStmtIdx = StmtIdx;
558  currBldrCtx = Ctx;
559 
560  switch (E.getKind()) {
564  ProcessStmt(E.castAs<CFGStmt>().getStmt(), Pred);
565  return;
568  return;
571  Pred);
572  return;
579  return;
582  return;
586  return;
587  }
588 }
589 
591  const Stmt *S,
592  const ExplodedNode *Pred,
593  const LocationContext *LC) {
594  // Are we never purging state values?
595  if (AMgr.options.AnalysisPurgeOpt == PurgeNone)
596  return false;
597 
598  // Is this the beginning of a basic block?
599  if (Pred->getLocation().getAs<BlockEntrance>())
600  return true;
601 
602  // Is this on a non-expression?
603  if (!isa<Expr>(S))
604  return true;
605 
606  // Run before processing a call.
607  if (CallEvent::isCallStmt(S))
608  return true;
609 
610  // Is this an expression that is consumed by another expression? If so,
611  // postpone cleaning out the state.
613  return !PM.isConsumedExpr(cast<Expr>(S));
614 }
615 
617  const Stmt *ReferenceStmt,
618  const LocationContext *LC,
619  const Stmt *DiagnosticStmt,
620  ProgramPoint::Kind K) {
622  ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt))
623  && "PostStmt is not generally supported by the SymbolReaper yet");
624  assert(LC && "Must pass the current (or expiring) LocationContext");
625 
626  if (!DiagnosticStmt) {
627  DiagnosticStmt = ReferenceStmt;
628  assert(DiagnosticStmt && "Required for clearing a LocationContext");
629  }
630 
631  NumRemoveDeadBindings++;
632  ProgramStateRef CleanedState = Pred->getState();
633 
634  // LC is the location context being destroyed, but SymbolReaper wants a
635  // location context that is still live. (If this is the top-level stack
636  // frame, this will be null.)
637  if (!ReferenceStmt) {
639  "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
640  LC = LC->getParent();
641  }
642 
643  const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : nullptr;
644  SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager());
645 
646  for (auto I : CleanedState->get<ObjectsUnderConstruction>()) {
647  if (SymbolRef Sym = I.second.getAsSymbol())
648  SymReaper.markLive(Sym);
649  if (const MemRegion *MR = I.second.getAsRegion())
650  SymReaper.markLive(MR);
651  }
652 
653  getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper);
654 
655  // Create a state in which dead bindings are removed from the environment
656  // and the store. TODO: The function should just return new env and store,
657  // not a new state.
658  CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper);
659 
660  // Process any special transfer function for dead symbols.
661  // A tag to track convenience transitions, which can be removed at cleanup.
662  static SimpleProgramPointTag cleanupTag(TagProviderName, "Clean Node");
663  if (!SymReaper.hasDeadSymbols()) {
664  // Generate a CleanedNode that has the environment and store cleaned
665  // up. Since no symbols are dead, we can optimize and not clean out
666  // the constraint manager.
667  StmtNodeBuilder Bldr(Pred, Out, *currBldrCtx);
668  Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K);
669 
670  } else {
671  // Call checkers with the non-cleaned state so that they could query the
672  // values of the soon to be dead symbols.
673  ExplodedNodeSet CheckedSet;
674  getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper,
675  DiagnosticStmt, *this, K);
676 
677  // For each node in CheckedSet, generate CleanedNodes that have the
678  // environment, the store, and the constraints cleaned up but have the
679  // user-supplied states as the predecessors.
680  StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx);
681  for (const auto I : CheckedSet) {
682  ProgramStateRef CheckerState = I->getState();
683 
684  // The constraint manager has not been cleaned up yet, so clean up now.
685  CheckerState = getConstraintManager().removeDeadBindings(CheckerState,
686  SymReaper);
687 
688  assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->getState()) &&
689  "Checkers are not allowed to modify the Environment as a part of "
690  "checkDeadSymbols processing.");
691  assert(StateMgr.haveEqualStores(CheckerState, Pred->getState()) &&
692  "Checkers are not allowed to modify the Store as a part of "
693  "checkDeadSymbols processing.");
694 
695  // Create a state based on CleanedState with CheckerState GDM and
696  // generate a transition to that state.
697  ProgramStateRef CleanedCheckerSt =
698  StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
699  Bldr.generateNode(DiagnosticStmt, I, CleanedCheckerSt, &cleanupTag, K);
700  }
701  }
702 }
703 
704 void ExprEngine::ProcessStmt(const Stmt *currStmt, ExplodedNode *Pred) {
705  // Reclaim any unnecessary nodes in the ExplodedGraph.
707 
708  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
709  currStmt->getLocStart(),
710  "Error evaluating statement");
711 
712  // Remove dead bindings and symbols.
713  ExplodedNodeSet CleanedStates;
714  if (shouldRemoveDeadBindings(AMgr, currStmt, Pred,
715  Pred->getLocationContext())) {
716  removeDead(Pred, CleanedStates, currStmt,
717  Pred->getLocationContext());
718  } else
719  CleanedStates.Add(Pred);
720 
721  // Visit the statement.
722  ExplodedNodeSet Dst;
723  for (const auto I : CleanedStates) {
724  ExplodedNodeSet DstI;
725  // Visit the statement.
726  Visit(currStmt, I, DstI);
727  Dst.insert(DstI);
728  }
729 
730  // Enqueue the new nodes onto the work list.
731  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
732 }
733 
735  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
736  S->getLocStart(),
737  "Error evaluating end of the loop");
738  ExplodedNodeSet Dst;
739  Dst.Add(Pred);
740  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
741  ProgramStateRef NewState = Pred->getState();
742 
743  if(AMgr.options.shouldUnrollLoops())
744  NewState = processLoopEnd(S, NewState);
745 
746  LoopExit PP(S, Pred->getLocationContext());
747  Bldr.generateNode(PP, NewState, Pred);
748  // Enqueue the new nodes onto the work list.
749  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
750 }
751 
753  ExplodedNode *Pred) {
754  const CXXCtorInitializer *BMI = CFGInit.getInitializer();
755  const Expr *Init = BMI->getInit()->IgnoreImplicit();
756  const LocationContext *LC = Pred->getLocationContext();
757 
758  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
759  BMI->getSourceLocation(),
760  "Error evaluating initializer");
761 
762  // We don't clean up dead bindings here.
763  const auto *stackFrame = cast<StackFrameContext>(Pred->getLocationContext());
764  const auto *decl = cast<CXXConstructorDecl>(stackFrame->getDecl());
765 
766  ProgramStateRef State = Pred->getState();
767  SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame));
768 
769  ExplodedNodeSet Tmp;
770  SVal FieldLoc;
771 
772  // Evaluate the initializer, if necessary
773  if (BMI->isAnyMemberInitializer()) {
774  // Constructors build the object directly in the field,
775  // but non-objects must be copied in from the initializer.
776  if (getObjectUnderConstruction(State, BMI, LC)) {
777  // The field was directly constructed, so there is no need to bind.
778  // But we still need to stop tracking the object under construction.
779  State = finishObjectConstruction(State, BMI, LC);
780  NodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
781  PostStore PS(Init, LC, /*Loc*/ nullptr, /*tag*/ nullptr);
782  Bldr.generateNode(PS, State, Pred);
783  } else {
784  const ValueDecl *Field;
785  if (BMI->isIndirectMemberInitializer()) {
786  Field = BMI->getIndirectMember();
787  FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal);
788  } else {
789  Field = BMI->getMember();
790  FieldLoc = State->getLValue(BMI->getMember(), thisVal);
791  }
792 
793  SVal InitVal;
794  if (Init->getType()->isArrayType()) {
795  // Handle arrays of trivial type. We can represent this with a
796  // primitive load/copy from the base array region.
797  const ArraySubscriptExpr *ASE;
798  while ((ASE = dyn_cast<ArraySubscriptExpr>(Init)))
799  Init = ASE->getBase()->IgnoreImplicit();
800 
801  SVal LValue = State->getSVal(Init, stackFrame);
802  if (!Field->getType()->isReferenceType())
803  if (Optional<Loc> LValueLoc = LValue.getAs<Loc>())
804  InitVal = State->getSVal(*LValueLoc);
805 
806  // If we fail to get the value for some reason, use a symbolic value.
807  if (InitVal.isUnknownOrUndef()) {
808  SValBuilder &SVB = getSValBuilder();
809  InitVal = SVB.conjureSymbolVal(BMI->getInit(), stackFrame,
810  Field->getType(),
811  currBldrCtx->blockCount());
812  }
813  } else {
814  InitVal = State->getSVal(BMI->getInit(), stackFrame);
815  }
816 
817  PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame);
818  evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP);
819  }
820  } else {
821  assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer());
822  Tmp.insert(Pred);
823  // We already did all the work when visiting the CXXConstructExpr.
824  }
825 
826  // Construct PostInitializer nodes whether the state changed or not,
827  // so that the diagnostics don't get confused.
828  PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame);
829  ExplodedNodeSet Dst;
830  NodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
831  for (const auto I : Tmp) {
832  ProgramStateRef State = I->getState();
833  Bldr.generateNode(PP, State, I);
834  }
835 
836  // Enqueue the new nodes onto the work list.
837  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
838 }
839 
841  ExplodedNode *Pred) {
842  ExplodedNodeSet Dst;
843  switch (D.getKind()) {
846  break;
848  ProcessBaseDtor(D.castAs<CFGBaseDtor>(), Pred, Dst);
849  break;
851  ProcessMemberDtor(D.castAs<CFGMemberDtor>(), Pred, Dst);
852  break;
855  break;
857  ProcessDeleteDtor(D.castAs<CFGDeleteDtor>(), Pred, Dst);
858  break;
859  default:
860  llvm_unreachable("Unexpected dtor kind.");
861  }
862 
863  // Enqueue the new nodes onto the work list.
864  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
865 }
866 
868  ExplodedNode *Pred) {
869  ExplodedNodeSet Dst;
871  AnalyzerOptions &Opts = AMgr.options;
872  // TODO: We're not evaluating allocators for all cases just yet as
873  // we're not handling the return value correctly, which causes false
874  // positives when the alpha.cplusplus.NewDeleteLeaks check is on.
875  if (Opts.mayInlineCXXAllocator())
876  VisitCXXNewAllocatorCall(NE, Pred, Dst);
877  else {
878  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
879  const LocationContext *LCtx = Pred->getLocationContext();
880  PostImplicitCall PP(NE->getOperatorNew(), NE->getLocStart(), LCtx);
881  Bldr.generateNode(PP, Pred->getState(), Pred);
882  }
883  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
884 }
885 
887  ExplodedNode *Pred,
888  ExplodedNodeSet &Dst) {
889  const VarDecl *varDecl = Dtor.getVarDecl();
890  QualType varType = varDecl->getType();
891 
892  ProgramStateRef state = Pred->getState();
893  SVal dest = state->getLValue(varDecl, Pred->getLocationContext());
894  const MemRegion *Region = dest.castAs<loc::MemRegionVal>().getRegion();
895 
896  if (varType->isReferenceType()) {
897  const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
898  if (!ValueRegion) {
899  // FIXME: This should not happen. The language guarantees a presence
900  // of a valid initializer here, so the reference shall not be undefined.
901  // It seems that we're calling destructors over variables that
902  // were not initialized yet.
903  return;
904  }
905  Region = ValueRegion->getBaseRegion();
906  varType = cast<TypedValueRegion>(Region)->getValueType();
907  }
908 
909  // FIXME: We need to run the same destructor on every element of the array.
910  // This workaround will just run the first destructor (which will still
911  // invalidate the entire array).
912  EvalCallOptions CallOpts;
913  Region = makeZeroElementRegion(state, loc::MemRegionVal(Region), varType,
914  CallOpts.IsArrayCtorOrDtor).getAsRegion();
915 
916  VisitCXXDestructor(varType, Region, Dtor.getTriggerStmt(), /*IsBase=*/ false,
917  Pred, Dst, CallOpts);
918 }
919 
921  ExplodedNode *Pred,
922  ExplodedNodeSet &Dst) {
923  ProgramStateRef State = Pred->getState();
924  const LocationContext *LCtx = Pred->getLocationContext();
925  const CXXDeleteExpr *DE = Dtor.getDeleteExpr();
926  const Stmt *Arg = DE->getArgument();
927  QualType DTy = DE->getDestroyedType();
928  SVal ArgVal = State->getSVal(Arg, LCtx);
929 
930  // If the argument to delete is known to be a null value,
931  // don't run destructor.
932  if (State->isNull(ArgVal).isConstrainedTrue()) {
934  const CXXRecordDecl *RD = BTy->getAsCXXRecordDecl();
935  const CXXDestructorDecl *Dtor = RD->getDestructor();
936 
937  PostImplicitCall PP(Dtor, DE->getLocStart(), LCtx);
938  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
939  Bldr.generateNode(PP, Pred->getState(), Pred);
940  return;
941  }
942 
943  EvalCallOptions CallOpts;
944  const MemRegion *ArgR = ArgVal.getAsRegion();
945  if (DE->isArrayForm()) {
946  // FIXME: We need to run the same destructor on every element of the array.
947  // This workaround will just run the first destructor (which will still
948  // invalidate the entire array).
949  CallOpts.IsArrayCtorOrDtor = true;
950  // Yes, it may even be a multi-dimensional array.
951  while (const auto *AT = getContext().getAsArrayType(DTy))
952  DTy = AT->getElementType();
953  if (ArgR)
954  ArgR = getStoreManager().GetElementZeroRegion(cast<SubRegion>(ArgR), DTy);
955  }
956 
957  VisitCXXDestructor(DTy, ArgR, DE, /*IsBase=*/false, Pred, Dst, CallOpts);
958 }
959 
961  ExplodedNode *Pred, ExplodedNodeSet &Dst) {
962  const LocationContext *LCtx = Pred->getLocationContext();
963 
964  const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
965  Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor,
966  LCtx->getCurrentStackFrame());
967  SVal ThisVal = Pred->getState()->getSVal(ThisPtr);
968 
969  // Create the base object region.
971  QualType BaseTy = Base->getType();
972  SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy,
973  Base->isVirtual());
974 
976  CurDtor->getBody(), /*IsBase=*/ true, Pred, Dst, {});
977 }
978 
980  ExplodedNode *Pred, ExplodedNodeSet &Dst) {
981  const FieldDecl *Member = D.getFieldDecl();
982  QualType T = Member->getType();
983  ProgramStateRef State = Pred->getState();
984  const LocationContext *LCtx = Pred->getLocationContext();
985 
986  const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
987  Loc ThisVal = getSValBuilder().getCXXThis(CurDtor,
988  LCtx->getCurrentStackFrame());
989  SVal FieldVal =
990  State->getLValue(Member, State->getSVal(ThisVal).castAs<Loc>());
991 
992  // FIXME: We need to run the same destructor on every element of the array.
993  // This workaround will just run the first destructor (which will still
994  // invalidate the entire array).
995  EvalCallOptions CallOpts;
996  FieldVal = makeZeroElementRegion(State, FieldVal, T,
997  CallOpts.IsArrayCtorOrDtor);
998 
1000  CurDtor->getBody(), /*IsBase=*/false, Pred, Dst, CallOpts);
1001 }
1002 
1004  ExplodedNode *Pred,
1005  ExplodedNodeSet &Dst) {
1006  ExplodedNodeSet CleanDtorState;
1007  StmtNodeBuilder StmtBldr(Pred, CleanDtorState, *currBldrCtx);
1008  ProgramStateRef State = Pred->getState();
1009  const MemRegion *MR = nullptr;
1010  if (Optional<SVal> V =
1011  getObjectUnderConstruction(State, D.getBindTemporaryExpr(),
1012  Pred->getLocationContext())) {
1013  // FIXME: Currently we insert temporary destructors for default parameters,
1014  // but we don't insert the constructors, so the entry in
1015  // ObjectsUnderConstruction may be missing.
1016  State = finishObjectConstruction(State, D.getBindTemporaryExpr(),
1017  Pred->getLocationContext());
1018  MR = V->getAsRegion();
1019  }
1020  StmtBldr.generateNode(D.getBindTemporaryExpr(), Pred, State);
1021 
1023  // FIXME: Currently CleanDtorState can be empty here due to temporaries being
1024  // bound to default parameters.
1025  assert(CleanDtorState.size() <= 1);
1026  ExplodedNode *CleanPred =
1027  CleanDtorState.empty() ? Pred : *CleanDtorState.begin();
1028 
1029  EvalCallOptions CallOpts;
1030  CallOpts.IsTemporaryCtorOrDtor = true;
1031  if (!MR) {
1033 
1034  // If we have no MR, we still need to unwrap the array to avoid destroying
1035  // the whole array at once. Regardless, we'd eventually need to model array
1036  // destructors properly, element-by-element.
1037  while (const ArrayType *AT = getContext().getAsArrayType(T)) {
1038  T = AT->getElementType();
1039  CallOpts.IsArrayCtorOrDtor = true;
1040  }
1041  } else {
1042  // We'd eventually need to makeZeroElementRegion() trick here,
1043  // but for now we don't have the respective construction contexts,
1044  // so MR would always be null in this case. Do nothing for now.
1045  }
1047  /*IsBase=*/false, CleanPred, Dst, CallOpts);
1048 }
1049 
1051  NodeBuilderContext &BldCtx,
1052  ExplodedNode *Pred,
1053  ExplodedNodeSet &Dst,
1054  const CFGBlock *DstT,
1055  const CFGBlock *DstF) {
1056  BranchNodeBuilder TempDtorBuilder(Pred, Dst, BldCtx, DstT, DstF);
1057  ProgramStateRef State = Pred->getState();
1058  const LocationContext *LC = Pred->getLocationContext();
1059  if (getObjectUnderConstruction(State, BTE, LC)) {
1060  TempDtorBuilder.markInfeasible(false);
1061  TempDtorBuilder.generateNode(State, true, Pred);
1062  } else {
1063  TempDtorBuilder.markInfeasible(true);
1064  TempDtorBuilder.generateNode(State, false, Pred);
1065  }
1066 }
1067 
1069  ExplodedNodeSet &PreVisit,
1070  ExplodedNodeSet &Dst) {
1071  // This is a fallback solution in case we didn't have a construction
1072  // context when we were constructing the temporary. Otherwise the map should
1073  // have been populated there.
1074  if (!getAnalysisManager().options.includeTemporaryDtorsInCFG()) {
1075  // In case we don't have temporary destructors in the CFG, do not mark
1076  // the initialization - we would otherwise never clean it up.
1077  Dst = PreVisit;
1078  return;
1079  }
1080  StmtNodeBuilder StmtBldr(PreVisit, Dst, *currBldrCtx);
1081  for (ExplodedNode *Node : PreVisit) {
1082  ProgramStateRef State = Node->getState();
1083  const LocationContext *LC = Node->getLocationContext();
1084  if (!getObjectUnderConstruction(State, BTE, LC)) {
1085  // FIXME: Currently the state might also already contain the marker due to
1086  // incorrect handling of temporaries bound to default parameters; for
1087  // those, we currently skip the CXXBindTemporaryExpr but rely on adding
1088  // temporary destructor nodes.
1089  State = addObjectUnderConstruction(State, BTE, LC, UnknownVal());
1090  }
1091  StmtBldr.generateNode(BTE, Node, State);
1092  }
1093 }
1094 
1096  PointerEscapeKind K) const {
1097  class CollectReachableSymbolsCallback final : public SymbolVisitor {
1098  InvalidatedSymbols Symbols;
1099 
1100  public:
1101  explicit CollectReachableSymbolsCallback(ProgramStateRef State) {}
1102 
1103  const InvalidatedSymbols &getSymbols() const { return Symbols; }
1104 
1105  bool VisitSymbol(SymbolRef Sym) override {
1106  Symbols.insert(Sym);
1107  return true;
1108  }
1109  };
1110 
1111  const CollectReachableSymbolsCallback &Scanner =
1112  State->scanReachableSymbols<CollectReachableSymbolsCallback>(V);
1114  State, Scanner.getSymbols(), /*CallEvent*/ nullptr, K, nullptr);
1115 }
1116 
1117 void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
1118  ExplodedNodeSet &DstTop) {
1119  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
1120  S->getLocStart(),
1121  "Error evaluating statement");
1122  ExplodedNodeSet Dst;
1123  StmtNodeBuilder Bldr(Pred, DstTop, *currBldrCtx);
1124 
1125  assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
1126 
1127  switch (S->getStmtClass()) {
1128  // C++, OpenMP and ARC stuff we don't support yet.
1129  case Expr::ObjCIndirectCopyRestoreExprClass:
1130  case Stmt::CXXDependentScopeMemberExprClass:
1131  case Stmt::CXXInheritedCtorInitExprClass:
1132  case Stmt::CXXTryStmtClass:
1133  case Stmt::CXXTypeidExprClass:
1134  case Stmt::CXXUuidofExprClass:
1135  case Stmt::CXXFoldExprClass:
1136  case Stmt::MSPropertyRefExprClass:
1137  case Stmt::MSPropertySubscriptExprClass:
1138  case Stmt::CXXUnresolvedConstructExprClass:
1139  case Stmt::DependentScopeDeclRefExprClass:
1140  case Stmt::ArrayTypeTraitExprClass:
1141  case Stmt::ExpressionTraitExprClass:
1142  case Stmt::UnresolvedLookupExprClass:
1143  case Stmt::UnresolvedMemberExprClass:
1144  case Stmt::TypoExprClass:
1145  case Stmt::CXXNoexceptExprClass:
1146  case Stmt::PackExpansionExprClass:
1147  case Stmt::SubstNonTypeTemplateParmPackExprClass:
1148  case Stmt::FunctionParmPackExprClass:
1149  case Stmt::CoroutineBodyStmtClass:
1150  case Stmt::CoawaitExprClass:
1151  case Stmt::DependentCoawaitExprClass:
1152  case Stmt::CoreturnStmtClass:
1153  case Stmt::CoyieldExprClass:
1154  case Stmt::SEHTryStmtClass:
1155  case Stmt::SEHExceptStmtClass:
1156  case Stmt::SEHLeaveStmtClass:
1157  case Stmt::SEHFinallyStmtClass:
1158  case Stmt::OMPParallelDirectiveClass:
1159  case Stmt::OMPSimdDirectiveClass:
1160  case Stmt::OMPForDirectiveClass:
1161  case Stmt::OMPForSimdDirectiveClass:
1162  case Stmt::OMPSectionsDirectiveClass:
1163  case Stmt::OMPSectionDirectiveClass:
1164  case Stmt::OMPSingleDirectiveClass:
1165  case Stmt::OMPMasterDirectiveClass:
1166  case Stmt::OMPCriticalDirectiveClass:
1167  case Stmt::OMPParallelForDirectiveClass:
1168  case Stmt::OMPParallelForSimdDirectiveClass:
1169  case Stmt::OMPParallelSectionsDirectiveClass:
1170  case Stmt::OMPTaskDirectiveClass:
1171  case Stmt::OMPTaskyieldDirectiveClass:
1172  case Stmt::OMPBarrierDirectiveClass:
1173  case Stmt::OMPTaskwaitDirectiveClass:
1174  case Stmt::OMPTaskgroupDirectiveClass:
1175  case Stmt::OMPFlushDirectiveClass:
1176  case Stmt::OMPOrderedDirectiveClass:
1177  case Stmt::OMPAtomicDirectiveClass:
1178  case Stmt::OMPTargetDirectiveClass:
1179  case Stmt::OMPTargetDataDirectiveClass:
1180  case Stmt::OMPTargetEnterDataDirectiveClass:
1181  case Stmt::OMPTargetExitDataDirectiveClass:
1182  case Stmt::OMPTargetParallelDirectiveClass:
1183  case Stmt::OMPTargetParallelForDirectiveClass:
1184  case Stmt::OMPTargetUpdateDirectiveClass:
1185  case Stmt::OMPTeamsDirectiveClass:
1186  case Stmt::OMPCancellationPointDirectiveClass:
1187  case Stmt::OMPCancelDirectiveClass:
1188  case Stmt::OMPTaskLoopDirectiveClass:
1189  case Stmt::OMPTaskLoopSimdDirectiveClass:
1190  case Stmt::OMPDistributeDirectiveClass:
1191  case Stmt::OMPDistributeParallelForDirectiveClass:
1192  case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1193  case Stmt::OMPDistributeSimdDirectiveClass:
1194  case Stmt::OMPTargetParallelForSimdDirectiveClass:
1195  case Stmt::OMPTargetSimdDirectiveClass:
1196  case Stmt::OMPTeamsDistributeDirectiveClass:
1197  case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1198  case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1199  case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1200  case Stmt::OMPTargetTeamsDirectiveClass:
1201  case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1202  case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1203  case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1204  case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1205  case Stmt::CapturedStmtClass: {
1206  const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
1207  Engine.addAbortedBlock(node, currBldrCtx->getBlock());
1208  break;
1209  }
1210 
1211  case Stmt::ParenExprClass:
1212  llvm_unreachable("ParenExprs already handled.");
1213  case Stmt::GenericSelectionExprClass:
1214  llvm_unreachable("GenericSelectionExprs already handled.");
1215  // Cases that should never be evaluated simply because they shouldn't
1216  // appear in the CFG.
1217  case Stmt::BreakStmtClass:
1218  case Stmt::CaseStmtClass:
1219  case Stmt::CompoundStmtClass:
1220  case Stmt::ContinueStmtClass:
1221  case Stmt::CXXForRangeStmtClass:
1222  case Stmt::DefaultStmtClass:
1223  case Stmt::DoStmtClass:
1224  case Stmt::ForStmtClass:
1225  case Stmt::GotoStmtClass:
1226  case Stmt::IfStmtClass:
1227  case Stmt::IndirectGotoStmtClass:
1228  case Stmt::LabelStmtClass:
1229  case Stmt::NoStmtClass:
1230  case Stmt::NullStmtClass:
1231  case Stmt::SwitchStmtClass:
1232  case Stmt::WhileStmtClass:
1233  case Expr::MSDependentExistsStmtClass:
1234  llvm_unreachable("Stmt should not be in analyzer evaluation loop");
1235 
1236  case Stmt::ObjCSubscriptRefExprClass:
1237  case Stmt::ObjCPropertyRefExprClass:
1238  llvm_unreachable("These are handled by PseudoObjectExpr");
1239 
1240  case Stmt::GNUNullExprClass: {
1241  // GNU __null is a pointer-width integer, not an actual pointer.
1242  ProgramStateRef state = Pred->getState();
1243  state = state->BindExpr(S, Pred->getLocationContext(),
1244  svalBuilder.makeIntValWithPtrWidth(0, false));
1245  Bldr.generateNode(S, Pred, state);
1246  break;
1247  }
1248 
1249  case Stmt::ObjCAtSynchronizedStmtClass:
1250  Bldr.takeNodes(Pred);
1251  VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst);
1252  Bldr.addNodes(Dst);
1253  break;
1254 
1255  case Stmt::ExprWithCleanupsClass:
1256  // Handled due to fully linearised CFG.
1257  break;
1258 
1259  case Stmt::CXXBindTemporaryExprClass: {
1260  Bldr.takeNodes(Pred);
1261  ExplodedNodeSet PreVisit;
1262  getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
1263  ExplodedNodeSet Next;
1264  VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), PreVisit, Next);
1265  getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this);
1266  Bldr.addNodes(Dst);
1267  break;
1268  }
1269 
1270  // Cases not handled yet; but will handle some day.
1271  case Stmt::DesignatedInitExprClass:
1272  case Stmt::DesignatedInitUpdateExprClass:
1273  case Stmt::ArrayInitLoopExprClass:
1274  case Stmt::ArrayInitIndexExprClass:
1275  case Stmt::ExtVectorElementExprClass:
1276  case Stmt::ImaginaryLiteralClass:
1277  case Stmt::ObjCAtCatchStmtClass:
1278  case Stmt::ObjCAtFinallyStmtClass:
1279  case Stmt::ObjCAtTryStmtClass:
1280  case Stmt::ObjCAutoreleasePoolStmtClass:
1281  case Stmt::ObjCEncodeExprClass:
1282  case Stmt::ObjCIsaExprClass:
1283  case Stmt::ObjCProtocolExprClass:
1284  case Stmt::ObjCSelectorExprClass:
1285  case Stmt::ParenListExprClass:
1286  case Stmt::ShuffleVectorExprClass:
1287  case Stmt::ConvertVectorExprClass:
1288  case Stmt::VAArgExprClass:
1289  case Stmt::CUDAKernelCallExprClass:
1290  case Stmt::OpaqueValueExprClass:
1291  case Stmt::AsTypeExprClass:
1292  // Fall through.
1293 
1294  // Cases we intentionally don't evaluate, since they don't need
1295  // to be explicitly evaluated.
1296  case Stmt::PredefinedExprClass:
1297  case Stmt::AddrLabelExprClass:
1298  case Stmt::AttributedStmtClass:
1299  case Stmt::IntegerLiteralClass:
1300  case Stmt::FixedPointLiteralClass:
1301  case Stmt::CharacterLiteralClass:
1302  case Stmt::ImplicitValueInitExprClass:
1303  case Stmt::CXXScalarValueInitExprClass:
1304  case Stmt::CXXBoolLiteralExprClass:
1305  case Stmt::ObjCBoolLiteralExprClass:
1306  case Stmt::ObjCAvailabilityCheckExprClass:
1307  case Stmt::FloatingLiteralClass:
1308  case Stmt::NoInitExprClass:
1309  case Stmt::SizeOfPackExprClass:
1310  case Stmt::StringLiteralClass:
1311  case Stmt::ObjCStringLiteralClass:
1312  case Stmt::CXXPseudoDestructorExprClass:
1313  case Stmt::SubstNonTypeTemplateParmExprClass:
1314  case Stmt::CXXNullPtrLiteralExprClass:
1315  case Stmt::OMPArraySectionExprClass:
1316  case Stmt::TypeTraitExprClass: {
1317  Bldr.takeNodes(Pred);
1318  ExplodedNodeSet preVisit;
1319  getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
1320  getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this);
1321  Bldr.addNodes(Dst);
1322  break;
1323  }
1324 
1325  case Stmt::CXXDefaultArgExprClass:
1326  case Stmt::CXXDefaultInitExprClass: {
1327  Bldr.takeNodes(Pred);
1328  ExplodedNodeSet PreVisit;
1329  getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
1330 
1331  ExplodedNodeSet Tmp;
1332  StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
1333 
1334  const Expr *ArgE;
1335  if (const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
1336  ArgE = DefE->getExpr();
1337  else if (const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
1338  ArgE = DefE->getExpr();
1339  else
1340  llvm_unreachable("unknown constant wrapper kind");
1341 
1342  bool IsTemporary = false;
1343  if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
1344  ArgE = MTE->GetTemporaryExpr();
1345  IsTemporary = true;
1346  }
1347 
1348  Optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
1349  if (!ConstantVal)
1350  ConstantVal = UnknownVal();
1351 
1352  const LocationContext *LCtx = Pred->getLocationContext();
1353  for (const auto I : PreVisit) {
1354  ProgramStateRef State = I->getState();
1355  State = State->BindExpr(S, LCtx, *ConstantVal);
1356  if (IsTemporary)
1357  State = createTemporaryRegionIfNeeded(State, LCtx,
1358  cast<Expr>(S),
1359  cast<Expr>(S));
1360  Bldr2.generateNode(S, I, State);
1361  }
1362 
1363  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
1364  Bldr.addNodes(Dst);
1365  break;
1366  }
1367 
1368  // Cases we evaluate as opaque expressions, conjuring a symbol.
1369  case Stmt::CXXStdInitializerListExprClass:
1370  case Expr::ObjCArrayLiteralClass:
1371  case Expr::ObjCDictionaryLiteralClass:
1372  case Expr::ObjCBoxedExprClass: {
1373  Bldr.takeNodes(Pred);
1374 
1375  ExplodedNodeSet preVisit;
1376  getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
1377 
1378  ExplodedNodeSet Tmp;
1379  StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
1380 
1381  const auto *Ex = cast<Expr>(S);
1382  QualType resultType = Ex->getType();
1383 
1384  for (const auto N : preVisit) {
1385  const LocationContext *LCtx = N->getLocationContext();
1386  SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
1387  resultType,
1388  currBldrCtx->blockCount());
1389  ProgramStateRef State = N->getState()->BindExpr(Ex, LCtx, result);
1390 
1391  // Escape pointers passed into the list, unless it's an ObjC boxed
1392  // expression which is not a boxable C structure.
1393  if (!(isa<ObjCBoxedExpr>(Ex) &&
1394  !cast<ObjCBoxedExpr>(Ex)->getSubExpr()
1395  ->getType()->isRecordType()))
1396  for (auto Child : Ex->children()) {
1397  assert(Child);
1398  SVal Val = State->getSVal(Child, LCtx);
1399  State = escapeValue(State, Val, PSK_EscapeOther);
1400  }
1401 
1402  Bldr2.generateNode(S, N, State);
1403  }
1404 
1405  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
1406  Bldr.addNodes(Dst);
1407  break;
1408  }
1409 
1410  case Stmt::ArraySubscriptExprClass:
1411  Bldr.takeNodes(Pred);
1412  VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
1413  Bldr.addNodes(Dst);
1414  break;
1415 
1416  case Stmt::GCCAsmStmtClass:
1417  Bldr.takeNodes(Pred);
1418  VisitGCCAsmStmt(cast<GCCAsmStmt>(S), Pred, Dst);
1419  Bldr.addNodes(Dst);
1420  break;
1421 
1422  case Stmt::MSAsmStmtClass:
1423  Bldr.takeNodes(Pred);
1424  VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst);
1425  Bldr.addNodes(Dst);
1426  break;
1427 
1428  case Stmt::BlockExprClass:
1429  Bldr.takeNodes(Pred);
1430  VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
1431  Bldr.addNodes(Dst);
1432  break;
1433 
1434  case Stmt::LambdaExprClass:
1435  if (AMgr.options.shouldInlineLambdas()) {
1436  Bldr.takeNodes(Pred);
1437  VisitLambdaExpr(cast<LambdaExpr>(S), Pred, Dst);
1438  Bldr.addNodes(Dst);
1439  } else {
1440  const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
1441  Engine.addAbortedBlock(node, currBldrCtx->getBlock());
1442  }
1443  break;
1444 
1445  case Stmt::BinaryOperatorClass: {
1446  const auto *B = cast<BinaryOperator>(S);
1447  if (B->isLogicalOp()) {
1448  Bldr.takeNodes(Pred);
1449  VisitLogicalExpr(B, Pred, Dst);
1450  Bldr.addNodes(Dst);
1451  break;
1452  }
1453  else if (B->getOpcode() == BO_Comma) {
1454  ProgramStateRef state = Pred->getState();
1455  Bldr.generateNode(B, Pred,
1456  state->BindExpr(B, Pred->getLocationContext(),
1457  state->getSVal(B->getRHS(),
1458  Pred->getLocationContext())));
1459  break;
1460  }
1461 
1462  Bldr.takeNodes(Pred);
1463 
1464  if (AMgr.options.eagerlyAssumeBinOpBifurcation &&
1465  (B->isRelationalOp() || B->isEqualityOp())) {
1466  ExplodedNodeSet Tmp;
1467  VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
1468  evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S));
1469  }
1470  else
1471  VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
1472 
1473  Bldr.addNodes(Dst);
1474  break;
1475  }
1476 
1477  case Stmt::CXXOperatorCallExprClass: {
1478  const auto *OCE = cast<CXXOperatorCallExpr>(S);
1479 
1480  // For instance method operators, make sure the 'this' argument has a
1481  // valid region.
1482  const Decl *Callee = OCE->getCalleeDecl();
1483  if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
1484  if (MD->isInstance()) {
1485  ProgramStateRef State = Pred->getState();
1486  const LocationContext *LCtx = Pred->getLocationContext();
1487  ProgramStateRef NewState =
1488  createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
1489  if (NewState != State) {
1490  Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/nullptr,
1492  // Did we cache out?
1493  if (!Pred)
1494  break;
1495  }
1496  }
1497  }
1498  // FALLTHROUGH
1499  LLVM_FALLTHROUGH;
1500  }
1501 
1502  case Stmt::CallExprClass:
1503  case Stmt::CXXMemberCallExprClass:
1504  case Stmt::UserDefinedLiteralClass:
1505  Bldr.takeNodes(Pred);
1506  VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
1507  Bldr.addNodes(Dst);
1508  break;
1509 
1510  case Stmt::CXXCatchStmtClass:
1511  Bldr.takeNodes(Pred);
1512  VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
1513  Bldr.addNodes(Dst);
1514  break;
1515 
1516  case Stmt::CXXTemporaryObjectExprClass:
1517  case Stmt::CXXConstructExprClass:
1518  Bldr.takeNodes(Pred);
1519  VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
1520  Bldr.addNodes(Dst);
1521  break;
1522 
1523  case Stmt::CXXNewExprClass: {
1524  Bldr.takeNodes(Pred);
1525 
1526  ExplodedNodeSet PreVisit;
1527  getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
1528 
1529  ExplodedNodeSet PostVisit;
1530  for (const auto i : PreVisit)
1531  VisitCXXNewExpr(cast<CXXNewExpr>(S), i, PostVisit);
1532 
1533  getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
1534  Bldr.addNodes(Dst);
1535  break;
1536  }
1537 
1538  case Stmt::CXXDeleteExprClass: {
1539  Bldr.takeNodes(Pred);
1540  ExplodedNodeSet PreVisit;
1541  const auto *CDE = cast<CXXDeleteExpr>(S);
1542  getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
1543 
1544  for (const auto i : PreVisit)
1545  VisitCXXDeleteExpr(CDE, i, Dst);
1546 
1547  Bldr.addNodes(Dst);
1548  break;
1549  }
1550  // FIXME: ChooseExpr is really a constant. We need to fix
1551  // the CFG do not model them as explicit control-flow.
1552 
1553  case Stmt::ChooseExprClass: { // __builtin_choose_expr
1554  Bldr.takeNodes(Pred);
1555  const auto *C = cast<ChooseExpr>(S);
1556  VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
1557  Bldr.addNodes(Dst);
1558  break;
1559  }
1560 
1561  case Stmt::CompoundAssignOperatorClass:
1562  Bldr.takeNodes(Pred);
1563  VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
1564  Bldr.addNodes(Dst);
1565  break;
1566 
1567  case Stmt::CompoundLiteralExprClass:
1568  Bldr.takeNodes(Pred);
1569  VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
1570  Bldr.addNodes(Dst);
1571  break;
1572 
1573  case Stmt::BinaryConditionalOperatorClass:
1574  case Stmt::ConditionalOperatorClass: { // '?' operator
1575  Bldr.takeNodes(Pred);
1576  const auto *C = cast<AbstractConditionalOperator>(S);
1577  VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
1578  Bldr.addNodes(Dst);
1579  break;
1580  }
1581 
1582  case Stmt::CXXThisExprClass:
1583  Bldr.takeNodes(Pred);
1584  VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
1585  Bldr.addNodes(Dst);
1586  break;
1587 
1588  case Stmt::DeclRefExprClass: {
1589  Bldr.takeNodes(Pred);
1590  const auto *DE = cast<DeclRefExpr>(S);
1591  VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
1592  Bldr.addNodes(Dst);
1593  break;
1594  }
1595 
1596  case Stmt::DeclStmtClass:
1597  Bldr.takeNodes(Pred);
1598  VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
1599  Bldr.addNodes(Dst);
1600  break;
1601 
1602  case Stmt::ImplicitCastExprClass:
1603  case Stmt::CStyleCastExprClass:
1604  case Stmt::CXXStaticCastExprClass:
1605  case Stmt::CXXDynamicCastExprClass:
1606  case Stmt::CXXReinterpretCastExprClass:
1607  case Stmt::CXXConstCastExprClass:
1608  case Stmt::CXXFunctionalCastExprClass:
1609  case Stmt::ObjCBridgedCastExprClass: {
1610  Bldr.takeNodes(Pred);
1611  const auto *C = cast<CastExpr>(S);
1612  ExplodedNodeSet dstExpr;
1613  VisitCast(C, C->getSubExpr(), Pred, dstExpr);
1614 
1615  // Handle the postvisit checks.
1616  getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
1617  Bldr.addNodes(Dst);
1618  break;
1619  }
1620 
1621  case Expr::MaterializeTemporaryExprClass: {
1622  Bldr.takeNodes(Pred);
1623  const auto *MTE = cast<MaterializeTemporaryExpr>(S);
1624  ExplodedNodeSet dstPrevisit;
1625  getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this);
1626  ExplodedNodeSet dstExpr;
1627  for (const auto i : dstPrevisit)
1628  CreateCXXTemporaryObject(MTE, i, dstExpr);
1629  getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this);
1630  Bldr.addNodes(Dst);
1631  break;
1632  }
1633 
1634  case Stmt::InitListExprClass:
1635  Bldr.takeNodes(Pred);
1636  VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
1637  Bldr.addNodes(Dst);
1638  break;
1639 
1640  case Stmt::MemberExprClass:
1641  Bldr.takeNodes(Pred);
1642  VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
1643  Bldr.addNodes(Dst);
1644  break;
1645 
1646  case Stmt::AtomicExprClass:
1647  Bldr.takeNodes(Pred);
1648  VisitAtomicExpr(cast<AtomicExpr>(S), Pred, Dst);
1649  Bldr.addNodes(Dst);
1650  break;
1651 
1652  case Stmt::ObjCIvarRefExprClass:
1653  Bldr.takeNodes(Pred);
1654  VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
1655  Bldr.addNodes(Dst);
1656  break;
1657 
1658  case Stmt::ObjCForCollectionStmtClass:
1659  Bldr.takeNodes(Pred);
1660  VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
1661  Bldr.addNodes(Dst);
1662  break;
1663 
1664  case Stmt::ObjCMessageExprClass:
1665  Bldr.takeNodes(Pred);
1666  VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
1667  Bldr.addNodes(Dst);
1668  break;
1669 
1670  case Stmt::ObjCAtThrowStmtClass:
1671  case Stmt::CXXThrowExprClass:
1672  // FIXME: This is not complete. We basically treat @throw as
1673  // an abort.
1674  Bldr.generateSink(S, Pred, Pred->getState());
1675  break;
1676 
1677  case Stmt::ReturnStmtClass:
1678  Bldr.takeNodes(Pred);
1679  VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
1680  Bldr.addNodes(Dst);
1681  break;
1682 
1683  case Stmt::OffsetOfExprClass: {
1684  Bldr.takeNodes(Pred);
1685  ExplodedNodeSet PreVisit;
1686  getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
1687 
1688  ExplodedNodeSet PostVisit;
1689  for (const auto Node : PreVisit)
1690  VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Node, PostVisit);
1691 
1692  getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
1693  Bldr.addNodes(Dst);
1694  break;
1695  }
1696 
1697  case Stmt::UnaryExprOrTypeTraitExprClass:
1698  Bldr.takeNodes(Pred);
1699  VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
1700  Pred, Dst);
1701  Bldr.addNodes(Dst);
1702  break;
1703 
1704  case Stmt::StmtExprClass: {
1705  const auto *SE = cast<StmtExpr>(S);
1706 
1707  if (SE->getSubStmt()->body_empty()) {
1708  // Empty statement expression.
1709  assert(SE->getType() == getContext().VoidTy
1710  && "Empty statement expression must have void type.");
1711  break;
1712  }
1713 
1714  if (const auto *LastExpr =
1715  dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
1716  ProgramStateRef state = Pred->getState();
1717  Bldr.generateNode(SE, Pred,
1718  state->BindExpr(SE, Pred->getLocationContext(),
1719  state->getSVal(LastExpr,
1720  Pred->getLocationContext())));
1721  }
1722  break;
1723  }
1724 
1725  case Stmt::UnaryOperatorClass: {
1726  Bldr.takeNodes(Pred);
1727  const auto *U = cast<UnaryOperator>(S);
1728  if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->getOpcode() == UO_LNot)) {
1729  ExplodedNodeSet Tmp;
1730  VisitUnaryOperator(U, Pred, Tmp);
1731  evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U);
1732  }
1733  else
1734  VisitUnaryOperator(U, Pred, Dst);
1735  Bldr.addNodes(Dst);
1736  break;
1737  }
1738 
1739  case Stmt::PseudoObjectExprClass: {
1740  Bldr.takeNodes(Pred);
1741  ProgramStateRef state = Pred->getState();
1742  const auto *PE = cast<PseudoObjectExpr>(S);
1743  if (const Expr *Result = PE->getResultExpr()) {
1744  SVal V = state->getSVal(Result, Pred->getLocationContext());
1745  Bldr.generateNode(S, Pred,
1746  state->BindExpr(S, Pred->getLocationContext(), V));
1747  }
1748  else
1749  Bldr.generateNode(S, Pred,
1750  state->BindExpr(S, Pred->getLocationContext(),
1751  UnknownVal()));
1752 
1753  Bldr.addNodes(Dst);
1754  break;
1755  }
1756  }
1757 }
1758 
1759 bool ExprEngine::replayWithoutInlining(ExplodedNode *N,
1760  const LocationContext *CalleeLC) {
1761  const StackFrameContext *CalleeSF = CalleeLC->getCurrentStackFrame();
1762  const StackFrameContext *CallerSF = CalleeSF->getParent()->getCurrentStackFrame();
1763  assert(CalleeSF && CallerSF);
1764  ExplodedNode *BeforeProcessingCall = nullptr;
1765  const Stmt *CE = CalleeSF->getCallSite();
1766 
1767  // Find the first node before we started processing the call expression.
1768  while (N) {
1769  ProgramPoint L = N->getLocation();
1770  BeforeProcessingCall = N;
1771  N = N->pred_empty() ? nullptr : *(N->pred_begin());
1772 
1773  // Skip the nodes corresponding to the inlined code.
1774  if (L.getLocationContext()->getCurrentStackFrame() != CallerSF)
1775  continue;
1776  // We reached the caller. Find the node right before we started
1777  // processing the call.
1778  if (L.isPurgeKind())
1779  continue;
1780  if (L.getAs<PreImplicitCall>())
1781  continue;
1782  if (L.getAs<CallEnter>())
1783  continue;
1784  if (Optional<StmtPoint> SP = L.getAs<StmtPoint>())
1785  if (SP->getStmt() == CE)
1786  continue;
1787  break;
1788  }
1789 
1790  if (!BeforeProcessingCall)
1791  return false;
1792 
1793  // TODO: Clean up the unneeded nodes.
1794 
1795  // Build an Epsilon node from which we will restart the analyzes.
1796  // Note that CE is permitted to be NULL!
1797  ProgramPoint NewNodeLoc =
1798  EpsilonPoint(BeforeProcessingCall->getLocationContext(), CE);
1799  // Add the special flag to GDM to signal retrying with no inlining.
1800  // Note, changing the state ensures that we are not going to cache out.
1801  ProgramStateRef NewNodeState = BeforeProcessingCall->getState();
1802  NewNodeState =
1803  NewNodeState->set<ReplayWithoutInlining>(const_cast<Stmt *>(CE));
1804 
1805  // Make the new node a successor of BeforeProcessingCall.
1806  bool IsNew = false;
1807  ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState, false, &IsNew);
1808  // We cached out at this point. Caching out is common due to us backtracking
1809  // from the inlined function, which might spawn several paths.
1810  if (!IsNew)
1811  return true;
1812 
1813  NewNode->addPredecessor(BeforeProcessingCall, G);
1814 
1815  // Add the new node to the work list.
1816  Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(),
1817  CalleeSF->getIndex());
1818  NumTimesRetriedWithoutInlining++;
1819  return true;
1820 }
1821 
1822 /// Block entrance. (Update counters).
1824  NodeBuilderWithSinks &nodeBuilder,
1825  ExplodedNode *Pred) {
1827  // If we reach a loop which has a known bound (and meets
1828  // other constraints) then consider completely unrolling it.
1829  if(AMgr.options.shouldUnrollLoops()) {
1830  unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
1831  const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminator();
1832  if (Term) {
1833  ProgramStateRef NewState = updateLoopStack(Term, AMgr.getASTContext(),
1834  Pred, maxBlockVisitOnPath);
1835  if (NewState != Pred->getState()) {
1836  ExplodedNode *UpdatedNode = nodeBuilder.generateNode(NewState, Pred);
1837  if (!UpdatedNode)
1838  return;
1839  Pred = UpdatedNode;
1840  }
1841  }
1842  // Is we are inside an unrolled loop then no need the check the counters.
1843  if(isUnrolledState(Pred->getState()))
1844  return;
1845  }
1846 
1847  // If this block is terminated by a loop and it has already been visited the
1848  // maximum number of times, widen the loop.
1849  unsigned int BlockCount = nodeBuilder.getContext().blockCount();
1850  if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
1851  AMgr.options.shouldWidenLoops()) {
1852  const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminator();
1853  if (!(Term &&
1854  (isa<ForStmt>(Term) || isa<WhileStmt>(Term) || isa<DoStmt>(Term))))
1855  return;
1856  // Widen.
1857  const LocationContext *LCtx = Pred->getLocationContext();
1858  ProgramStateRef WidenedState =
1859  getWidenedLoopState(Pred->getState(), LCtx, BlockCount, Term);
1860  nodeBuilder.generateNode(WidenedState, Pred);
1861  return;
1862  }
1863 
1864  // FIXME: Refactor this into a checker.
1865  if (BlockCount >= AMgr.options.maxBlockVisitOnPath) {
1866  static SimpleProgramPointTag tag(TagProviderName, "Block count exceeded");
1867  const ExplodedNode *Sink =
1868  nodeBuilder.generateSink(Pred->getState(), Pred, &tag);
1869 
1870  // Check if we stopped at the top level function or not.
1871  // Root node should have the location context of the top most function.
1872  const LocationContext *CalleeLC = Pred->getLocation().getLocationContext();
1873  const LocationContext *CalleeSF = CalleeLC->getCurrentStackFrame();
1874  const LocationContext *RootLC =
1875  (*G.roots_begin())->getLocation().getLocationContext();
1876  if (RootLC->getCurrentStackFrame() != CalleeSF) {
1877  Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
1878 
1879  // Re-run the call evaluation without inlining it, by storing the
1880  // no-inlining policy in the state and enqueuing the new work item on
1881  // the list. Replay should almost never fail. Use the stats to catch it
1882  // if it does.
1883  if ((!AMgr.options.NoRetryExhausted &&
1884  replayWithoutInlining(Pred, CalleeLC)))
1885  return;
1886  NumMaxBlockCountReachedInInlined++;
1887  } else
1888  NumMaxBlockCountReached++;
1889 
1890  // Make sink nodes as exhausted(for stats) only if retry failed.
1891  Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
1892  }
1893 }
1894 
1895 //===----------------------------------------------------------------------===//
1896 // Branch processing.
1897 //===----------------------------------------------------------------------===//
1898 
1899 /// RecoverCastedSymbol - A helper function for ProcessBranch that is used
1900 /// to try to recover some path-sensitivity for casts of symbolic
1901 /// integers that promote their values (which are currently not tracked well).
1902 /// This function returns the SVal bound to Condition->IgnoreCasts if all the
1903 // cast(s) did was sign-extend the original value.
1906  const Stmt *Condition,
1907  const LocationContext *LCtx,
1908  ASTContext &Ctx) {
1909 
1910  const auto *Ex = dyn_cast<Expr>(Condition);
1911  if (!Ex)
1912  return UnknownVal();
1913 
1914  uint64_t bits = 0;
1915  bool bitsInit = false;
1916 
1917  while (const auto *CE = dyn_cast<CastExpr>(Ex)) {
1918  QualType T = CE->getType();
1919 
1920  if (!T->isIntegralOrEnumerationType())
1921  return UnknownVal();
1922 
1923  uint64_t newBits = Ctx.getTypeSize(T);
1924  if (!bitsInit || newBits < bits) {
1925  bitsInit = true;
1926  bits = newBits;
1927  }
1928 
1929  Ex = CE->getSubExpr();
1930  }
1931 
1932  // We reached a non-cast. Is it a symbolic value?
1933  QualType T = Ex->getType();
1934 
1935  if (!bitsInit || !T->isIntegralOrEnumerationType() ||
1936  Ctx.getTypeSize(T) > bits)
1937  return UnknownVal();
1938 
1939  return state->getSVal(Ex, LCtx);
1940 }
1941 
1942 #ifndef NDEBUG
1943 static const Stmt *getRightmostLeaf(const Stmt *Condition) {
1944  while (Condition) {
1945  const auto *BO = dyn_cast<BinaryOperator>(Condition);
1946  if (!BO || !BO->isLogicalOp()) {
1947  return Condition;
1948  }
1949  Condition = BO->getRHS()->IgnoreParens();
1950  }
1951  return nullptr;
1952 }
1953 #endif
1954 
1955 // Returns the condition the branch at the end of 'B' depends on and whose value
1956 // has been evaluated within 'B'.
1957 // In most cases, the terminator condition of 'B' will be evaluated fully in
1958 // the last statement of 'B'; in those cases, the resolved condition is the
1959 // given 'Condition'.
1960 // If the condition of the branch is a logical binary operator tree, the CFG is
1961 // optimized: in that case, we know that the expression formed by all but the
1962 // rightmost leaf of the logical binary operator tree must be true, and thus
1963 // the branch condition is at this point equivalent to the truth value of that
1964 // rightmost leaf; the CFG block thus only evaluates this rightmost leaf
1965 // expression in its final statement. As the full condition in that case was
1966 // not evaluated, and is thus not in the SVal cache, we need to use that leaf
1967 // expression to evaluate the truth value of the condition in the current state
1968 // space.
1969 static const Stmt *ResolveCondition(const Stmt *Condition,
1970  const CFGBlock *B) {
1971  if (const auto *Ex = dyn_cast<Expr>(Condition))
1972  Condition = Ex->IgnoreParens();
1973 
1974  const auto *BO = dyn_cast<BinaryOperator>(Condition);
1975  if (!BO || !BO->isLogicalOp())
1976  return Condition;
1977 
1978  assert(!B->getTerminator().isTemporaryDtorsBranch() &&
1979  "Temporary destructor branches handled by processBindTemporary.");
1980 
1981  // For logical operations, we still have the case where some branches
1982  // use the traditional "merge" approach and others sink the branch
1983  // directly into the basic blocks representing the logical operation.
1984  // We need to distinguish between those two cases here.
1985 
1986  // The invariants are still shifting, but it is possible that the
1987  // last element in a CFGBlock is not a CFGStmt. Look for the last
1988  // CFGStmt as the value of the condition.
1989  CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend();
1990  for (; I != E; ++I) {
1991  CFGElement Elem = *I;
1992  Optional<CFGStmt> CS = Elem.getAs<CFGStmt>();
1993  if (!CS)
1994  continue;
1995  const Stmt *LastStmt = CS->getStmt();
1996  assert(LastStmt == Condition || LastStmt == getRightmostLeaf(Condition));
1997  return LastStmt;
1998  }
1999  llvm_unreachable("could not resolve condition");
2000 }
2001 
2002 void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
2003  NodeBuilderContext& BldCtx,
2004  ExplodedNode *Pred,
2005  ExplodedNodeSet &Dst,
2006  const CFGBlock *DstT,
2007  const CFGBlock *DstF) {
2008  assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) &&
2009  "CXXBindTemporaryExprs are handled by processBindTemporary.");
2010  const LocationContext *LCtx = Pred->getLocationContext();
2011  PrettyStackTraceLocationContext StackCrashInfo(LCtx);
2012  currBldrCtx = &BldCtx;
2013 
2014  // Check for NULL conditions; e.g. "for(;;)"
2015  if (!Condition) {
2016  BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
2017  NullCondBldr.markInfeasible(false);
2018  NullCondBldr.generateNode(Pred->getState(), true, Pred);
2019  return;
2020  }
2021 
2022  if (const auto *Ex = dyn_cast<Expr>(Condition))
2023  Condition = Ex->IgnoreParens();
2024 
2025  Condition = ResolveCondition(Condition, BldCtx.getBlock());
2026  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
2027  Condition->getLocStart(),
2028  "Error evaluating branch");
2029 
2030  ExplodedNodeSet CheckersOutSet;
2031  getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet,
2032  Pred, *this);
2033  // We generated only sinks.
2034  if (CheckersOutSet.empty())
2035  return;
2036 
2037  BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
2038  for (const auto PredI : CheckersOutSet) {
2039  if (PredI->isSink())
2040  continue;
2041 
2042  ProgramStateRef PrevState = PredI->getState();
2043  SVal X = PrevState->getSVal(Condition, PredI->getLocationContext());
2044 
2045  if (X.isUnknownOrUndef()) {
2046  // Give it a chance to recover from unknown.
2047  if (const auto *Ex = dyn_cast<Expr>(Condition)) {
2048  if (Ex->getType()->isIntegralOrEnumerationType()) {
2049  // Try to recover some path-sensitivity. Right now casts of symbolic
2050  // integers that promote their values are currently not tracked well.
2051  // If 'Condition' is such an expression, try and recover the
2052  // underlying value and use that instead.
2054  PrevState, Condition,
2055  PredI->getLocationContext(),
2056  getContext());
2057 
2058  if (!recovered.isUnknown()) {
2059  X = recovered;
2060  }
2061  }
2062  }
2063  }
2064 
2065  // If the condition is still unknown, give up.
2066  if (X.isUnknownOrUndef()) {
2067  builder.generateNode(PrevState, true, PredI);
2068  builder.generateNode(PrevState, false, PredI);
2069  continue;
2070  }
2071 
2072  DefinedSVal V = X.castAs<DefinedSVal>();
2073 
2074  ProgramStateRef StTrue, StFalse;
2075  std::tie(StTrue, StFalse) = PrevState->assume(V);
2076 
2077  // Process the true branch.
2078  if (builder.isFeasible(true)) {
2079  if (StTrue)
2080  builder.generateNode(StTrue, true, PredI);
2081  else
2082  builder.markInfeasible(true);
2083  }
2084 
2085  // Process the false branch.
2086  if (builder.isFeasible(false)) {
2087  if (StFalse)
2088  builder.generateNode(StFalse, false, PredI);
2089  else
2090  builder.markInfeasible(false);
2091  }
2092  }
2093  currBldrCtx = nullptr;
2094 }
2095 
2096 /// The GDM component containing the set of global variables which have been
2097 /// previously initialized with explicit initializers.
2098 REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedGlobalsSet,
2099  llvm::ImmutableSet<const VarDecl *>)
2100 
2102  NodeBuilderContext &BuilderCtx,
2103  ExplodedNode *Pred,
2104  ExplodedNodeSet &Dst,
2105  const CFGBlock *DstT,
2106  const CFGBlock *DstF) {
2108  currBldrCtx = &BuilderCtx;
2109 
2110  const auto *VD = cast<VarDecl>(DS->getSingleDecl());
2111  ProgramStateRef state = Pred->getState();
2112  bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
2113  BranchNodeBuilder builder(Pred, Dst, BuilderCtx, DstT, DstF);
2114 
2115  if (!initHasRun) {
2116  state = state->add<InitializedGlobalsSet>(VD);
2117  }
2118 
2119  builder.generateNode(state, initHasRun, Pred);
2120  builder.markInfeasible(!initHasRun);
2121 
2122  currBldrCtx = nullptr;
2123 }
2124 
2125 /// processIndirectGoto - Called by CoreEngine. Used to generate successor
2126 /// nodes by processing the 'effects' of a computed goto jump.
2128  ProgramStateRef state = builder.getState();
2129  SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext());
2130 
2131  // Three possibilities:
2132  //
2133  // (1) We know the computed label.
2134  // (2) The label is NULL (or some other constant), or Undefined.
2135  // (3) We have no clue about the label. Dispatch to all targets.
2136  //
2137 
2138  using iterator = IndirectGotoNodeBuilder::iterator;
2139 
2141  const LabelDecl *L = LV->getLabel();
2142 
2143  for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) {
2144  if (I.getLabel() == L) {
2145  builder.generateNode(I, state);
2146  return;
2147  }
2148  }
2149 
2150  llvm_unreachable("No block with label.");
2151  }
2152 
2153  if (V.getAs<loc::ConcreteInt>() || V.getAs<UndefinedVal>()) {
2154  // Dispatch to the first target and mark it as a sink.
2155  //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
2156  // FIXME: add checker visit.
2157  // UndefBranches.insert(N);
2158  return;
2159  }
2160 
2161  // This is really a catch-all. We don't support symbolics yet.
2162  // FIXME: Implement dispatch for symbolic pointers.
2163 
2164  for (iterator I = builder.begin(), E = builder.end(); I != E; ++I)
2165  builder.generateNode(I, state);
2166 }
2167 
2169  ExplodedNode *Pred,
2170  ExplodedNodeSet &Dst,
2171  const BlockEdge &L) {
2172  SaveAndRestore<const NodeBuilderContext *> NodeContextRAII(currBldrCtx, &BC);
2173  getCheckerManager().runCheckersForBeginFunction(Dst, L, Pred, *this);
2174 }
2175 
2176 /// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path
2177 /// nodes when the control reaches the end of a function.
2179  ExplodedNode *Pred,
2180  const ReturnStmt *RS) {
2181  // FIXME: We currently cannot assert that temporaries are clear, because
2182  // lifetime extended temporaries are not always modelled correctly. In some
2183  // cases when we materialize the temporary, we do
2184  // createTemporaryRegionIfNeeded(), and the region changes, and also the
2185  // respective destructor becomes automatic from temporary. So for now clean up
2186  // the state manually before asserting. Ideally, the code above the assertion
2187  // should go away, but the assertion should remain.
2188  {
2189  ExplodedNodeSet CleanUpObjects;
2190  NodeBuilder Bldr(Pred, CleanUpObjects, BC);
2191  ProgramStateRef State = Pred->getState();
2192  const LocationContext *FromLC = Pred->getLocationContext();
2193  const LocationContext *ToLC = FromLC->getCurrentStackFrame()->getParent();
2194  const LocationContext *LC = FromLC;
2195  while (LC != ToLC) {
2196  assert(LC && "ToLC must be a parent of FromLC!");
2197  for (auto I : State->get<ObjectsUnderConstruction>())
2198  if (I.first.getLocationContext() == LC) {
2199  // The comment above only pardons us for not cleaning up a
2200  // CXXBindTemporaryExpr. If any other statements are found here,
2201  // it must be a separate problem.
2202  assert(isa<CXXBindTemporaryExpr>(I.first.getStmt()));
2203  State = State->remove<ObjectsUnderConstruction>(I.first);
2204  }
2205 
2206  LC = LC->getParent();
2207  }
2208  if (State != Pred->getState()) {
2209  Pred = Bldr.generateNode(Pred->getLocation(), State, Pred);
2210  if (!Pred) {
2211  // The node with clean temporaries already exists. We might have reached
2212  // it on a path on which we initialize different temporaries.
2213  return;
2214  }
2215  }
2216  }
2217  assert(areAllObjectsFullyConstructed(Pred->getState(),
2218  Pred->getLocationContext(),
2219  Pred->getStackFrame()->getParent()));
2220 
2222  StateMgr.EndPath(Pred->getState());
2223 
2224  ExplodedNodeSet Dst;
2225  if (Pred->getLocationContext()->inTopFrame()) {
2226  // Remove dead symbols.
2227  ExplodedNodeSet AfterRemovedDead;
2228  removeDeadOnEndOfFunction(BC, Pred, AfterRemovedDead);
2229 
2230  // Notify checkers.
2231  for (const auto I : AfterRemovedDead)
2232  getCheckerManager().runCheckersForEndFunction(BC, Dst, I, *this);
2233  } else {
2234  getCheckerManager().runCheckersForEndFunction(BC, Dst, Pred, *this);
2235  }
2236 
2237  Engine.enqueueEndOfFunction(Dst, RS);
2238 }
2239 
2240 /// ProcessSwitch - Called by CoreEngine. Used to generate successor
2241 /// nodes by processing the 'effects' of a switch statement.
2243  using iterator = SwitchNodeBuilder::iterator;
2244 
2245  ProgramStateRef state = builder.getState();
2246  const Expr *CondE = builder.getCondition();
2247  SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext());
2248 
2249  if (CondV_untested.isUndef()) {
2250  //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
2251  // FIXME: add checker
2252  //UndefBranches.insert(N);
2253 
2254  return;
2255  }
2256  DefinedOrUnknownSVal CondV = CondV_untested.castAs<DefinedOrUnknownSVal>();
2257 
2258  ProgramStateRef DefaultSt = state;
2259 
2260  iterator I = builder.begin(), EI = builder.end();
2261  bool defaultIsFeasible = I == EI;
2262 
2263  for ( ; I != EI; ++I) {
2264  // Successor may be pruned out during CFG construction.
2265  if (!I.getBlock())
2266  continue;
2267 
2268  const CaseStmt *Case = I.getCase();
2269 
2270  // Evaluate the LHS of the case value.
2271  llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext());
2272  assert(V1.getBitWidth() == getContext().getIntWidth(CondE->getType()));
2273 
2274  // Get the RHS of the case, if it exists.
2275  llvm::APSInt V2;
2276  if (const Expr *E = Case->getRHS())
2277  V2 = E->EvaluateKnownConstInt(getContext());
2278  else
2279  V2 = V1;
2280 
2281  ProgramStateRef StateCase;
2282  if (Optional<NonLoc> NL = CondV.getAs<NonLoc>())
2283  std::tie(StateCase, DefaultSt) =
2284  DefaultSt->assumeInclusiveRange(*NL, V1, V2);
2285  else // UnknownVal
2286  StateCase = DefaultSt;
2287 
2288  if (StateCase)
2289  builder.generateCaseStmtNode(I, StateCase);
2290 
2291  // Now "assume" that the case doesn't match. Add this state
2292  // to the default state (if it is feasible).
2293  if (DefaultSt)
2294  defaultIsFeasible = true;
2295  else {
2296  defaultIsFeasible = false;
2297  break;
2298  }
2299  }
2300 
2301  if (!defaultIsFeasible)
2302  return;
2303 
2304  // If we have switch(enum value), the default branch is not
2305  // feasible if all of the enum constants not covered by 'case:' statements
2306  // are not feasible values for the switch condition.
2307  //
2308  // Note that this isn't as accurate as it could be. Even if there isn't
2309  // a case for a particular enum value as long as that enum value isn't
2310  // feasible then it shouldn't be considered for making 'default:' reachable.
2311  const SwitchStmt *SS = builder.getSwitch();
2312  const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts();
2313  if (CondExpr->getType()->getAs<EnumType>()) {
2314  if (SS->isAllEnumCasesCovered())
2315  return;
2316  }
2317 
2318  builder.generateDefaultCaseNode(DefaultSt);
2319 }
2320 
2321 //===----------------------------------------------------------------------===//
2322 // Transfer functions: Loads and stores.
2323 //===----------------------------------------------------------------------===//
2324 
2326  ExplodedNode *Pred,
2327  ExplodedNodeSet &Dst) {
2328  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
2329 
2330  ProgramStateRef state = Pred->getState();
2331  const LocationContext *LCtx = Pred->getLocationContext();
2332 
2333  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2334  // C permits "extern void v", and if you cast the address to a valid type,
2335  // you can even do things with it. We simply pretend
2336  assert(Ex->isGLValue() || VD->getType()->isVoidType());
2337  const LocationContext *LocCtxt = Pred->getLocationContext();
2338  const Decl *D = LocCtxt->getDecl();
2339  const auto *MD = dyn_cast_or_null<CXXMethodDecl>(D);
2340  const auto *DeclRefEx = dyn_cast<DeclRefExpr>(Ex);
2342 
2343  if (AMgr.options.shouldInlineLambdas() && DeclRefEx &&
2344  DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
2345  MD->getParent()->isLambda()) {
2346  // Lookup the field of the lambda.
2347  const CXXRecordDecl *CXXRec = MD->getParent();
2348  llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
2349  FieldDecl *LambdaThisCaptureField;
2350  CXXRec->getCaptureFields(LambdaCaptureFields, LambdaThisCaptureField);
2351 
2352  // Sema follows a sequence of complex rules to determine whether the
2353  // variable should be captured.
2354  if (const FieldDecl *FD = LambdaCaptureFields[VD]) {
2355  Loc CXXThis =
2356  svalBuilder.getCXXThis(MD, LocCtxt->getCurrentStackFrame());
2357  SVal CXXThisVal = state->getSVal(CXXThis);
2358  VInfo = std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
2359  }
2360  }
2361 
2362  if (!VInfo)
2363  VInfo = std::make_pair(state->getLValue(VD, LocCtxt), VD->getType());
2364 
2365  SVal V = VInfo->first;
2366  bool IsReference = VInfo->second->isReferenceType();
2367 
2368  // For references, the 'lvalue' is the pointer address stored in the
2369  // reference region.
2370  if (IsReference) {
2371  if (const MemRegion *R = V.getAsRegion())
2372  V = state->getSVal(R);
2373  else
2374  V = UnknownVal();
2375  }
2376 
2377  Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr,
2379  return;
2380  }
2381  if (const auto *ED = dyn_cast<EnumConstantDecl>(D)) {
2382  assert(!Ex->isGLValue());
2383  SVal V = svalBuilder.makeIntVal(ED->getInitVal());
2384  Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
2385  return;
2386  }
2387  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
2388  SVal V = svalBuilder.getFunctionPointer(FD);
2389  Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr,
2391  return;
2392  }
2393  if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
2394  // FIXME: Compute lvalue of field pointers-to-member.
2395  // Right now we just use a non-null void pointer, so that it gives proper
2396  // results in boolean contexts.
2397  // FIXME: Maybe delegate this to the surrounding operator&.
2398  // Note how this expression is lvalue, however pointer-to-member is NonLoc.
2399  SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy,
2400  currBldrCtx->blockCount());
2401  state = state->assume(V.castAs<DefinedOrUnknownSVal>(), true);
2402  Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr,
2404  return;
2405  }
2406  if (isa<BindingDecl>(D)) {
2407  // FIXME: proper support for bound declarations.
2408  // For now, let's just prevent crashing.
2409  return;
2410  }
2411 
2412  llvm_unreachable("Support for this Decl not implemented.");
2413 }
2414 
2415 /// VisitArraySubscriptExpr - Transfer function for array accesses
2417  ExplodedNode *Pred,
2418  ExplodedNodeSet &Dst){
2419  const Expr *Base = A->getBase()->IgnoreParens();
2420  const Expr *Idx = A->getIdx()->IgnoreParens();
2421 
2422  ExplodedNodeSet CheckerPreStmt;
2423  getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this);
2424 
2425  ExplodedNodeSet EvalSet;
2426  StmtNodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
2427 
2428  bool IsVectorType = A->getBase()->getType()->isVectorType();
2429 
2430  // The "like" case is for situations where C standard prohibits the type to
2431  // be an lvalue, e.g. taking the address of a subscript of an expression of
2432  // type "void *".
2433  bool IsGLValueLike = A->isGLValue() ||
2434  (A->getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
2435 
2436  for (auto *Node : CheckerPreStmt) {
2437  const LocationContext *LCtx = Node->getLocationContext();
2438  ProgramStateRef state = Node->getState();
2439 
2440  if (IsGLValueLike) {
2441  QualType T = A->getType();
2442 
2443  // One of the forbidden LValue types! We still need to have sensible
2444  // symbolic locations to represent this stuff. Note that arithmetic on
2445  // void pointers is a GCC extension.
2446  if (T->isVoidType())
2447  T = getContext().CharTy;
2448 
2449  SVal V = state->getLValue(T,
2450  state->getSVal(Idx, LCtx),
2451  state->getSVal(Base, LCtx));
2452  Bldr.generateNode(A, Node, state->BindExpr(A, LCtx, V), nullptr,
2454  } else if (IsVectorType) {
2455  // FIXME: non-glvalue vector reads are not modelled.
2456  Bldr.generateNode(A, Node, state, nullptr);
2457  } else {
2458  llvm_unreachable("Array subscript should be an lValue when not \
2459 a vector and not a forbidden lvalue type");
2460  }
2461  }
2462 
2463  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, A, *this);
2464 }
2465 
2466 /// VisitMemberExpr - Transfer function for member expressions.
2468  ExplodedNodeSet &Dst) {
2469  // FIXME: Prechecks eventually go in ::Visit().
2470  ExplodedNodeSet CheckedSet;
2471  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, M, *this);
2472 
2473  ExplodedNodeSet EvalSet;
2474  ValueDecl *Member = M->getMemberDecl();
2475 
2476  // Handle static member variables and enum constants accessed via
2477  // member syntax.
2478  if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
2479  for (const auto I : CheckedSet)
2480  VisitCommonDeclRefExpr(M, Member, I, EvalSet);
2481  } else {
2482  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
2483  ExplodedNodeSet Tmp;
2484 
2485  for (const auto I : CheckedSet) {
2486  ProgramStateRef state = I->getState();
2487  const LocationContext *LCtx = I->getLocationContext();
2488  Expr *BaseExpr = M->getBase();
2489 
2490  // Handle C++ method calls.
2491  if (const auto *MD = dyn_cast<CXXMethodDecl>(Member)) {
2492  if (MD->isInstance())
2493  state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2494 
2495  SVal MDVal = svalBuilder.getFunctionPointer(MD);
2496  state = state->BindExpr(M, LCtx, MDVal);
2497 
2498  Bldr.generateNode(M, I, state);
2499  continue;
2500  }
2501 
2502  // Handle regular struct fields / member variables.
2503  state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2504  SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
2505 
2506  const auto *field = cast<FieldDecl>(Member);
2507  SVal L = state->getLValue(field, baseExprVal);
2508 
2509  if (M->isGLValue() || M->getType()->isArrayType()) {
2510  // We special-case rvalues of array type because the analyzer cannot
2511  // reason about them, since we expect all regions to be wrapped in Locs.
2512  // We instead treat these as lvalues and assume that they will decay to
2513  // pointers as soon as they are used.
2514  if (!M->isGLValue()) {
2515  assert(M->getType()->isArrayType());
2516  const auto *PE =
2517  dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
2518  if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
2519  llvm_unreachable("should always be wrapped in ArrayToPointerDecay");
2520  }
2521  }
2522 
2523  if (field->getType()->isReferenceType()) {
2524  if (const MemRegion *R = L.getAsRegion())
2525  L = state->getSVal(R);
2526  else
2527  L = UnknownVal();
2528  }
2529 
2530  Bldr.generateNode(M, I, state->BindExpr(M, LCtx, L), nullptr,
2532  } else {
2533  Bldr.takeNodes(I);
2534  evalLoad(Tmp, M, M, I, state, L);
2535  Bldr.addNodes(Tmp);
2536  }
2537  }
2538  }
2539 
2540  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, M, *this);
2541 }
2542 
2544  ExplodedNodeSet &Dst) {
2545  ExplodedNodeSet AfterPreSet;
2546  getCheckerManager().runCheckersForPreStmt(AfterPreSet, Pred, AE, *this);
2547 
2548  // For now, treat all the arguments to C11 atomics as escaping.
2549  // FIXME: Ideally we should model the behavior of the atomics precisely here.
2550 
2551  ExplodedNodeSet AfterInvalidateSet;
2552  StmtNodeBuilder Bldr(AfterPreSet, AfterInvalidateSet, *currBldrCtx);
2553 
2554  for (const auto I : AfterPreSet) {
2555  ProgramStateRef State = I->getState();
2556  const LocationContext *LCtx = I->getLocationContext();
2557 
2558  SmallVector<SVal, 8> ValuesToInvalidate;
2559  for (unsigned SI = 0, Count = AE->getNumSubExprs(); SI != Count; SI++) {
2560  const Expr *SubExpr = AE->getSubExprs()[SI];
2561  SVal SubExprVal = State->getSVal(SubExpr, LCtx);
2562  ValuesToInvalidate.push_back(SubExprVal);
2563  }
2564 
2565  State = State->invalidateRegions(ValuesToInvalidate, AE,
2566  currBldrCtx->blockCount(),
2567  LCtx,
2568  /*CausedByPointerEscape*/true,
2569  /*Symbols=*/nullptr);
2570 
2571  SVal ResultVal = UnknownVal();
2572  State = State->BindExpr(AE, LCtx, ResultVal);
2573  Bldr.generateNode(AE, I, State, nullptr,
2575  }
2576 
2577  getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE, *this);
2578 }
2579 
2580 // A value escapes in three possible cases:
2581 // (1) We are binding to something that is not a memory region.
2582 // (2) We are binding to a MemrRegion that does not have stack storage.
2583 // (3) We are binding to a MemRegion with stack storage that the store
2584 // does not understand.
2586  SVal Loc,
2587  SVal Val,
2588  const LocationContext *LCtx) {
2589  // Are we storing to something that causes the value to "escape"?
2590  bool escapes = true;
2591 
2592  // TODO: Move to StoreManager.
2593  if (Optional<loc::MemRegionVal> regionLoc = Loc.getAs<loc::MemRegionVal>()) {
2594  escapes = !regionLoc->getRegion()->hasStackStorage();
2595 
2596  if (!escapes) {
2597  // To test (3), generate a new state with the binding added. If it is
2598  // the same state, then it escapes (since the store cannot represent
2599  // the binding).
2600  // Do this only if we know that the store is not supposed to generate the
2601  // same state.
2602  SVal StoredVal = State->getSVal(regionLoc->getRegion());
2603  if (StoredVal != Val)
2604  escapes = (State == (State->bindLoc(*regionLoc, Val, LCtx)));
2605  }
2606  }
2607 
2608  // If our store can represent the binding and we aren't storing to something
2609  // that doesn't have local storage then just return and have the simulation
2610  // state continue as is.
2611  if (!escapes)
2612  return State;
2613 
2614  // Otherwise, find all symbols referenced by 'val' that we are tracking
2615  // and stop tracking them.
2616  State = escapeValue(State, Val, PSK_EscapeOnBind);
2617  return State;
2618 }
2619 
2622  const InvalidatedSymbols *Invalidated,
2623  ArrayRef<const MemRegion *> ExplicitRegions,
2625  const CallEvent *Call,
2627  if (!Invalidated || Invalidated->empty())
2628  return State;
2629 
2630  if (!Call)
2632  *Invalidated,
2633  nullptr,
2635  &ITraits);
2636 
2637  // If the symbols were invalidated by a call, we want to find out which ones
2638  // were invalidated directly due to being arguments to the call.
2639  InvalidatedSymbols SymbolsDirectlyInvalidated;
2640  for (const auto I : ExplicitRegions) {
2641  if (const SymbolicRegion *R = I->StripCasts()->getAs<SymbolicRegion>())
2642  SymbolsDirectlyInvalidated.insert(R->getSymbol());
2643  }
2644 
2645  InvalidatedSymbols SymbolsIndirectlyInvalidated;
2646  for (const auto &sym : *Invalidated) {
2647  if (SymbolsDirectlyInvalidated.count(sym))
2648  continue;
2649  SymbolsIndirectlyInvalidated.insert(sym);
2650  }
2651 
2652  if (!SymbolsDirectlyInvalidated.empty())
2654  SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall, &ITraits);
2655 
2656  // Notify about the symbols that get indirectly invalidated by the call.
2657  if (!SymbolsIndirectlyInvalidated.empty())
2659  SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall, &ITraits);
2660 
2661  return State;
2662 }
2663 
2664 /// evalBind - Handle the semantics of binding a value to a specific location.
2665 /// This method is used by evalStore and (soon) VisitDeclStmt, and others.
2666 void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
2667  ExplodedNode *Pred,
2668  SVal location, SVal Val,
2669  bool atDeclInit, const ProgramPoint *PP) {
2670  const LocationContext *LC = Pred->getLocationContext();
2671  PostStmt PS(StoreE, LC);
2672  if (!PP)
2673  PP = &PS;
2674 
2675  // Do a previsit of the bind.
2676  ExplodedNodeSet CheckedSet;
2677  getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val,
2678  StoreE, *this, *PP);
2679 
2680  StmtNodeBuilder Bldr(CheckedSet, Dst, *currBldrCtx);
2681 
2682  // If the location is not a 'Loc', it will already be handled by
2683  // the checkers. There is nothing left to do.
2684  if (!location.getAs<Loc>()) {
2685  const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr,
2686  /*tag*/nullptr);
2687  ProgramStateRef state = Pred->getState();
2688  state = processPointerEscapedOnBind(state, location, Val, LC);
2689  Bldr.generateNode(L, state, Pred);
2690  return;
2691  }
2692 
2693  for (const auto PredI : CheckedSet) {
2694  ProgramStateRef state = PredI->getState();
2695 
2696  state = processPointerEscapedOnBind(state, location, Val, LC);
2697 
2698  // When binding the value, pass on the hint that this is a initialization.
2699  // For initializations, we do not need to inform clients of region
2700  // changes.
2701  state = state->bindLoc(location.castAs<Loc>(),
2702  Val, LC, /* notifyChanges = */ !atDeclInit);
2703 
2704  const MemRegion *LocReg = nullptr;
2705  if (Optional<loc::MemRegionVal> LocRegVal =
2706  location.getAs<loc::MemRegionVal>()) {
2707  LocReg = LocRegVal->getRegion();
2708  }
2709 
2710  const ProgramPoint L = PostStore(StoreE, LC, LocReg, nullptr);
2711  Bldr.generateNode(L, state, PredI);
2712  }
2713 }
2714 
2715 /// evalStore - Handle the semantics of a store via an assignment.
2716 /// @param Dst The node set to store generated state nodes
2717 /// @param AssignE The assignment expression if the store happens in an
2718 /// assignment.
2719 /// @param LocationE The location expression that is stored to.
2720 /// @param state The current simulation state
2721 /// @param location The location to store the value
2722 /// @param Val The value to be stored
2723 void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
2724  const Expr *LocationE,
2725  ExplodedNode *Pred,
2726  ProgramStateRef state, SVal location, SVal Val,
2727  const ProgramPointTag *tag) {
2728  // Proceed with the store. We use AssignE as the anchor for the PostStore
2729  // ProgramPoint if it is non-NULL, and LocationE otherwise.
2730  const Expr *StoreE = AssignE ? AssignE : LocationE;
2731 
2732  // Evaluate the location (checks for bad dereferences).
2733  ExplodedNodeSet Tmp;
2734  evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag, false);
2735 
2736  if (Tmp.empty())
2737  return;
2738 
2739  if (location.isUndef())
2740  return;
2741 
2742  for (const auto I : Tmp)
2743  evalBind(Dst, StoreE, I, location, Val, false);
2744 }
2745 
2747  const Expr *NodeEx,
2748  const Expr *BoundEx,
2749  ExplodedNode *Pred,
2751  SVal location,
2752  const ProgramPointTag *tag,
2753  QualType LoadTy) {
2754  assert(!location.getAs<NonLoc>() && "location cannot be a NonLoc.");
2755  assert(NodeEx);
2756  assert(BoundEx);
2757  // Evaluate the location (checks for bad dereferences).
2758  ExplodedNodeSet Tmp;
2759  evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag, true);
2760  if (Tmp.empty())
2761  return;
2762 
2763  StmtNodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
2764  if (location.isUndef())
2765  return;
2766 
2767  // Proceed with the load.
2768  for (const auto I : Tmp) {
2769  state = I->getState();
2770  const LocationContext *LCtx = I->getLocationContext();
2771 
2772  SVal V = UnknownVal();
2773  if (location.isValid()) {
2774  if (LoadTy.isNull())
2775  LoadTy = BoundEx->getType();
2776  V = state->getSVal(location.castAs<Loc>(), LoadTy);
2777  }
2778 
2779  Bldr.generateNode(NodeEx, I, state->BindExpr(BoundEx, LCtx, V), tag,
2781  }
2782 }
2783 
2784 void ExprEngine::evalLocation(ExplodedNodeSet &Dst,
2785  const Stmt *NodeEx,
2786  const Stmt *BoundEx,
2787  ExplodedNode *Pred,
2789  SVal location,
2790  const ProgramPointTag *tag,
2791  bool isLoad) {
2792  StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx);
2793  // Early checks for performance reason.
2794  if (location.isUnknown()) {
2795  return;
2796  }
2797 
2798  ExplodedNodeSet Src;
2799  BldrTop.takeNodes(Pred);
2800  StmtNodeBuilder Bldr(Pred, Src, *currBldrCtx);
2801  if (Pred->getState() != state) {
2802  // Associate this new state with an ExplodedNode.
2803  // FIXME: If I pass null tag, the graph is incorrect, e.g for
2804  // int *p;
2805  // p = 0;
2806  // *p = 0xDEADBEEF;
2807  // "p = 0" is not noted as "Null pointer value stored to 'p'" but
2808  // instead "int *p" is noted as
2809  // "Variable 'p' initialized to a null pointer value"
2810 
2811  static SimpleProgramPointTag tag(TagProviderName, "Location");
2812  Bldr.generateNode(NodeEx, Pred, state, &tag);
2813  }
2814  ExplodedNodeSet Tmp;
2815  getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad,
2816  NodeEx, BoundEx, *this);
2817  BldrTop.addNodes(Tmp);
2818 }
2819 
2820 std::pair<const ProgramPointTag *, const ProgramPointTag*>
2822  static SimpleProgramPointTag
2823  eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
2824  "Eagerly Assume True"),
2825  eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
2826  "Eagerly Assume False");
2827  return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
2828  &eagerlyAssumeBinOpBifurcationFalse);
2829 }
2830 
2832  ExplodedNodeSet &Src,
2833  const Expr *Ex) {
2834  StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx);
2835 
2836  for (const auto Pred : Src) {
2837  // Test if the previous node was as the same expression. This can happen
2838  // when the expression fails to evaluate to anything meaningful and
2839  // (as an optimization) we don't generate a node.
2840  ProgramPoint P = Pred->getLocation();
2841  if (!P.getAs<PostStmt>() || P.castAs<PostStmt>().getStmt() != Ex) {
2842  continue;
2843  }
2844 
2845  ProgramStateRef state = Pred->getState();
2846  SVal V = state->getSVal(Ex, Pred->getLocationContext());
2848  if (SEV && SEV->isExpression()) {
2849  const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
2851 
2852  ProgramStateRef StateTrue, StateFalse;
2853  std::tie(StateTrue, StateFalse) = state->assume(*SEV);
2854 
2855  // First assume that the condition is true.
2856  if (StateTrue) {
2857  SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
2858  StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
2859  Bldr.generateNode(Ex, Pred, StateTrue, tags.first);
2860  }
2861 
2862  // Next, assume that the condition is false.
2863  if (StateFalse) {
2864  SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
2865  StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val);
2866  Bldr.generateNode(Ex, Pred, StateFalse, tags.second);
2867  }
2868  }
2869  }
2870 }
2871 
2873  ExplodedNodeSet &Dst) {
2874  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
2875  // We have processed both the inputs and the outputs. All of the outputs
2876  // should evaluate to Locs. Nuke all of their values.
2877 
2878  // FIXME: Some day in the future it would be nice to allow a "plug-in"
2879  // which interprets the inline asm and stores proper results in the
2880  // outputs.
2881 
2882  ProgramStateRef state = Pred->getState();
2883 
2884  for (const Expr *O : A->outputs()) {
2885  SVal X = state->getSVal(O, Pred->getLocationContext());
2886  assert(!X.getAs<NonLoc>()); // Should be an Lval, or unknown, undef.
2887 
2888  if (Optional<Loc> LV = X.getAs<Loc>())
2889  state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
2890  }
2891 
2892  Bldr.generateNode(A, Pred, state);
2893 }
2894 
2896  ExplodedNodeSet &Dst) {
2897  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
2898  Bldr.generateNode(A, Pred, Pred->getState());
2899 }
2900 
2901 //===----------------------------------------------------------------------===//
2902 // Visualization.
2903 //===----------------------------------------------------------------------===//
2904 
2905 #ifndef NDEBUG
2908 
2909 namespace llvm {
2910 
2911 template<>
2912 struct DOTGraphTraits<ExplodedNode*> : public DefaultDOTGraphTraits {
2913  DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
2914 
2915  // FIXME: Since we do not cache error nodes in ExprEngine now, this does not
2916  // work.
2917  static std::string getNodeAttributes(const ExplodedNode *N, void*) {
2918  return {};
2919  }
2920 
2921  // De-duplicate some source location pretty-printing.
2922  static void printLocation(raw_ostream &Out, SourceLocation SLoc) {
2923  if (SLoc.isFileID()) {
2924  Out << "\\lline="
2925  << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
2926  << " col="
2927  << GraphPrintSourceManager->getExpansionColumnNumber(SLoc)
2928  << "\\l";
2929  }
2930  }
2931 
2932  static std::string getNodeLabel(const ExplodedNode *N, void*){
2933  std::string sbuf;
2934  llvm::raw_string_ostream Out(sbuf);
2935 
2936  // Program Location.
2937  ProgramPoint Loc = N->getLocation();
2938 
2939  switch (Loc.getKind()) {
2941  Out << "Block Entrance: B"
2942  << Loc.castAs<BlockEntrance>().getBlock()->getBlockID();
2943  break;
2944 
2946  assert(false);
2947  break;
2948 
2950  Out << "CallEnter";
2951  break;
2952 
2954  Out << "CallExitBegin";
2955  break;
2956 
2958  Out << "CallExitEnd";
2959  break;
2960 
2962  Out << "PostStmtPurgeDeadSymbols";
2963  break;
2964 
2966  Out << "PreStmtPurgeDeadSymbols";
2967  break;
2968 
2970  Out << "Epsilon Point";
2971  break;
2972 
2974  LoopExit LE = Loc.castAs<LoopExit>();
2975  Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();
2976  break;
2977  }
2978 
2981  Out << "PreCall: ";
2982 
2983  // FIXME: Get proper printing options.
2984  PC.getDecl()->print(Out, LangOptions());
2985  printLocation(Out, PC.getLocation());
2986  break;
2987  }
2988 
2991  Out << "PostCall: ";
2992 
2993  // FIXME: Get proper printing options.
2994  PC.getDecl()->print(Out, LangOptions());
2995  printLocation(Out, PC.getLocation());
2996  break;
2997  }
2998 
3000  Out << "PostInitializer: ";
3001  const CXXCtorInitializer *Init =
3002  Loc.castAs<PostInitializer>().getInitializer();
3003  if (const FieldDecl *FD = Init->getAnyMember())
3004  Out << *FD;
3005  else {
3006  QualType Ty = Init->getTypeSourceInfo()->getType();
3007  Ty = Ty.getLocalUnqualifiedType();
3008  LangOptions LO; // FIXME.
3009  Ty.print(Out, LO);
3010  }
3011  break;
3012  }
3013 
3015  const BlockEdge &E = Loc.castAs<BlockEdge>();
3016  Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
3017  << E.getDst()->getBlockID() << ')';
3018 
3019  if (const Stmt *T = E.getSrc()->getTerminator()) {
3020  SourceLocation SLoc = T->getLocStart();
3021 
3022  Out << "\\|Terminator: ";
3023  LangOptions LO; // FIXME.
3024  E.getSrc()->printTerminator(Out, LO);
3025 
3026  if (SLoc.isFileID()) {
3027  Out << "\\lline="
3028  << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
3029  << " col="
3030  << GraphPrintSourceManager->getExpansionColumnNumber(SLoc);
3031  }
3032 
3033  if (isa<SwitchStmt>(T)) {
3034  const Stmt *Label = E.getDst()->getLabel();
3035 
3036  if (Label) {
3037  if (const auto *C = dyn_cast<CaseStmt>(Label)) {
3038  Out << "\\lcase ";
3039  LangOptions LO; // FIXME.
3040  if (C->getLHS())
3041  C->getLHS()->printPretty(Out, nullptr, PrintingPolicy(LO));
3042 
3043  if (const Stmt *RHS = C->getRHS()) {
3044  Out << " .. ";
3045  RHS->printPretty(Out, nullptr, PrintingPolicy(LO));
3046  }
3047 
3048  Out << ":";
3049  }
3050  else {
3051  assert(isa<DefaultStmt>(Label));
3052  Out << "\\ldefault:";
3053  }
3054  }
3055  else
3056  Out << "\\l(implicit) default:";
3057  }
3058  else if (isa<IndirectGotoStmt>(T)) {
3059  // FIXME
3060  }
3061  else {
3062  Out << "\\lCondition: ";
3063  if (*E.getSrc()->succ_begin() == E.getDst())
3064  Out << "true";
3065  else
3066  Out << "false";
3067  }
3068 
3069  Out << "\\l";
3070  }
3071 
3072  break;
3073  }
3074 
3075  default: {
3076  const Stmt *S = Loc.castAs<StmtPoint>().getStmt();
3077  assert(S != nullptr && "Expecting non-null Stmt");
3078 
3079  Out << S->getStmtClassName() << ' ' << (const void*) S << ' ';
3080  LangOptions LO; // FIXME.
3081  S->printPretty(Out, nullptr, PrintingPolicy(LO));
3082  printLocation(Out, S->getLocStart());
3083 
3084  if (Loc.getAs<PreStmt>())
3085  Out << "\\lPreStmt\\l;";
3086  else if (Loc.getAs<PostLoad>())
3087  Out << "\\lPostLoad\\l;";
3088  else if (Loc.getAs<PostStore>())
3089  Out << "\\lPostStore\\l";
3090  else if (Loc.getAs<PostLValue>())
3091  Out << "\\lPostLValue\\l";
3092  else if (Loc.getAs<PostAllocatorCall>())
3093  Out << "\\lPostAllocatorCall\\l";
3094 
3095  break;
3096  }
3097  }
3098 
3099  ProgramStateRef state = N->getState();
3100  Out << "\\|StateID: " << (const void*) state.get()
3101  << " NodeID: " << (const void*) N << "\\|";
3102 
3103  state->printDOT(Out, N->getLocationContext());
3104 
3105  Out << "\\l";
3106 
3107  if (const ProgramPointTag *tag = Loc.getTag()) {
3108  Out << "\\|Tag: " << tag->getTagDescription();
3109  Out << "\\l";
3110  }
3111  return Out.str();
3112  }
3113 };
3114 
3115 } // namespace llvm
3116 #endif
3117 
3118 void ExprEngine::ViewGraph(bool trim) {
3119 #ifndef NDEBUG
3120  if (trim) {
3121  std::vector<const ExplodedNode *> Src;
3122 
3123  // Flush any outstanding reports to make sure we cover all the nodes.
3124  // This does not cause them to get displayed.
3125  for (const auto I : BR)
3126  const_cast<BugType *>(I)->FlushReports(BR);
3127 
3128  // Iterate through the reports and get their nodes.
3130  EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) {
3131  const auto *N = const_cast<ExplodedNode *>(EI->begin()->getErrorNode());
3132  if (N) Src.push_back(N);
3133  }
3134 
3135  ViewGraph(Src);
3136  }
3137  else {
3138  GraphPrintCheckerState = this;
3139  GraphPrintSourceManager = &getContext().getSourceManager();
3140 
3141  llvm::ViewGraph(*G.roots_begin(), "ExprEngine");
3142 
3143  GraphPrintCheckerState = nullptr;
3144  GraphPrintSourceManager = nullptr;
3145  }
3146 #endif
3147 }
3148 
3150 #ifndef NDEBUG
3151  GraphPrintCheckerState = this;
3152  GraphPrintSourceManager = &getContext().getSourceManager();
3153 
3154  std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
3155 
3156  if (!TrimmedG.get())
3157  llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n";
3158  else
3159  llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine");
3160 
3161  GraphPrintCheckerState = nullptr;
3162  GraphPrintSourceManager = nullptr;
3163 #endif
3164 }
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
Definition: DeclCXX.h:2304
Defines the clang::ASTContext interface.
CFGNewAllocator - Represents C++ allocator call.
Definition: CFG.h:235
This represents a GCC inline-assembly statement extension.
Definition: Stmt.h:1636
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:525
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const LocationContext *LCtx)
Definition: SubEngine.h:146
Expr * getInit() const
Get the initializer.
Definition: DeclCXX.h:2433
void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArraySubscriptExpr - Transfer function for array accesses.
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred)
Definition: ExprEngine.cpp:752
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
Definition: Store.cpp:248
A (possibly-)qualified type.
Definition: Type.h:655
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
Static storage duration.
Definition: Specifiers.h:280
bool isArrayType() const
Definition: Type.h:6098
void markLive(SymbolRef sym)
Unconditionally marks a symbol as live.
bool isMemberPointerType() const
Definition: Type.h:6080
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:2561
void markInfeasible(bool branch)
Definition: CoreEngine.h:457
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr *> &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Definition: Expr.cpp:77
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:991
const Stmt * getStmt() const
Definition: CFG.h:132
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
Definition: ExprEngine.h:106
succ_iterator succ_begin()
Definition: CFG.h:750
ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits) override
Call PointerEscape callback when a value escapes as a result of region invalidation.
bool isCForbiddenLValueType() const
Determine whether expressions of the given type are forbidden from being lvalues in C...
Definition: Type.h:6005
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path...
Definition: CoreEngine.h:212
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:30
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
Stmt - This represents one statement.
Definition: Stmt.h:66
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1384
This builder class is useful for generating nodes that resulted from visiting a statement.
Definition: CoreEngine.h:370
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, ExplodedNodeSet &PreVisit, ExplodedNodeSet &Dst)
bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2)
Definition: ProgramState.h:600
C Language Family Type Representation.
Defines the SourceManager interface.
static const Stmt * getRightmostLeaf(const Stmt *Condition)
Expr * getBase() const
Definition: Expr.h:2555
static void printObjectsUnderConstructionForContext(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep, const LocationContext *LC)
Definition: ExprEngine.cpp:517
unsigned getBlockID() const
Definition: CFG.h:855
const CFGBlock * getSrc() const
Definition: ProgramPoint.h:481
void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMSAsmStmt - Transfer function logic for MS inline asm.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Represents a point when we begin processing an inlined call.
Definition: ProgramPoint.h:600
SourceLocation getLocStart() const LLVM_READONLY
Definition: ExprCXX.h:2059
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
FunctionDecl * getOperatorNew() const
Definition: ExprCXX.h:1945
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
Definition: DeclCXX.h:245
void runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on end of function.
StringRef P
const CastExpr * BasePath
Definition: Expr.h:68
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T)
Definition: ExprEngine.h:568
static ExprEngine * GraphPrintCheckerState
The pointer has been passed to a function indirectly.
void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, NodeBuilderContext &BldCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
Called by CoreEngine.
CFGDeleteDtor - Represents C++ object destructor generated from a call to delete. ...
Definition: CFG.h:405
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:2650
Hints for figuring out of a call should be inlined during evalCall().
Definition: ExprEngine.h:96
Represents a program point just before an implicit call event.
Definition: ProgramPoint.h:553
bool IsArrayCtorOrDtor
This call is a constructor or a destructor for a single element within an array, a part of array cons...
Definition: ExprEngine.h:103
const CXXCtorInitializer * getCXXCtorInitializer() const
Definition: ExprEngine.cpp:149
void ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Definition: ExprEngine.cpp:979
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
Definition: Specifiers.h:276
static std::string getNodeLabel(const ExplodedNode *N, void *)
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
Definition: CFG.h:98
const ProgramStateRef & getState() const
ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr, bool gcEnabled, SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn)
Definition: ExprEngine.cpp:193
void processCFGBlockEntrance(const BlockEdge &L, NodeBuilderWithSinks &nodeBuilder, ExplodedNode *Pred) override
Called by CoreEngine when processing the entrance of a CFGBlock.
bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2)
Definition: ProgramState.h:596
Represents a point when we exit a loop.
Definition: ProgramPoint.h:683
ProgramStateRef getInitialState(const LocationContext *InitLoc) override
getInitialState - Return the initial state used for the root vertex in the ExplodedGraph.
Definition: ExprEngine.cpp:223
Represents an implicit call event.
Definition: ProgramPoint.h:529
bool isIndirectMemberInitializer() const
Definition: DeclCXX.h:2316
bool isConsumedExpr(Expr *E) const
Definition: ParentMap.cpp:160
void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryOperator - Transfer function logic for unary operators.
void takeNodes(const ExplodedNodeSet &S)
Definition: CoreEngine.h:321
Represents a variable declaration or definition.
Definition: Decl.h:812
ASTContext & getASTContext() const
REGISTER_TRAIT_WITH_PROGRAMSTATE(ObjectsUnderConstruction, ObjectsUnderConstructionMap) static const char *TagProviderName
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6456
void ProcessDeleteDtor(const CFGDeleteDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Definition: ExprEngine.cpp:920
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the &#39;this&#39; object reference.
bool operator<(const ConstructedObjectKey &RHS) const
Definition: ExprEngine.cpp:176
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
Definition: Expr.h:741
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, const ProgramPointTag *tag=nullptr)
evalStore - Handle the semantics of a store via an assignment.
bool isUnrolledState(ProgramStateRef State)
Returns if the given State indicates that is inside a completely unrolled loop.
const ElementRegion * GetElementZeroRegion(const SubRegion *R, QualType T)
Definition: Store.cpp:68
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
Definition: CoreEngine.cpp:520
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const Stmt * getTriggerStmt() const
Definition: CFG.h:389
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
Defines the Objective-C statement AST node classes.
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const LocationContext *LC, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer&#39;s garbage collection - remove dead symbols and bindings from the state...
Definition: ExprEngine.cpp:616
ProgramStateRef removeDeadBindings(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
Represents a parameter to a function.
Definition: Decl.h:1533
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
Definition: Type.h:887
Defines the clang::Expr interface and subclasses for C++ expressions.
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
BoundNodesTreeBuilder Nodes
static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S, const ExplodedNode *Pred, const LocationContext *LC)
Definition: ExprEngine.cpp:590
void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void ProcessLoopExit(const Stmt *S, ExplodedNode *Pred)
Definition: ExprEngine.cpp:734
void runCheckersForLocation(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, bool isLoad, const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &Eng)
Run checkers for load/store of a location.
Symbolic value.
Definition: SymExpr.h:30
const char * getStmtClassName() const
Definition: Stmt.cpp:75
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
One of these records is kept for each identifier that is lexed.
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
A pointer escapes due to binding its value to a location that the analyzer cannot track...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:150
LineState State
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
Represents a member of a struct/union/class.
Definition: Decl.h:2521
TypeSourceInfo * getTypeSourceInfo() const
Returns the declarator information for a base class or delegating initializer.
Definition: DeclCXX.h:2365
void printTerminator(raw_ostream &OS, const LangOptions &LO) const
printTerminator - A simple pretty printer of the terminator of a CFGBlock.
Definition: CFG.cpp:5344
Represents a program point after a store evaluation.
Definition: ProgramPoint.h:401
CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated for automatic object or t...
Definition: CFG.h:379
const LocationContext * getLocationContext() const
Definition: ExprEngine.cpp:153
ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State)
Updates the given ProgramState.
bool isReferenceType() const
Definition: Type.h:6061
void dumpStack(raw_ostream &OS, StringRef Indent={}, const char *NL="\, const char *Sep="", std::function< void(const LocationContext *)> printMoreInfoPerContext=[](const LocationContext *) {}) const
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred)
Definition: ExprEngine.cpp:840
bool isAllEnumCasesCovered() const
Returns true if the SwitchStmt is a switch of an enum value and all cases have been explicitly covere...
Definition: Stmt.h:1099
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:6370
void enableNodeReclamation(unsigned Interval)
Enable tracking of recently allocated nodes for potential reclamation when calling reclaimRecentlyAll...
static std::string getNodeAttributes(const ExplodedNode *N, void *)
SourceLocation getLocation() const
Definition: ProgramPoint.h:536
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val, const LocationContext *LCtx) override
Call PointerEscape callback when a value escapes as a result of bind.
bool isGLValue() const
Definition: Expr.h:252
static bool isLocType(QualType T)
Definition: SVals.h:327
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
This is a meta program point, which should be skipped by all the diagnostic reasoning etc...
Definition: ProgramPoint.h:702
ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx, ExplodedNode *Pred, unsigned maxVisitOnPath)
Updates the stack of loops contained by the ProgramState.
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:409
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
STATISTIC(NumRemoveDeadBindings, "The # of times RemoveDeadBindings is called")
const StackFrameContext * getCurrentStackFrame() const
const LocationContext * getLocationContext() const
ExplodedNode * generateCaseStmtNode(const iterator &I, ProgramStateRef State)
Definition: CoreEngine.cpp:610
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:636
static bool isRecordType(QualType T)
const LocationContext * getParent() const
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3065
bool isUnknown() const
Definition: SVals.h:137
const Stmt * getStmt() const
If a crash happens while one of these objects are live, the message is printed out along with the spe...
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, const ASTContext *Context=nullptr) const
const VarDecl * getVarDecl() const
Definition: CFG.h:384
bool shouldUnrollLoops()
Returns true if the analysis should try to unroll loops with known bounds.
const CXXBaseSpecifier * getBaseSpecifier() const
Definition: CFG.h:436
bool isAnyMemberInitializer() const
Definition: DeclCXX.h:2312
An adjustment to be made to the temporary created when emitting a reference binding, which accesses a particular subobject of that temporary.
Definition: Expr.h:60
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
Definition: ExprEngine.cpp:867
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Definition: ExprEngine.cpp:886
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1196
virtual SVal getLValueField(const FieldDecl *D, SVal Base)
Definition: Store.h:144
FieldDecl * getAnyMember() const
Definition: DeclCXX.h:2377
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition: DeclCXX.cpp:1663
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
Definition: DeclCXX.h:2371
reverse_iterator rend()
Definition: CFG.h:708
void Profile(llvm::FoldingSetNodeID &ID) const
Definition: ExprEngine.cpp:167
void processStaticInitializer(const DeclStmt *DS, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
Called by CoreEngine.
const CFGBlock * getCallSiteBlock() const
void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, SVal location, SVal Val, bool atDeclInit=false, const ProgramPoint *PP=nullptr)
evalBind - Handle the semantics of binding a value to a specific location.
CheckerManager & getCheckerManager() const
Definition: ExprEngine.h:186
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for &#39;&&&#39;, &#39;||&#39;.
bool isArrayForm() const
Definition: ExprCXX.h:2115
CXXCtorInitializer * getInitializer() const
Definition: CFG.h:220
void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep)
Run checkers for debug-printing a ProgramState.
void removeDeadOnEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
void runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, ExprEngine &Eng, const ProgramPoint &PP)
Run checkers for binding of a value to a location.
static SourceManager * GraphPrintSourceManager
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1590
const FieldDecl * getFieldDecl() const
Definition: CFG.h:457
const Stmt * getCallSite() const
Expr ** getSubExprs()
Definition: Expr.h:5250
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
bool isDelegatingInitializer() const
Determine whether this initializer is creating a delegating constructor.
Definition: DeclCXX.h:2332
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
Definition: CFG.h:478
CFGBlock - Represents a single basic block in a source-level CFG.
Definition: CFG.h:548
void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
InliningModes
The modes of inlining, which override the default analysis-wide settings.
Definition: ExprEngine.h:87
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:759
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
static void printLocation(raw_ostream &OS, const SourceManager &SM, SourceLocation SLoc)
static unsigned getNumSubExprs(AtomicOp Op)
Determine the number of arguments the specified atomic builtin should have.
Definition: Expr.cpp:4054
void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Definition: ExprEngine.cpp:960
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing &#39;0&#39; for the specified type.
Definition: SValBuilder.cpp:51
void processSwitch(SwitchNodeBuilder &builder) override
ProcessSwitch - Called by CoreEngine.
void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep, const LocationContext *LCtx=nullptr) override
printState - Called by ProgramStateManager to print checker-specific data.
Definition: ExprEngine.cpp:534
void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L) override
Called by CoreEngine.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:636
Expr - This represents one expression.
Definition: Expr.h:106
Defines the clang::LangOptions interface.
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
std::string Label
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
const FunctionProtoType * T
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Kind getKind() const
Definition: ProgramPoint.h:161
const Expr * getCondition() const
Definition: CoreEngine.h:562
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2686
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition: CoreEngine.h:228
void Add(ExplodedNode *N)
The pointer has been passed to a function call directly.
struct DTB DerivedToBase
Definition: Expr.h:78
Expr * getRHS()
Definition: Stmt.h:781
virtual StringRef getTagDescription() const =0
QualType getConditionType() const
Definition: SValBuilder.h:161
bool isValid() const
Definition: SVals.h:149
const LocationContext * getLocationContext() const
Definition: CoreEngine.h:566
bool isTemporaryDtorsBranch() const
Definition: CFG.h:509
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
void FlushReports()
Generate and flush diagnostics for all bug reports.
const CFGBlock * getDst() const
Definition: ProgramPoint.h:485
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
std::pair< const ProgramPointTag *, const ProgramPointTag * > geteagerlyAssumeBinOpBifurcationTags()
QualType getType() const
Definition: Expr.h:128
The reason for pointer escape is unknown.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Definition: ExprEngine.h:182
Traits for storing the call processing policy inside GDM.
Definition: ExprEngine.h:795
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1341
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:1433
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAtomicExpr - Transfer function for builtin atomic expressions.
This represents a Microsoft inline-assembly statement extension.
Definition: Stmt.h:1811
const SwitchStmt * getSwitch() const
Definition: CoreEngine.h:552
void evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx, const Expr *BoundExpr, ExplodedNode *Pred, ProgramStateRef St, SVal location, const ProgramPointTag *tag=nullptr, QualType LoadTy=QualType())
Simulate a read of the result of Ex.
CFGBaseDtor - Represents C++ object destructor implicitly generated for base object in destructor...
Definition: CFG.h:431
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
QualType getDestroyedType() const
Retrieve the type being destroyed.
Definition: ExprCXX.cpp:178
const Expr * getSubExpr() const
Definition: ExprCXX.h:1219
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:720
reverse_iterator rbegin()
Definition: CFG.h:707
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper &SymReaper)=0
Scan all symbols referenced by the constraints.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:112
const MemRegion * getRegion() const
Get the underlining region.
Definition: SVals.h:602
ExplodedNode * generateNode(const iterator &I, ProgramStateRef State, bool isSink=false)
Definition: CoreEngine.cpp:591
While alive, includes the current analysis stack in a crash trace.
void processEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, const ReturnStmt *RS=nullptr) override
Called by CoreEngine.
Thread storage duration.
Definition: Specifiers.h:279
Expr * getArgument()
Definition: ExprCXX.h:2128
static const Stmt * ResolveCondition(const Stmt *Condition, const CFGBlock *B)
CFGTerminator getTerminator()
Definition: CFG.h:839
Kind getKind() const
Definition: CFG.h:118
void processCFGElement(const CFGElement E, ExplodedNode *Pred, unsigned StmtIdx, NodeBuilderContext *Ctx) override
processCFGElement - Called by CoreEngine.
Definition: ExprEngine.cpp:554
bool operator==(const ConstructedObjectKey &RHS) const
Definition: ExprEngine.cpp:172
ProgramStateRef getInitialState(const LocationContext *InitLoc)
const LocationContext * getLocationContext() const
Definition: CoreEngine.h:512
const Stmt * getStmt() const
Definition: ProgramPoint.h:272
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
const Stmt * getLoopStmt() const
Definition: ProgramPoint.h:688
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState, const LocationContext *LCtx, unsigned BlockCount, const Stmt *LoopStmt)
Get the states that result from widening the loop.
Encodes a location in the source.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique &#39;name&#39;.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Definition: Type.h:4098
Stmt * getLabel()
Definition: CFG.h:850
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
Definition: ProgramPoint.h:141
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
Definition: CallEvent.cpp:309
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
Definition: ProgramPoint.h:40
AnalysisManager & getAnalysisManager() override
Definition: ExprEngine.h:184
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Definition: Decl.h:291
void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex)
evalEagerlyAssumeBinOpBifurcation - Given the nodes in &#39;Src&#39;, eagerly assume symbolic expressions of ...
const MemRegion * getAsRegion() const
Definition: SVals.cpp:151
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Definition: ExprCXX.h:1845
Expr * getLHS()
Definition: Stmt.h:780
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:499
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
Represents the declaration of a label.
Definition: Decl.h:468
ExplodedNode * generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Definition: CoreEngine.h:345
static void printLocation(raw_ostream &Out, SourceLocation SLoc)
void processIndirectGoto(IndirectGotoNodeBuilder &builder) override
processIndirectGoto - Called by CoreEngine.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
Definition: MemRegion.cpp:1015
SourceLocation getLocStart() const LLVM_READONLY
Definition: ExprCXX.h:2137
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void processBranch(const Stmt *Condition, const Stmt *Term, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
ProcessBranch - Called by CoreEngine.
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...
Definition: ExprEngine.h:99
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:76
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>, and corresponding __opencl_atomic_* for OpenCL 2.0.
Definition: Expr.h:5183
CanQualType VoidTy
Definition: ASTContext.h:997
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:2902
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitObjCForCollectionStmt - Transfer function logic for ObjCForCollectionStmt.
A class responsible for cleaning up unused symbols.
const Decl * getDecl() const
Definition: ProgramPoint.h:535
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
bool isVectorType() const
Definition: Type.h:6134
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
void insert(const ExplodedNodeSet &S)
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
Definition: CFG.h:109
Defines various enumerations that describe declaration and type specifiers.
StringRef getName() const
Return the actual identifier string.
ast_type_traits::DynTypedNode Node
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
CanQualType CharTy
Definition: ASTContext.h:999
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
Dataflow Directional Tag Classes.
void ProcessStmt(const Stmt *S, ExplodedNode *Pred)
Definition: ExprEngine.cpp:704
ExplodedNode * generateDefaultCaseNode(ProgramStateRef State, bool isSink=false)
Definition: CoreEngine.cpp:625
SValBuilder & getSValBuilder()
Definition: ExprEngine.h:190
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
Definition: ExprCXX.h:2074
void addNodes(const ExplodedNodeSet &S)
Definition: CoreEngine.h:327
StoreManager & getStoreManager()
Definition: ExprEngine.h:372
Represents a program point just after an implicit call event.
Definition: ProgramPoint.h:570
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call) override
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store...
Definition: ExprEngine.cpp:506
const Stmt * getStmt() const
Definition: ExprEngine.cpp:145
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
Definition: DeclCXX.cpp:2225
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, const EvalCallOptions &Options)
const NodeBuilderContext & getContext()
Definition: CoreEngine.h:318
unsigned getGraphTrimInterval()
Returns how often nodes in the ExplodedGraph should be recycled to save memory.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
bool hasWorkRemaining() const
Definition: ExprEngine.h:390
This node builder keeps track of the generated sink nodes.
Definition: CoreEngine.h:333
bool isPurgeKind()
Is this a program point corresponding to purge/removal of dead symbols and bindings.
Definition: ProgramPoint.h:172
StmtClass getStmtClass() const
Definition: Stmt.h:389
void reclaimRecentlyAllocatedNodes()
Reclaim "uninteresting" nodes created since the last time this method was called. ...
enum clang::SubobjectAdjustment::@36 Kind
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
const Decl * getSingleDecl() const
Definition: Stmt.h:516
const ProgramPointTag * getTag() const
Definition: ProgramPoint.h:178
Represents symbolic expression.
Definition: SVals.h:347
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
Definition: CoreEngine.h:422
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:164
ProgramStateRef getState() const
Definition: CoreEngine.h:564
const Stmt * getLoopStmt() const
Definition: CFG.h:265
ProgramStateManager & getStateManager() override
Definition: ExprEngine.h:370
This class is used for tools that requires cross translation unit capability.
const Decl * getDecl() const
const CXXDeleteExpr * getDeleteExpr() const
Definition: CFG.h:415
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Definition: Expr.cpp:2587
const CXXTempObjectRegion * getCXXStaticTempObjectRegion(const Expr *Ex)
Create a CXXTempObjectRegion for temporaries which are lifetime-extended by static references...
Definition: MemRegion.cpp:939
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
SwitchStmt - This represents a &#39;switch&#39; stmt.
Definition: Stmt.h:1027
unsigned getIntWidth(QualType T) const
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)
Run checkers for end of analysis.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition: SVals.h:104
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2195
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Definition: CoreEngine.h:352
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2238
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for ObjCAtSynchronizedStmts.
IndirectFieldDecl * getIndirectMember() const
Definition: DeclCXX.h:2385
const LocationContext * getLocationContext() const
Definition: ProgramPoint.h:180
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
llvm::FoldingSet< BugReportEquivClass >::iterator EQClasses_iterator
Iterator over the set of BugReports tracked by the BugReporter.
Definition: BugReporter.h:465
Represents a base class of a C++ class.
Definition: DeclCXX.h:192
void getCaptureFields(llvm::DenseMap< const VarDecl *, FieldDecl *> &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
Definition: DeclCXX.cpp:1360
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2040
SourceManager & getSourceManager()
Definition: ASTContext.h:644
outputs_range outputs()
Definition: Stmt.h:1614
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:13462
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
Definition: CoreEngine.h:281
const CXXNewExpr * getAllocatorExpr() const
Definition: CFG.h:241
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:2465
Defines the clang::SourceLocation class and associated facilities.
Represents a C++ struct/union/class.
Definition: DeclCXX.h:300
bool isVoidType() const
Definition: Type.h:6276
CFGImplicitDtor - Represents C++ object destructor implicitly generated by compiler on various occasi...
Definition: CFG.h:354
ProgramStateRef getState() const
Definition: CoreEngine.h:510
pred_iterator pred_begin()
ExplodedNode * generateNode(ProgramStateRef State, bool branch, ExplodedNode *Pred)
Definition: CoreEngine.cpp:577
CFGElement - Represents a top-level expression in a basic block.
Definition: CFG.h:55
ConstructedObjectKey(llvm::PointerUnion< const Stmt *, const CXXCtorInitializer *> P, const LocationContext *LC)
Definition: ExprEngine.cpp:134
This class is used for builtin types like &#39;int&#39;.
Definition: Type.h:2235
ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption) override
evalAssume - Callback function invoked by the ConstraintManager when making assumptions about state v...
Definition: ExprEngine.cpp:500
CFGMemberDtor - Represents C++ object destructor implicitly generated for member object in destructor...
Definition: CFG.h:452
const MemRegion * getBaseRegion() const
Definition: MemRegion.cpp:1126
FieldDecl * Field
Definition: Expr.h:79
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:399
bool isUndef() const
Definition: SVals.h:141
void processEndWorklist(bool hasWorkRemaining) override
Called by CoreEngine when the analysis worklist has terminated.
Definition: ExprEngine.cpp:550
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call)
Run checkers for region changes.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:972
CFGInitializer - Represents C++ base or member initializer from constructor&#39;s initialization list...
Definition: CFG.h:215
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
const StackFrameContext * getStackFrame() const
bool mayInlineCXXAllocator()
Returns whether or not allocator call may be considered for inlining.
void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for member expressions.
QualType getType() const
Definition: Decl.h:647
ProgramStateRef escapeValue(ProgramStateRef State, SVal V, PointerEscapeKind K) const
A simple wrapper when you only need to notify checkers of pointer-escape of a single value...
AnalysisPurgeMode AnalysisPurgeOpt
llvm::ImmutableMap< ConstructedObjectKey, SVal > ObjectsUnderConstructionMap
Definition: ExprEngine.cpp:182
This represents a decl that may have a name.
Definition: Decl.h:248
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
Definition: ProgramPoint.h:152
ConstraintManager & getConstraintManager()
Definition: ExprEngine.h:374
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
Definition: ExprEngineC.cpp:41
AnalysisDeclContext * getAnalysisDeclContext() const
bool isFeasible(bool branch)
Definition: CoreEngine.h:464
const Expr * getCond() const
Definition: Stmt.h:1065
static SVal RecoverCastedSymbol(ProgramStateManager &StateMgr, ProgramStateRef state, const Stmt *Condition, const LocationContext *LCtx, ASTContext &Ctx)
RecoverCastedSymbol - A helper function for ProcessBranch that is used to try to recover some path-se...
ConstructedObjectKey is used for being able to find the path-sensitive memory region of a freshly con...
Definition: ExprEngine.cpp:119
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
SourceLocation getLocStart() const LLVM_READONLY
Definition: Stmt.cpp:278
const Expr * getTarget() const
Definition: CoreEngine.h:508
This class handles loading and caching of source files into memory.
CFGTemporaryDtor - Represents C++ object destructor implicitly generated at the end of full expressio...
Definition: CFG.h:473
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
Definition: CoreEngine.h:208
bool isUnknownOrUndef() const
Definition: SVals.h:145
QualType getType() const
Return the type wrapped by this type source info.
Definition: Decl.h:97
void print(llvm::raw_ostream &OS, PrinterHelper *Helper, PrintingPolicy &PP)
Definition: ExprEngine.cpp:157
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Definition: Expr.cpp:2469
QualType getType() const
Retrieves the type of the base class.
Definition: DeclCXX.h:291
Represents the point where a loop ends.
Definition: CFG.h:261