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