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