clang  16.0.0git
ExprEngineCallAndReturn.cpp
Go to the documentation of this file.
1 //=-- ExprEngineCallAndReturn.cpp - Support for call/return -----*- C++ -*-===//
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 ExprEngine's support for calls and returns.
10 //
11 //===----------------------------------------------------------------------===//
12 
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclCXX.h"
23 #include "llvm/ADT/SmallSet.h"
24 #include "llvm/ADT/Statistic.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Support/SaveAndRestore.h"
28 
29 using namespace clang;
30 using namespace ento;
31 
32 #define DEBUG_TYPE "ExprEngine"
33 
34 STATISTIC(NumOfDynamicDispatchPathSplits,
35  "The # of times we split the path due to imprecise dynamic dispatch info");
36 
37 STATISTIC(NumInlinedCalls,
38  "The # of times we inlined a call");
39 
40 STATISTIC(NumReachedInlineCountMax,
41  "The # of times we reached inline count maximum");
42 
44  ExplodedNode *Pred) {
45  // Get the entry block in the CFG of the callee.
46  const StackFrameContext *calleeCtx = CE.getCalleeContext();
47  PrettyStackTraceLocationContext CrashInfo(calleeCtx);
48  const CFGBlock *Entry = CE.getEntry();
49 
50  // Validate the CFG.
51  assert(Entry->empty());
52  assert(Entry->succ_size() == 1);
53 
54  // Get the solitary successor.
55  const CFGBlock *Succ = *(Entry->succ_begin());
56 
57  // Construct an edge representing the starting location in the callee.
58  BlockEdge Loc(Entry, Succ, calleeCtx);
59 
60  ProgramStateRef state = Pred->getState();
61 
62  // Construct a new node, notify checkers that analysis of the function has
63  // begun, and add the resultant nodes to the worklist.
64  bool isNew;
65  ExplodedNode *Node = G.getNode(Loc, state, false, &isNew);
66  Node->addPredecessor(Pred, G);
67  if (isNew) {
68  ExplodedNodeSet DstBegin;
69  processBeginOfFunction(BC, Node, DstBegin, Loc);
70  Engine.enqueue(DstBegin);
71  }
72 }
73 
74 // Find the last statement on the path to the exploded node and the
75 // corresponding Block.
76 static std::pair<const Stmt*,
77  const CFGBlock*> getLastStmt(const ExplodedNode *Node) {
78  const Stmt *S = nullptr;
79  const CFGBlock *Blk = nullptr;
80  const StackFrameContext *SF = Node->getStackFrame();
81 
82  // Back up through the ExplodedGraph until we reach a statement node in this
83  // stack frame.
84  while (Node) {
85  const ProgramPoint &PP = Node->getLocation();
86 
87  if (PP.getStackFrame() == SF) {
88  if (Optional<StmtPoint> SP = PP.getAs<StmtPoint>()) {
89  S = SP->getStmt();
90  break;
91  } else if (Optional<CallExitEnd> CEE = PP.getAs<CallExitEnd>()) {
92  S = CEE->getCalleeContext()->getCallSite();
93  if (S)
94  break;
95 
96  // If there is no statement, this is an implicitly-generated call.
97  // We'll walk backwards over it and then continue the loop to find
98  // an actual statement.
100  do {
101  Node = Node->getFirstPred();
102  CE = Node->getLocationAs<CallEnter>();
103  } while (!CE || CE->getCalleeContext() != CEE->getCalleeContext());
104 
105  // Continue searching the graph.
106  } else if (Optional<BlockEdge> BE = PP.getAs<BlockEdge>()) {
107  Blk = BE->getSrc();
108  }
109  } else if (Optional<CallEnter> CE = PP.getAs<CallEnter>()) {
110  // If we reached the CallEnter for this function, it has no statements.
111  if (CE->getCalleeContext() == SF)
112  break;
113  }
114 
115  if (Node->pred_empty())
116  return std::make_pair(nullptr, nullptr);
117 
118  Node = *Node->pred_begin();
119  }
120 
121  return std::make_pair(S, Blk);
122 }
123 
124 /// Adjusts a return value when the called function's return type does not
125 /// match the caller's expression type. This can happen when a dynamic call
126 /// is devirtualized, and the overriding method has a covariant (more specific)
127 /// return type than the parent's method. For C++ objects, this means we need
128 /// to add base casts.
129 static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy,
130  StoreManager &StoreMgr) {
131  // For now, the only adjustments we handle apply only to locations.
132  if (!isa<Loc>(V))
133  return V;
134 
135  // If the types already match, don't do any unnecessary work.
136  ExpectedTy = ExpectedTy.getCanonicalType();
137  ActualTy = ActualTy.getCanonicalType();
138  if (ExpectedTy == ActualTy)
139  return V;
140 
141  // No adjustment is needed between Objective-C pointer types.
142  if (ExpectedTy->isObjCObjectPointerType() &&
143  ActualTy->isObjCObjectPointerType())
144  return V;
145 
146  // C++ object pointers may need "derived-to-base" casts.
147  const CXXRecordDecl *ExpectedClass = ExpectedTy->getPointeeCXXRecordDecl();
148  const CXXRecordDecl *ActualClass = ActualTy->getPointeeCXXRecordDecl();
149  if (ExpectedClass && ActualClass) {
150  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
151  /*DetectVirtual=*/false);
152  if (ActualClass->isDerivedFrom(ExpectedClass, Paths) &&
153  !Paths.isAmbiguous(ActualTy->getCanonicalTypeUnqualified())) {
154  return StoreMgr.evalDerivedToBase(V, Paths.front());
155  }
156  }
157 
158  // Unfortunately, Objective-C does not enforce that overridden methods have
159  // covariant return types, so we can't assert that that never happens.
160  // Be safe and return UnknownVal().
161  return UnknownVal();
162 }
163 
165  ExplodedNode *Pred,
166  ExplodedNodeSet &Dst) {
167  // Find the last statement in the function and the corresponding basic block.
168  const Stmt *LastSt = nullptr;
169  const CFGBlock *Blk = nullptr;
170  std::tie(LastSt, Blk) = getLastStmt(Pred);
171  if (!Blk || !LastSt) {
172  Dst.Add(Pred);
173  return;
174  }
175 
176  // Here, we destroy the current location context. We use the current
177  // function's entire body as a diagnostic statement, with which the program
178  // point will be associated. However, we only want to use LastStmt as a
179  // reference for what to clean up if it's a ReturnStmt; otherwise, everything
180  // is dead.
181  SaveAndRestore<const NodeBuilderContext *> NodeContextRAII(currBldrCtx, &BC);
182  const LocationContext *LCtx = Pred->getLocationContext();
183  removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt), LCtx,
184  LCtx->getAnalysisDeclContext()->getBody(),
186 }
187 
188 static bool wasDifferentDeclUsedForInlining(CallEventRef<> Call,
189  const StackFrameContext *calleeCtx) {
190  const Decl *RuntimeCallee = calleeCtx->getDecl();
191  const Decl *StaticDecl = Call->getDecl();
192  assert(RuntimeCallee);
193  if (!StaticDecl)
194  return true;
195  return RuntimeCallee->getCanonicalDecl() != StaticDecl->getCanonicalDecl();
196 }
197 
198 // Returns the number of elements in the array currently being destructed.
199 // If the element count is not found 0 will be returned.
201  const CallEvent &Call, const ProgramStateRef State, SValBuilder &SVB) {
202  assert(isa<CXXDestructorCall>(Call) &&
203  "The call event is not a destructor call!");
204 
205  const auto &DtorCall = cast<CXXDestructorCall>(Call);
206 
207  auto ThisVal = DtorCall.getCXXThisVal();
208 
209  if (auto ThisElementRegion = dyn_cast<ElementRegion>(ThisVal.getAsRegion())) {
210  auto ArrayRegion = ThisElementRegion->getAsArrayOffset().getRegion();
211  auto ElementType = ThisElementRegion->getElementType();
212 
213  auto ElementCount =
214  getDynamicElementCount(State, ArrayRegion, SVB, ElementType);
215 
216  if (!ElementCount.isConstant())
217  return 0;
218 
219  return ElementCount.getAsInteger()->getLimitedValue();
220  }
221 
222  return 0;
223 }
224 
225 ProgramStateRef ExprEngine::removeStateTraitsUsedForArrayEvaluation(
227  const LocationContext *LCtx) {
228 
229  assert(LCtx && "Location context must be provided!");
230 
231  if (E) {
232  if (getPendingInitLoop(State, E, LCtx))
233  State = removePendingInitLoop(State, E, LCtx);
234 
235  if (getIndexOfElementToConstruct(State, E, LCtx))
236  State = removeIndexOfElementToConstruct(State, E, LCtx);
237  }
238 
240  State = removePendingArrayDestruction(State, LCtx);
241 
242  return State;
243 }
244 
245 /// The call exit is simulated with a sequence of nodes, which occur between
246 /// CallExitBegin and CallExitEnd. The following operations occur between the
247 /// two program points:
248 /// 1. CallExitBegin (triggers the start of call exit sequence)
249 /// 2. Bind the return value
250 /// 3. Run Remove dead bindings to clean up the dead symbols from the callee.
251 /// 4. CallExitEnd (switch to the caller context)
252 /// 5. PostStmt<CallExpr>
254  // Step 1 CEBNode was generated before the call.
256  const StackFrameContext *calleeCtx = CEBNode->getStackFrame();
257 
258  // The parent context might not be a stack frame, so make sure we
259  // look up the first enclosing stack frame.
260  const StackFrameContext *callerCtx =
261  calleeCtx->getParent()->getStackFrame();
262 
263  const Stmt *CE = calleeCtx->getCallSite();
264  ProgramStateRef state = CEBNode->getState();
265  // Find the last statement in the function and the corresponding basic block.
266  const Stmt *LastSt = nullptr;
267  const CFGBlock *Blk = nullptr;
268  std::tie(LastSt, Blk) = getLastStmt(CEBNode);
269 
270  // Generate a CallEvent /before/ cleaning the state, so that we can get the
271  // correct value for 'this' (if necessary).
273  CallEventRef<> Call = CEMgr.getCaller(calleeCtx, state);
274 
275  // Step 2: generate node with bound return value: CEBNode -> BindedRetNode.
276 
277  // If this variable is set to 'true' the analyzer will evaluate the call
278  // statement we are about to exit again, instead of continuing the execution
279  // from the statement after the call. This is useful for non-POD type array
280  // construction where the CXXConstructExpr is referenced only once in the CFG,
281  // but we want to evaluate it as many times as many elements the array has.
282  bool ShouldRepeatCall = false;
283 
284  if (const auto *DtorDecl =
285  dyn_cast_or_null<CXXDestructorDecl>(Call->getDecl())) {
286  if (auto Idx = getPendingArrayDestruction(state, callerCtx)) {
287  ShouldRepeatCall = *Idx > 0;
288 
289  auto ThisVal = svalBuilder.getCXXThis(DtorDecl->getParent(), calleeCtx);
290  state = state->killBinding(ThisVal);
291  }
292  }
293 
294  // If the callee returns an expression, bind its value to CallExpr.
295  if (CE) {
296  if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
297  const LocationContext *LCtx = CEBNode->getLocationContext();
298  SVal V = state->getSVal(RS, LCtx);
299 
300  // Ensure that the return type matches the type of the returned Expr.
301  if (wasDifferentDeclUsedForInlining(Call, calleeCtx)) {
302  QualType ReturnedTy =
304  if (!ReturnedTy.isNull()) {
305  if (const Expr *Ex = dyn_cast<Expr>(CE)) {
306  V = adjustReturnValue(V, Ex->getType(), ReturnedTy,
307  getStoreManager());
308  }
309  }
310  }
311 
312  state = state->BindExpr(CE, callerCtx, V);
313  }
314 
315  // Bind the constructed object value to CXXConstructExpr.
316  if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
318  svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
319  SVal ThisV = state->getSVal(This);
320  ThisV = state->getSVal(ThisV.castAs<Loc>());
321  state = state->BindExpr(CCE, callerCtx, ThisV);
322 
323  ShouldRepeatCall = shouldRepeatCtorCall(state, CCE, callerCtx);
324  }
325 
326  if (const auto *CNE = dyn_cast<CXXNewExpr>(CE)) {
327  // We are currently evaluating a CXXNewAllocator CFGElement. It takes a
328  // while to reach the actual CXXNewExpr element from here, so keep the
329  // region for later use.
330  // Additionally cast the return value of the inlined operator new
331  // (which is of type 'void *') to the correct object type.
332  SVal AllocV = state->getSVal(CNE, callerCtx);
333  AllocV = svalBuilder.evalCast(
334  AllocV, CNE->getType(),
335  getContext().getPointerType(getContext().VoidTy));
336 
337  state = addObjectUnderConstruction(state, CNE, calleeCtx->getParent(),
338  AllocV);
339  }
340  }
341 
342  if (!ShouldRepeatCall) {
343  state = removeStateTraitsUsedForArrayEvaluation(
344  state, dyn_cast_or_null<CXXConstructExpr>(CE), callerCtx);
345  }
346 
347  // Step 3: BindedRetNode -> CleanedNodes
348  // If we can find a statement and a block in the inlined function, run remove
349  // dead bindings before returning from the call. This is important to ensure
350  // that we report the issues such as leaks in the stack contexts in which
351  // they occurred.
352  ExplodedNodeSet CleanedNodes;
353  if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
354  static SimpleProgramPointTag retValBind("ExprEngine", "Bind Return Value");
355  PostStmt Loc(LastSt, calleeCtx, &retValBind);
356  bool isNew;
357  ExplodedNode *BindedRetNode = G.getNode(Loc, state, false, &isNew);
358  BindedRetNode->addPredecessor(CEBNode, G);
359  if (!isNew)
360  return;
361 
362  NodeBuilderContext Ctx(getCoreEngine(), Blk, BindedRetNode);
363  currBldrCtx = &Ctx;
364  // Here, we call the Symbol Reaper with 0 statement and callee location
365  // context, telling it to clean up everything in the callee's context
366  // (and its children). We use the callee's function body as a diagnostic
367  // statement, with which the program point will be associated.
368  removeDead(BindedRetNode, CleanedNodes, nullptr, calleeCtx,
369  calleeCtx->getAnalysisDeclContext()->getBody(),
371  currBldrCtx = nullptr;
372  } else {
373  CleanedNodes.Add(CEBNode);
374  }
375 
376  for (ExplodedNodeSet::iterator I = CleanedNodes.begin(),
377  E = CleanedNodes.end(); I != E; ++I) {
378 
379  // Step 4: Generate the CallExit and leave the callee's context.
380  // CleanedNodes -> CEENode
381  CallExitEnd Loc(calleeCtx, callerCtx);
382  bool isNew;
383  ProgramStateRef CEEState = (*I == CEBNode) ? state : (*I)->getState();
384 
385  ExplodedNode *CEENode = G.getNode(Loc, CEEState, false, &isNew);
386  CEENode->addPredecessor(*I, G);
387  if (!isNew)
388  return;
389 
390  // Step 5: Perform the post-condition check of the CallExpr and enqueue the
391  // result onto the work list.
392  // CEENode -> Dst -> WorkList
393  NodeBuilderContext Ctx(Engine, calleeCtx->getCallSiteBlock(), CEENode);
394  SaveAndRestore<const NodeBuilderContext*> NBCSave(currBldrCtx,
395  &Ctx);
396  SaveAndRestore<unsigned> CBISave(currStmtIdx, calleeCtx->getIndex());
397 
398  CallEventRef<> UpdatedCall = Call.cloneWithState(CEEState);
399 
400  ExplodedNodeSet DstPostCall;
401  if (llvm::isa_and_nonnull<CXXNewExpr>(CE)) {
402  ExplodedNodeSet DstPostPostCallCallback;
403  getCheckerManager().runCheckersForPostCall(DstPostPostCallCallback,
404  CEENode, *UpdatedCall, *this,
405  /*wasInlined=*/true);
406  for (ExplodedNode *I : DstPostPostCallCallback) {
408  cast<CXXAllocatorCall>(*UpdatedCall), DstPostCall, I, *this,
409  /*wasInlined=*/true);
410  }
411  } else {
412  getCheckerManager().runCheckersForPostCall(DstPostCall, CEENode,
413  *UpdatedCall, *this,
414  /*wasInlined=*/true);
415  }
416  ExplodedNodeSet Dst;
417  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
418  getCheckerManager().runCheckersForPostObjCMessage(Dst, DstPostCall, *Msg,
419  *this,
420  /*wasInlined=*/true);
421  } else if (CE &&
422  !(isa<CXXNewExpr>(CE) && // Called when visiting CXXNewExpr.
423  AMgr.getAnalyzerOptions().MayInlineCXXAllocator)) {
424  getCheckerManager().runCheckersForPostStmt(Dst, DstPostCall, CE,
425  *this, /*wasInlined=*/true);
426  } else {
427  Dst.insert(DstPostCall);
428  }
429 
430  // Enqueue the next element in the block.
431  for (ExplodedNodeSet::iterator PSI = Dst.begin(), PSE = Dst.end();
432  PSI != PSE; ++PSI) {
433  unsigned Idx = calleeCtx->getIndex() + (ShouldRepeatCall ? 0 : 1);
434 
435  Engine.getWorkList()->enqueue(*PSI, calleeCtx->getCallSiteBlock(), Idx);
436  }
437  }
438 }
439 
440 bool ExprEngine::isSmall(AnalysisDeclContext *ADC) const {
441  // When there are no branches in the function, it means that there's no
442  // exponential complexity introduced by inlining such function.
443  // Such functions also don't trigger various fundamental problems
444  // with our inlining mechanism, such as the problem of
445  // inlined defensive checks. Hence isLinear().
446  const CFG *Cfg = ADC->getCFG();
447  return Cfg->isLinear() || Cfg->size() <= AMgr.options.AlwaysInlineSize;
448 }
449 
450 bool ExprEngine::isLarge(AnalysisDeclContext *ADC) const {
451  const CFG *Cfg = ADC->getCFG();
452  return Cfg->size() >= AMgr.options.MinCFGSizeTreatFunctionsAsLarge;
453 }
454 
455 bool ExprEngine::isHuge(AnalysisDeclContext *ADC) const {
456  const CFG *Cfg = ADC->getCFG();
457  return Cfg->getNumBlockIDs() > AMgr.options.MaxInlinableSize;
458 }
459 
460 void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx,
461  bool &IsRecursive, unsigned &StackDepth) {
462  IsRecursive = false;
463  StackDepth = 0;
464 
465  while (LCtx) {
466  if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LCtx)) {
467  const Decl *DI = SFC->getDecl();
468 
469  // Mark recursive (and mutually recursive) functions and always count
470  // them when measuring the stack depth.
471  if (DI == D) {
472  IsRecursive = true;
473  ++StackDepth;
474  LCtx = LCtx->getParent();
475  continue;
476  }
477 
478  // Do not count the small functions when determining the stack depth.
479  AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI);
480  if (!isSmall(CalleeADC))
481  ++StackDepth;
482  }
483  LCtx = LCtx->getParent();
484  }
485 }
486 
487 // The GDM component containing the dynamic dispatch bifurcation info. When
488 // the exact type of the receiver is not known, we want to explore both paths -
489 // one on which we do inline it and the other one on which we don't. This is
490 // done to ensure we do not drop coverage.
491 // This is the map from the receiver region to a bool, specifying either we
492 // consider this region's information precise or not along the given path.
493 namespace {
494  enum DynamicDispatchMode {
495  DynamicDispatchModeInlined = 1,
496  DynamicDispatchModeConservative
497  };
498 } // end anonymous namespace
499 
500 REGISTER_MAP_WITH_PROGRAMSTATE(DynamicDispatchBifurcationMap,
501  const MemRegion *, unsigned)
502 REGISTER_TRAIT_WITH_PROGRAMSTATE(CTUDispatchBifurcation, bool)
503 
504 void ExprEngine::ctuBifurcate(const CallEvent &Call, const Decl *D,
505  NodeBuilder &Bldr, ExplodedNode *Pred,
507  ProgramStateRef ConservativeEvalState = nullptr;
508  if (Call.isForeign() && !isSecondPhaseCTU()) {
509  const auto IK = AMgr.options.getCTUPhase1Inlining();
510  const bool DoInline = IK == CTUPhase1InliningKind::All ||
512  isSmall(AMgr.getAnalysisDeclContext(D)));
513  if (DoInline) {
514  inlineCall(Engine.getWorkList(), Call, D, Bldr, Pred, State);
515  return;
516  }
517  const bool BState = State->get<CTUDispatchBifurcation>();
518  if (!BState) { // This is the first time we see this foreign function.
519  // Enqueue it to be analyzed in the second (ctu) phase.
520  inlineCall(Engine.getCTUWorkList(), Call, D, Bldr, Pred, State);
521  // Conservatively evaluate in the first phase.
522  ConservativeEvalState = State->set<CTUDispatchBifurcation>(true);
523  conservativeEvalCall(Call, Bldr, Pred, ConservativeEvalState);
524  } else {
525  conservativeEvalCall(Call, Bldr, Pred, State);
526  }
527  return;
528  }
529  inlineCall(Engine.getWorkList(), Call, D, Bldr, Pred, State);
530 }
531 
532 void ExprEngine::inlineCall(WorkList *WList, const CallEvent &Call,
533  const Decl *D, NodeBuilder &Bldr,
534  ExplodedNode *Pred, ProgramStateRef State) {
535  assert(D);
536 
537  const LocationContext *CurLC = Pred->getLocationContext();
538  const StackFrameContext *CallerSFC = CurLC->getStackFrame();
539  const LocationContext *ParentOfCallee = CallerSFC;
540  if (Call.getKind() == CE_Block &&
541  !cast<BlockCall>(Call).isConversionFromLambda()) {
542  const BlockDataRegion *BR = cast<BlockCall>(Call).getBlockRegion();
543  assert(BR && "If we have the block definition we should have its region");
544  AnalysisDeclContext *BlockCtx = AMgr.getAnalysisDeclContext(D);
545  ParentOfCallee = BlockCtx->getBlockInvocationContext(CallerSFC,
546  cast<BlockDecl>(D),
547  BR);
548  }
549 
550  // This may be NULL, but that's fine.
551  const Expr *CallE = Call.getOriginExpr();
552 
553  // Construct a new stack frame for the callee.
554  AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
555  const StackFrameContext *CalleeSFC =
556  CalleeADC->getStackFrame(ParentOfCallee, CallE, currBldrCtx->getBlock(),
557  currBldrCtx->blockCount(), currStmtIdx);
558 
559  CallEnter Loc(CallE, CalleeSFC, CurLC);
560 
561  // Construct a new state which contains the mapping from actual to
562  // formal arguments.
563  State = State->enterStackFrame(Call, CalleeSFC);
564 
565  bool isNew;
566  if (ExplodedNode *N = G.getNode(Loc, State, false, &isNew)) {
567  N->addPredecessor(Pred, G);
568  if (isNew)
569  WList->enqueue(N);
570  }
571 
572  // If we decided to inline the call, the successor has been manually
573  // added onto the work list so remove it from the node builder.
574  Bldr.takeNodes(Pred);
575 
576  NumInlinedCalls++;
577  Engine.FunctionSummaries->bumpNumTimesInlined(D);
578 
579  // Do not mark as visited in the 2nd run (CTUWList), so the function will
580  // be visited as top-level, this way we won't loose reports in non-ctu
581  // mode. Considering the case when a function in a foreign TU calls back
582  // into the main TU.
583  // Note, during the 1st run, it doesn't matter if we mark the foreign
584  // functions as visited (or not) because they can never appear as a top level
585  // function in the main TU.
586  if (!isSecondPhaseCTU())
587  // Mark the decl as visited.
588  if (VisitedCallees)
589  VisitedCallees->insert(D);
590 }
591 
593  const Stmt *CallE) {
594  const void *ReplayState = State->get<ReplayWithoutInlining>();
595  if (!ReplayState)
596  return nullptr;
597 
598  assert(ReplayState == CallE && "Backtracked to the wrong call.");
599  (void)CallE;
600 
601  return State->remove<ReplayWithoutInlining>();
602 }
603 
605  ExplodedNodeSet &dst) {
606  // Perform the previsit of the CallExpr.
607  ExplodedNodeSet dstPreVisit;
608  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, CE, *this);
609 
610  // Get the call in its initial state. We use this as a template to perform
611  // all the checks.
613  CallEventRef<> CallTemplate
614  = CEMgr.getSimpleCall(CE, Pred->getState(), Pred->getLocationContext());
615 
616  // Evaluate the function call. We try each of the checkers
617  // to see if the can evaluate the function call.
618  ExplodedNodeSet dstCallEvaluated;
619  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
620  I != E; ++I) {
621  evalCall(dstCallEvaluated, *I, *CallTemplate);
622  }
623 
624  // Finally, perform the post-condition check of the CallExpr and store
625  // the created nodes in 'Dst'.
626  // Note that if the call was inlined, dstCallEvaluated will be empty.
627  // The post-CallExpr check will occur in processCallExit.
628  getCheckerManager().runCheckersForPostStmt(dst, dstCallEvaluated, CE,
629  *this);
630 }
631 
632 ProgramStateRef ExprEngine::finishArgumentConstruction(ProgramStateRef State,
633  const CallEvent &Call) {
634  const Expr *E = Call.getOriginExpr();
635  // FIXME: Constructors to placement arguments of operator new
636  // are not supported yet.
637  if (!E || isa<CXXNewExpr>(E))
638  return State;
639 
640  const LocationContext *LC = Call.getLocationContext();
641  for (unsigned CallI = 0, CallN = Call.getNumArgs(); CallI != CallN; ++CallI) {
642  unsigned I = Call.getASTArgumentIndex(CallI);
643  if (Optional<SVal> V =
644  getObjectUnderConstruction(State, {E, I}, LC)) {
645  SVal VV = *V;
646  (void)VV;
647  assert(cast<VarRegion>(VV.castAs<loc::MemRegionVal>().getRegion())
648  ->getStackFrame()->getParent()
649  ->getStackFrame() == LC->getStackFrame());
650  State = finishObjectConstruction(State, {E, I}, LC);
651  }
652  }
653 
654  return State;
655 }
656 
657 void ExprEngine::finishArgumentConstruction(ExplodedNodeSet &Dst,
658  ExplodedNode *Pred,
659  const CallEvent &Call) {
660  ProgramStateRef State = Pred->getState();
661  ProgramStateRef CleanedState = finishArgumentConstruction(State, Call);
662  if (CleanedState == State) {
663  Dst.insert(Pred);
664  return;
665  }
666 
667  const Expr *E = Call.getOriginExpr();
668  const LocationContext *LC = Call.getLocationContext();
669  NodeBuilder B(Pred, Dst, *currBldrCtx);
670  static SimpleProgramPointTag Tag("ExprEngine",
671  "Finish argument construction");
672  PreStmt PP(E, LC, &Tag);
673  B.generateNode(PP, CleanedState, Pred);
674 }
675 
677  const CallEvent &Call) {
678  // WARNING: At this time, the state attached to 'Call' may be older than the
679  // state in 'Pred'. This is a minor optimization since CheckerManager will
680  // use an updated CallEvent instance when calling checkers, but if 'Call' is
681  // ever used directly in this function all callers should be updated to pass
682  // the most recent state. (It is probably not worth doing the work here since
683  // for some callers this will not be necessary.)
684 
685  // Run any pre-call checks using the generic call interface.
686  ExplodedNodeSet dstPreVisit;
687  getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred,
688  Call, *this);
689 
690  // Actually evaluate the function call. We try each of the checkers
691  // to see if the can evaluate the function call, and get a callback at
692  // defaultEvalCall if all of them fail.
693  ExplodedNodeSet dstCallEvaluated;
694  getCheckerManager().runCheckersForEvalCall(dstCallEvaluated, dstPreVisit,
695  Call, *this, EvalCallOptions());
696 
697  // If there were other constructors called for object-type arguments
698  // of this call, clean them up.
699  ExplodedNodeSet dstArgumentCleanup;
700  for (ExplodedNode *I : dstCallEvaluated)
701  finishArgumentConstruction(dstArgumentCleanup, I, Call);
702 
703  ExplodedNodeSet dstPostCall;
704  getCheckerManager().runCheckersForPostCall(dstPostCall, dstArgumentCleanup,
705  Call, *this);
706 
707  // Escaping symbols conjured during invalidating the regions above.
708  // Note that, for inlined calls the nodes were put back into the worklist,
709  // so we can assume that every node belongs to a conservative call at this
710  // point.
711 
712  // Run pointerEscape callback with the newly conjured symbols.
714  for (ExplodedNode *I : dstPostCall) {
715  NodeBuilder B(I, Dst, *currBldrCtx);
716  ProgramStateRef State = I->getState();
717  Escaped.clear();
718  {
719  unsigned Arg = -1;
720  for (const ParmVarDecl *PVD : Call.parameters()) {
721  ++Arg;
722  QualType ParamTy = PVD->getType();
723  if (ParamTy.isNull() ||
724  (!ParamTy->isPointerType() && !ParamTy->isReferenceType()))
725  continue;
726  QualType Pointee = ParamTy->getPointeeType();
727  if (Pointee.isConstQualified() || Pointee->isVoidType())
728  continue;
729  if (const MemRegion *MR = Call.getArgSVal(Arg).getAsRegion())
730  Escaped.emplace_back(loc::MemRegionVal(MR), State->getSVal(MR, Pointee));
731  }
732  }
733 
734  State = processPointerEscapedOnBind(State, Escaped, I->getLocationContext(),
735  PSK_EscapeOutParameters, &Call);
736 
737  if (State == I->getState())
738  Dst.insert(I);
739  else
740  B.generateNode(I->getLocation(), State, I);
741  }
742 }
743 
745  const LocationContext *LCtx,
747  const Expr *E = Call.getOriginExpr();
748  if (!E)
749  return State;
750 
751  // Some method families have known return values.
752  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
753  switch (Msg->getMethodFamily()) {
754  default:
755  break;
756  case OMF_autorelease:
757  case OMF_retain:
758  case OMF_self: {
759  // These methods return their receivers.
760  return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
761  }
762  }
763  } else if (const CXXConstructorCall *C = dyn_cast<CXXConstructorCall>(&Call)){
764  SVal ThisV = C->getCXXThisVal();
765  ThisV = State->getSVal(ThisV.castAs<Loc>());
766  return State->BindExpr(E, LCtx, ThisV);
767  }
768 
769  SVal R;
770  QualType ResultTy = Call.getResultType();
771  unsigned Count = currBldrCtx->blockCount();
772  if (auto RTC = getCurrentCFGElement().getAs<CFGCXXRecordTypedCall>()) {
773  // Conjure a temporary if the function returns an object by value.
774  SVal Target;
775  assert(RTC->getStmt() == Call.getOriginExpr());
776  EvalCallOptions CallOpts; // FIXME: We won't really need those.
778  Call.getOriginExpr(), State, currBldrCtx, LCtx,
779  RTC->getConstructionContext(), CallOpts);
780  const MemRegion *TargetR = Target.getAsRegion();
781  assert(TargetR);
782  // Invalidate the region so that it didn't look uninitialized. If this is
783  // a field or element constructor, we do not want to invalidate
784  // the whole structure. Pointer escape is meaningless because
785  // the structure is a product of conservative evaluation
786  // and therefore contains nothing interesting at this point.
788  ITraits.setTrait(TargetR,
790  State = State->invalidateRegions(TargetR, E, Count, LCtx,
791  /* CausesPointerEscape=*/false, nullptr,
792  &Call, &ITraits);
793 
794  R = State->getSVal(Target.castAs<Loc>(), E->getType());
795  } else {
796  // Conjure a symbol if the return value is unknown.
797 
798  // See if we need to conjure a heap pointer instead of
799  // a regular unknown pointer.
800  const auto *CNE = dyn_cast<CXXNewExpr>(E);
801  if (CNE && CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
802  R = svalBuilder.getConjuredHeapSymbolVal(E, LCtx, Count);
803  const MemRegion *MR = R.getAsRegion()->StripCasts();
804 
805  // Store the extent of the allocated object(s).
806  SVal ElementCount;
807  if (const Expr *SizeExpr = CNE->getArraySize().value_or(nullptr)) {
808  ElementCount = State->getSVal(SizeExpr, LCtx);
809  } else {
810  ElementCount = svalBuilder.makeIntVal(1, /*IsUnsigned=*/true);
811  }
812 
813  SVal ElementSize = getElementExtent(CNE->getAllocatedType(), svalBuilder);
814 
815  SVal Size =
816  svalBuilder.evalBinOp(State, BO_Mul, ElementCount, ElementSize,
817  svalBuilder.getArrayIndexType());
818 
819  // FIXME: This line is to prevent a crash. For more details please check
820  // issue #56264.
821  if (Size.isUndef())
822  Size = UnknownVal();
823 
824  State = setDynamicExtent(State, MR, Size.castAs<DefinedOrUnknownSVal>(),
825  svalBuilder);
826  } else {
827  R = svalBuilder.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count);
828  }
829  }
830  return State->BindExpr(E, LCtx, R);
831 }
832 
833 // Conservatively evaluate call by invalidating regions and binding
834 // a conjured return value.
835 void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
837  State = Call.invalidateRegions(currBldrCtx->blockCount(), State);
838  State = bindReturnValue(Call, Pred->getLocationContext(), State);
839 
840  // And make the result node.
841  Bldr.generateNode(Call.getProgramPoint(), State, Pred);
842 }
843 
844 ExprEngine::CallInlinePolicy
845 ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred,
846  AnalyzerOptions &Opts,
847  const EvalCallOptions &CallOpts) {
848  const LocationContext *CurLC = Pred->getLocationContext();
849  const StackFrameContext *CallerSFC = CurLC->getStackFrame();
850  switch (Call.getKind()) {
851  case CE_Function:
852  case CE_Block:
853  break;
854  case CE_CXXMember:
857  return CIP_DisallowedAlways;
858  break;
859  case CE_CXXConstructor: {
861  return CIP_DisallowedAlways;
862 
863  const CXXConstructorCall &Ctor = cast<CXXConstructorCall>(Call);
864 
865  const CXXConstructExpr *CtorExpr = Ctor.getOriginExpr();
866 
867  auto CCE = getCurrentCFGElement().getAs<CFGConstructor>();
868  const ConstructionContext *CC = CCE ? CCE->getConstructionContext()
869  : nullptr;
870 
871  if (llvm::isa_and_nonnull<NewAllocatedObjectConstructionContext>(CC) &&
872  !Opts.MayInlineCXXAllocator)
873  return CIP_DisallowedOnce;
874 
875  if (CallOpts.IsArrayCtorOrDtor) {
876  if (!shouldInlineArrayConstruction(Pred->getState(), CtorExpr, CurLC))
877  return CIP_DisallowedOnce;
878  }
879 
880  // Inlining constructors requires including initializers in the CFG.
881  const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
882  assert(ADC->getCFGBuildOptions().AddInitializers && "No CFG initializers");
883  (void)ADC;
884 
885  // If the destructor is trivial, it's always safe to inline the constructor.
886  if (Ctor.getDecl()->getParent()->hasTrivialDestructor())
887  break;
888 
889  // For other types, only inline constructors if destructor inlining is
890  // also enabled.
892  return CIP_DisallowedAlways;
893 
895  // If we don't handle temporary destructors, we shouldn't inline
896  // their constructors.
897  if (CallOpts.IsTemporaryCtorOrDtor &&
898  !Opts.ShouldIncludeTemporaryDtorsInCFG)
899  return CIP_DisallowedOnce;
900 
901  // If we did not find the correct this-region, it would be pointless
902  // to inline the constructor. Instead we will simply invalidate
903  // the fake temporary target.
904  if (CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion)
905  return CIP_DisallowedOnce;
906 
907  // If the temporary is lifetime-extended by binding it to a reference-type
908  // field within an aggregate, automatic destructors don't work properly.
909  if (CallOpts.IsTemporaryLifetimeExtendedViaAggregate)
910  return CIP_DisallowedOnce;
911  }
912 
913  break;
914  }
916  // This doesn't really increase the cost of inlining ever, because
917  // the stack frame of the inherited constructor is trivial.
918  return CIP_Allowed;
919  }
920  case CE_CXXDestructor: {
922  return CIP_DisallowedAlways;
923 
924  // Inlining destructors requires building the CFG correctly.
925  const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
926  assert(ADC->getCFGBuildOptions().AddImplicitDtors && "No CFG destructors");
927  (void)ADC;
928 
929  if (CallOpts.IsArrayCtorOrDtor) {
930  if (!shouldInlineArrayDestruction(getElementCountOfArrayBeingDestructed(
931  Call, Pred->getState(), svalBuilder))) {
932  return CIP_DisallowedOnce;
933  }
934  }
935 
936  // Allow disabling temporary destructor inlining with a separate option.
937  if (CallOpts.IsTemporaryCtorOrDtor &&
938  !Opts.MayInlineCXXTemporaryDtors)
939  return CIP_DisallowedOnce;
940 
941  // If we did not find the correct this-region, it would be pointless
942  // to inline the destructor. Instead we will simply invalidate
943  // the fake temporary target.
944  if (CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion)
945  return CIP_DisallowedOnce;
946  break;
947  }
948  case CE_CXXDeallocator:
949  [[fallthrough]];
950  case CE_CXXAllocator:
951  if (Opts.MayInlineCXXAllocator)
952  break;
953  // Do not inline allocators until we model deallocators.
954  // This is unfortunate, but basically necessary for smart pointers and such.
955  return CIP_DisallowedAlways;
956  case CE_ObjCMessage:
957  if (!Opts.MayInlineObjCMethod)
958  return CIP_DisallowedAlways;
959  if (!(Opts.getIPAMode() == IPAK_DynamicDispatch ||
961  return CIP_DisallowedAlways;
962  break;
963  }
964 
965  return CIP_Allowed;
966 }
967 
968 /// Returns true if the given C++ class contains a member with the given name.
969 static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD,
970  StringRef Name) {
971  const IdentifierInfo &II = Ctx.Idents.get(Name);
972  return RD->hasMemberName(Ctx.DeclarationNames.getIdentifier(&II));
973 }
974 
975 /// Returns true if the given C++ class is a container or iterator.
976 ///
977 /// Our heuristic for this is whether it contains a method named 'begin()' or a
978 /// nested type named 'iterator' or 'iterator_category'.
979 static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD) {
980  return hasMember(Ctx, RD, "begin") ||
981  hasMember(Ctx, RD, "iterator") ||
982  hasMember(Ctx, RD, "iterator_category");
983 }
984 
985 /// Returns true if the given function refers to a method of a C++ container
986 /// or iterator.
987 ///
988 /// We generally do a poor job modeling most containers right now, and might
989 /// prefer not to inline their methods.
990 static bool isContainerMethod(const ASTContext &Ctx,
991  const FunctionDecl *FD) {
992  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
993  return isContainerClass(Ctx, MD->getParent());
994  return false;
995 }
996 
997 /// Returns true if the given function is the destructor of a class named
998 /// "shared_ptr".
999 static bool isCXXSharedPtrDtor(const FunctionDecl *FD) {
1000  const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(FD);
1001  if (!Dtor)
1002  return false;
1003 
1004  const CXXRecordDecl *RD = Dtor->getParent();
1005  if (const IdentifierInfo *II = RD->getDeclName().getAsIdentifierInfo())
1006  if (II->isStr("shared_ptr"))
1007  return true;
1008 
1009  return false;
1010 }
1011 
1012 /// Returns true if the function in \p CalleeADC may be inlined in general.
1013 ///
1014 /// This checks static properties of the function, such as its signature and
1015 /// CFG, to determine whether the analyzer should ever consider inlining it,
1016 /// in any context.
1017 bool ExprEngine::mayInlineDecl(AnalysisDeclContext *CalleeADC) const {
1018  AnalyzerOptions &Opts = AMgr.getAnalyzerOptions();
1019  // FIXME: Do not inline variadic calls.
1020  if (CallEvent::isVariadic(CalleeADC->getDecl()))
1021  return false;
1022 
1023  // Check certain C++-related inlining policies.
1024  ASTContext &Ctx = CalleeADC->getASTContext();
1025  if (Ctx.getLangOpts().CPlusPlus) {
1026  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeADC->getDecl())) {
1027  // Conditionally control the inlining of template functions.
1028  if (!Opts.MayInlineTemplateFunctions)
1029  if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate)
1030  return false;
1031 
1032  // Conditionally control the inlining of C++ standard library functions.
1033  if (!Opts.MayInlineCXXStandardLibrary)
1034  if (Ctx.getSourceManager().isInSystemHeader(FD->getLocation()))
1036  return false;
1037 
1038  // Conditionally control the inlining of methods on objects that look
1039  // like C++ containers.
1040  if (!Opts.MayInlineCXXContainerMethods)
1041  if (!AMgr.isInCodeFile(FD->getLocation()))
1042  if (isContainerMethod(Ctx, FD))
1043  return false;
1044 
1045  // Conditionally control the inlining of the destructor of C++ shared_ptr.
1046  // We don't currently do a good job modeling shared_ptr because we can't
1047  // see the reference count, so treating as opaque is probably the best
1048  // idea.
1049  if (!Opts.MayInlineCXXSharedPtrDtor)
1050  if (isCXXSharedPtrDtor(FD))
1051  return false;
1052  }
1053  }
1054 
1055  // It is possible that the CFG cannot be constructed.
1056  // Be safe, and check if the CalleeCFG is valid.
1057  const CFG *CalleeCFG = CalleeADC->getCFG();
1058  if (!CalleeCFG)
1059  return false;
1060 
1061  // Do not inline large functions.
1062  if (isHuge(CalleeADC))
1063  return false;
1064 
1065  // It is possible that the live variables analysis cannot be
1066  // run. If so, bail out.
1067  if (!CalleeADC->getAnalysis<RelaxedLiveVariables>())
1068  return false;
1069 
1070  return true;
1071 }
1072 
1073 bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D,
1074  const ExplodedNode *Pred,
1075  const EvalCallOptions &CallOpts) {
1076  if (!D)
1077  return false;
1078 
1079  AnalysisManager &AMgr = getAnalysisManager();
1080  AnalyzerOptions &Opts = AMgr.options;
1081  AnalysisDeclContextManager &ADCMgr = AMgr.getAnalysisDeclContextManager();
1082  AnalysisDeclContext *CalleeADC = ADCMgr.getContext(D);
1083 
1084  // The auto-synthesized bodies are essential to inline as they are
1085  // usually small and commonly used. Note: we should do this check early on to
1086  // ensure we always inline these calls.
1087  if (CalleeADC->isBodyAutosynthesized())
1088  return true;
1089 
1090  if (!AMgr.shouldInlineCall())
1091  return false;
1092 
1093  // Check if this function has been marked as non-inlinable.
1094  Optional<bool> MayInline = Engine.FunctionSummaries->mayInline(D);
1095  if (MayInline) {
1096  if (!MayInline.value())
1097  return false;
1098 
1099  } else {
1100  // We haven't actually checked the static properties of this function yet.
1101  // Do that now, and record our decision in the function summaries.
1102  if (mayInlineDecl(CalleeADC)) {
1103  Engine.FunctionSummaries->markMayInline(D);
1104  } else {
1105  Engine.FunctionSummaries->markShouldNotInline(D);
1106  return false;
1107  }
1108  }
1109 
1110  // Check if we should inline a call based on its kind.
1111  // FIXME: this checks both static and dynamic properties of the call, which
1112  // means we're redoing a bit of work that could be cached in the function
1113  // summary.
1114  CallInlinePolicy CIP = mayInlineCallKind(Call, Pred, Opts, CallOpts);
1115  if (CIP != CIP_Allowed) {
1116  if (CIP == CIP_DisallowedAlways) {
1117  assert(!MayInline || *MayInline);
1118  Engine.FunctionSummaries->markShouldNotInline(D);
1119  }
1120  return false;
1121  }
1122 
1123  // Do not inline if recursive or we've reached max stack frame count.
1124  bool IsRecursive = false;
1125  unsigned StackDepth = 0;
1126  examineStackFrames(D, Pred->getLocationContext(), IsRecursive, StackDepth);
1127  if ((StackDepth >= Opts.InlineMaxStackDepth) &&
1128  (!isSmall(CalleeADC) || IsRecursive))
1129  return false;
1130 
1131  // Do not inline large functions too many times.
1132  if ((Engine.FunctionSummaries->getNumTimesInlined(D) >
1133  Opts.MaxTimesInlineLarge) &&
1134  isLarge(CalleeADC)) {
1135  NumReachedInlineCountMax++;
1136  return false;
1137  }
1138 
1139  if (HowToInline == Inline_Minimal && (!isSmall(CalleeADC) || IsRecursive))
1140  return false;
1141 
1142  return true;
1143 }
1144 
1145 bool ExprEngine::shouldInlineArrayConstruction(const ProgramStateRef State,
1146  const CXXConstructExpr *CE,
1147  const LocationContext *LCtx) {
1148  if (!CE)
1149  return false;
1150 
1151  // FIXME: Handle other arrays types.
1152  if (const auto *CAT = dyn_cast<ConstantArrayType>(CE->getType())) {
1153  unsigned ArrSize = getContext().getConstantArrayElementCount(CAT);
1154 
1155  // This might seem conter-intuitive at first glance, but the functions are
1156  // closely related. Reasoning about destructors depends only on the type
1157  // of the expression that initialized the memory region, which is the
1158  // CXXConstructExpr. So to avoid code repetition, the work is delegated
1159  // to the function that reasons about destructor inlining. Also note that
1160  // if the constructors of the array elements are inlined, the destructors
1161  // can also be inlined and if the destructors can be inline, it's safe to
1162  // inline the constructors.
1163  return shouldInlineArrayDestruction(ArrSize);
1164  }
1165 
1166  // Check if we're inside an ArrayInitLoopExpr, and it's sufficiently small.
1167  if (auto Size = getPendingInitLoop(State, CE, LCtx))
1168  return shouldInlineArrayDestruction(*Size);
1169 
1170  return false;
1171 }
1172 
1173 bool ExprEngine::shouldInlineArrayDestruction(uint64_t Size) {
1174 
1175  uint64_t maxAllowedSize = AMgr.options.maxBlockVisitOnPath;
1176 
1177  // Declaring a 0 element array is also possible.
1178  return Size <= maxAllowedSize && Size > 0;
1179 }
1180 
1181 bool ExprEngine::shouldRepeatCtorCall(ProgramStateRef State,
1182  const CXXConstructExpr *E,
1183  const LocationContext *LCtx) {
1184 
1185  if (!E)
1186  return false;
1187 
1188  auto Ty = E->getType();
1189 
1190  // FIXME: Handle non constant array types
1191  if (const auto *CAT = dyn_cast<ConstantArrayType>(Ty)) {
1192  unsigned Size = getContext().getConstantArrayElementCount(CAT);
1193  return Size > getIndexOfElementToConstruct(State, E, LCtx);
1194  }
1195 
1196  if (auto Size = getPendingInitLoop(State, E, LCtx))
1197  return Size > getIndexOfElementToConstruct(State, E, LCtx);
1198 
1199  return false;
1200 }
1201 
1202 static bool isTrivialObjectAssignment(const CallEvent &Call) {
1203  const CXXInstanceCall *ICall = dyn_cast<CXXInstanceCall>(&Call);
1204  if (!ICall)
1205  return false;
1206 
1207  const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(ICall->getDecl());
1208  if (!MD)
1209  return false;
1210  if (!(MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()))
1211  return false;
1212 
1213  return MD->isTrivial();
1214 }
1215 
1217  const CallEvent &CallTemplate,
1218  const EvalCallOptions &CallOpts) {
1219  // Make sure we have the most recent state attached to the call.
1220  ProgramStateRef State = Pred->getState();
1221  CallEventRef<> Call = CallTemplate.cloneWithState(State);
1222 
1223  // Special-case trivial assignment operators.
1224  if (isTrivialObjectAssignment(*Call)) {
1225  performTrivialCopy(Bldr, Pred, *Call);
1226  return;
1227  }
1228 
1229  // Try to inline the call.
1230  // The origin expression here is just used as a kind of checksum;
1231  // this should still be safe even for CallEvents that don't come from exprs.
1232  const Expr *E = Call->getOriginExpr();
1233 
1234  ProgramStateRef InlinedFailedState = getInlineFailedState(State, E);
1235  if (InlinedFailedState) {
1236  // If we already tried once and failed, make sure we don't retry later.
1237  State = InlinedFailedState;
1238  } else {
1239  RuntimeDefinition RD = Call->getRuntimeDefinition();
1240  Call->setForeign(RD.isForeign());
1241  const Decl *D = RD.getDecl();
1242  if (shouldInlineCall(*Call, D, Pred, CallOpts)) {
1243  if (RD.mayHaveOtherDefinitions()) {
1245 
1246  // Explore with and without inlining the call.
1247  if (Options.getIPAMode() == IPAK_DynamicDispatchBifurcate) {
1248  BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred);
1249  return;
1250  }
1251 
1252  // Don't inline if we're not in any dynamic dispatch mode.
1253  if (Options.getIPAMode() != IPAK_DynamicDispatch) {
1254  conservativeEvalCall(*Call, Bldr, Pred, State);
1255  return;
1256  }
1257  }
1258  ctuBifurcate(*Call, D, Bldr, Pred, State);
1259  return;
1260  }
1261  }
1262 
1263  // If we can't inline it, clean up the state traits used only if the function
1264  // is inlined.
1265  State = removeStateTraitsUsedForArrayEvaluation(
1266  State, dyn_cast_or_null<CXXConstructExpr>(E), Call->getLocationContext());
1267 
1268  // Also handle the return value and invalidate the regions.
1269  conservativeEvalCall(*Call, Bldr, Pred, State);
1270 }
1271 
1272 void ExprEngine::BifurcateCall(const MemRegion *BifurReg,
1273  const CallEvent &Call, const Decl *D,
1274  NodeBuilder &Bldr, ExplodedNode *Pred) {
1275  assert(BifurReg);
1276  BifurReg = BifurReg->StripCasts();
1277 
1278  // Check if we've performed the split already - note, we only want
1279  // to split the path once per memory region.
1280  ProgramStateRef State = Pred->getState();
1281  const unsigned *BState =
1282  State->get<DynamicDispatchBifurcationMap>(BifurReg);
1283  if (BState) {
1284  // If we are on "inline path", keep inlining if possible.
1285  if (*BState == DynamicDispatchModeInlined)
1286  ctuBifurcate(Call, D, Bldr, Pred, State);
1287  // If inline failed, or we are on the path where we assume we
1288  // don't have enough info about the receiver to inline, conjure the
1289  // return value and invalidate the regions.
1290  conservativeEvalCall(Call, Bldr, Pred, State);
1291  return;
1292  }
1293 
1294  // If we got here, this is the first time we process a message to this
1295  // region, so split the path.
1296  ProgramStateRef IState =
1297  State->set<DynamicDispatchBifurcationMap>(BifurReg,
1298  DynamicDispatchModeInlined);
1299  ctuBifurcate(Call, D, Bldr, Pred, IState);
1300 
1301  ProgramStateRef NoIState =
1302  State->set<DynamicDispatchBifurcationMap>(BifurReg,
1303  DynamicDispatchModeConservative);
1304  conservativeEvalCall(Call, Bldr, Pred, NoIState);
1305 
1306  NumOfDynamicDispatchPathSplits++;
1307 }
1308 
1310  ExplodedNodeSet &Dst) {
1311  ExplodedNodeSet dstPreVisit;
1312  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, RS, *this);
1313 
1314  StmtNodeBuilder B(dstPreVisit, Dst, *currBldrCtx);
1315 
1316  if (RS->getRetValue()) {
1317  for (ExplodedNodeSet::iterator it = dstPreVisit.begin(),
1318  ei = dstPreVisit.end(); it != ei; ++it) {
1319  B.generateNode(RS, *it, (*it)->getState());
1320  }
1321  }
1322 }
clang::ento::CE_Function
@ CE_Function
Definition: CallEvent.h:60
clang::ento::ExprEngine::processCallEnter
void processCallEnter(NodeBuilderContext &BC, CallEnter CE, ExplodedNode *Pred)
Generate the entry node of the callee.
Definition: ExprEngineCallAndReturn.cpp:43
clang::ento::WorkList::enqueue
virtual void enqueue(const WorkListUnit &U)=0
clang::ento::SValBuilder::evalBinOp
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
Definition: SValBuilder.cpp:484
clang::CXXConstructExpr::CK_Complete
@ CK_Complete
Definition: ExprCXX.h:1472
clang::ReturnStmt::getRetValue
Expr * getRetValue()
Definition: Stmt.h:2829
clang::ento::RuntimeDefinition::mayHaveOtherDefinitions
bool mayHaveOtherDefinitions()
Check if the definition we have is precise.
Definition: CallEvent.h:132
clang::ento::ExprEngine::getStateManager
ProgramStateManager & getStateManager()
Definition: ExprEngine.h:417
clang::AnalysisDeclContext::getASTContext
ASTContext & getASTContext() const
Definition: AnalysisDeclContext.h:104
clang::CXXMethodDecl::isCopyAssignmentOperator
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition: DeclCXX.cpp:2396
clang::OMF_autorelease
@ OMF_autorelease
Definition: IdentifierTable.h:713
clang::ento::ExplodedNode::getLocationContext
const LocationContext * getLocationContext() const
Definition: ExplodedGraph.h:146
clang::ento::RuntimeDefinition::getDecl
const Decl * getDecl()
Definition: CallEvent.h:126
DynamicExtent.h
clang::ento::CallEventRef
Definition: CallEvent.h:81
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::ento::FunctionSummariesTy::markMayInline
void markMayInline(const Decl *D)
Definition: FunctionSummary.h:73
clang::CFGBlock::empty
bool empty() const
Definition: CFG.h:920
clang::AnalysisDeclContext::isBodyAutosynthesized
bool isBodyAutosynthesized() const
Definition: AnalysisDeclContext.cpp:131
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:100
clang::ento::ExprEngine::VisitCallExpr
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
Definition: ExprEngineCallAndReturn.cpp:604
clang::QualType::isConstQualified
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6694
clang::ento::ExplodedNodeSet::iterator
ImplTy::iterator iterator
Definition: ExplodedGraph.h:477
clang::ento::SVal::getAsRegion
const MemRegion * getAsRegion() const
Definition: SVals.cpp:120
clang::CFGBlock::succ_size
unsigned succ_size() const
Definition: CFG.h:975
clang::CFG::getNumBlockIDs
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
Definition: CFG.h:1413
clang::CFGBlock::succ_begin
succ_iterator succ_begin()
Definition: CFG.h:957
clang::ento::DefinedOrUnknownSVal
Definition: SVals.h:221
llvm::SmallVector
Definition: LLVM.h:38
clang::ento::MemRegion::StripCasts
const LLVM_ATTRIBUTE_RETURNS_NONNULL MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1342
clang::IdentifierTable::get
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Definition: IdentifierTable.h:597
clang::ento::ExprEngine::getContext
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Definition: ExprEngine.h:203
clang::MultiVersionKind::Target
@ Target
CXXInheritance.h
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::ASTContext::DeclarationNames
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:664
clang::ento::ProgramStateRef
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
Definition: ProgramState_Fwd.h:37
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::ConstructionContext
ConstructionContext's subclasses describe different ways of constructing an object in C++.
Definition: ConstructionContext.h:243
clang::AnalysisDeclContext
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Definition: AnalysisDeclContext.h:72
clang::ento::ExplodedNode::getStackFrame
const StackFrameContext * getStackFrame() const
Definition: ExplodedGraph.h:150
clang::QualType::getCanonicalType
QualType getCanonicalType() const
Definition: Type.h:6674
clang::ento::ExplodedNode
Definition: ExplodedGraph.h:65
clang::ento::CE_CXXDeallocator
@ CE_CXXDeallocator
Definition: CallEvent.h:71
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1712
clang::ento::CheckerManager::runCheckersForEvalCall
void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &CE, ExprEngine &Eng, const EvalCallOptions &CallOpts)
Run checkers for evaluating a call.
Definition: CheckerManager.cpp:653
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:1309
clang::AnalysisDeclContext::getStackFrame
const StackFrameContext * getStackFrame(LocationContext const *ParentLC, const Stmt *S, const CFGBlock *Blk, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
Definition: AnalysisDeclContext.cpp:312
clang::ento::ExplodedNodeSet::Add
void Add(ExplodedNode *N)
Definition: ExplodedGraph.h:473
clang::ento::SValBuilder::getArrayIndexType
QualType getArrayIndexType() const
Definition: SValBuilder.h:145
clang::StackFrameContext::getCallSiteBlock
const CFGBlock * getCallSiteBlock() const
Definition: AnalysisDeclContext.h:327
llvm::Optional
Definition: LLVM.h:40
clang::CFG::isLinear
bool isLinear() const
Returns true if the CFG has no branches.
Definition: CFG.cpp:5238
clang::StackFrameContext
It represents a stack frame of the call stack (based on CallEvent).
Definition: AnalysisDeclContext.h:299
clang::AnalyzerOptions::getCTUPhase1Inlining
CTUPhase1InliningKind getCTUPhase1Inlining() const
Definition: AnalyzerOptions.cpp:84
clang::ento::CheckerManager::runCheckersForPostCall
void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
Definition: CheckerManager.h:316
clang::Type::isVoidType
bool isVoidType() const
Definition: Type.h:7180
clang::ento::UnknownVal
Definition: SVals.h:236
clang::ento::StmtNodeBuilder
Definition: CoreEngine.h:391
clang::CTUPhase1InliningKind::Small
@ Small
clang::StackFrameContext::getIndex
unsigned getIndex() const
Definition: AnalysisDeclContext.h:331
clang::DeclarationName::getAsIdentifierInfo
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
Definition: DeclarationName.h:419
clang::CFG::size
unsigned size() const
Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlockIDs()...
Definition: CFG.h:1418
clang::ento::CallEvent::getDeclaredResultType
static QualType getDeclaredResultType(const Decl *D)
Returns the result type of a function or method declaration.
Definition: CallEvent.cpp:349
clang::ento::loc::MemRegionVal
Definition: SVals.h:506
clang::ento::ExprEngine::bindReturnValue
ProgramStateRef bindReturnValue(const CallEvent &Call, const LocationContext *LCtx, ProgramStateRef State)
Create a new state in which the call return value is binded to the call origin expression.
Definition: ExprEngineCallAndReturn.cpp:744
clang::ento::SValBuilder::getConjuredHeapSymbolVal
DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E, const LocationContext *LCtx, unsigned Count)
Conjure a symbol representing heap allocated memory region.
clang::CFG
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1227
clang::AnalyzerOptions::AnalysisPurgeOpt
AnalysisPurgeMode AnalysisPurgeOpt
Definition: AnalyzerOptions.h:197
clang::ASTContext::getSourceManager
SourceManager & getSourceManager()
Definition: ASTContext.h:721
clang::ento::CE_CXXInheritedConstructor
@ CE_CXXInheritedConstructor
Definition: CallEvent.h:67
clang::AnalysisDeclContext::getBlockInvocationContext
const BlockInvocationContext * getBlockInvocationContext(const LocationContext *ParentLC, const BlockDecl *BD, const void *Data)
Obtain a context of the block invocation using its parent context.
Definition: AnalysisDeclContext.cpp:319
clang::ento::AnalysisManager::getAnalysisDeclContext
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
Definition: AnalysisManager.h:121
clang::ento::ExprEngine::processCallExit
void processCallExit(ExplodedNode *Pred)
Generate the sequence of nodes that simulate the call exit and the post visit for CallExpr.
Definition: ExprEngineCallAndReturn.cpp:253
clang::ento::RuntimeDefinition::isForeign
bool isForeign() const
Definition: CallEvent.h:127
clang::ento::RuntimeDefinition
Definition: CallEvent.h:105
clang::CXXMethodDecl::isMoveAssignmentOperator
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Definition: DeclCXX.cpp:2417
REGISTER_TRAIT_WITH_PROGRAMSTATE
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
Declares a program state trait for type Type called Name, and introduce a type named NameTy.
Definition: ProgramStateTrait.h:34
Decl.h
CallEvent.h
clang::ento::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:95
clang::CFGBlock
Represents a single basic block in a source-level CFG.
Definition: CFG.h:578
clang::ento::CE_Block
@ CE_Block
Definition: CallEvent.h:74
clang::CIMK_Constructors
@ CIMK_Constructors
Refers to constructors (implicit or explicit).
Definition: AnalyzerOptions.h:83
REGISTER_MAP_WITH_PROGRAMSTATE
REGISTER_MAP_WITH_PROGRAMSTATE(DynamicDispatchBifurcationMap, const MemRegion *, unsigned) void ExprEngine
Definition: ExprEngineCallAndReturn.cpp:500
clang::ento::AnalysisManager::getAnalyzerOptions
AnalyzerOptions & getAnalyzerOptions() override
Definition: AnalysisManager.h:72
clang::IPAK_DynamicDispatchBifurcate
@ IPAK_DynamicDispatchBifurcate
Enable inlining of dynamically dispatched methods, bifurcate paths when exact type info is unavailabl...
Definition: AnalyzerOptions.h:105
clang::Type::isReferenceType
bool isReferenceType() const
Definition: Type.h:6895
clang::ento::ExprEngine::Inline_Minimal
@ Inline_Minimal
Do minimal inlining of callees.
Definition: ExprEngine.h:133
V
#define V(N, I)
Definition: ASTContext.h:3237
clang::AnalyzerOptions::mayInlineCXXMemberFunction
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const
Returns the option controlling which C++ member functions will be considered for inlining.
Definition: AnalyzerOptions.cpp:109
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
clang::AnalysisDeclContext::getAnalysis
T * getAnalysis()
Definition: AnalysisDeclContext.h:192
clang::OMF_retain
@ OMF_retain
Definition: IdentifierTable.h:717
clang::ento::CXXConstructorCall
Represents a call to a C++ constructor.
Definition: CallEvent.h:874
clang::ento::NodeBuilder
Definition: CoreEngine.h:247
clang::FunctionDecl::isTrivial
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2261
clang::ento::AnalysisManager::isInCodeFile
static bool isInCodeFile(SourceLocation SL, const SourceManager &SM)
Definition: AnalysisManager.h:125
clang::StmtPoint
Definition: ProgramPoint.h:270
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
Node
DynTypedNode Node
Definition: ASTMatchFinder.cpp:68
clang::CFGConstructor
Represents C++ constructor call.
Definition: CFG.h:156
isTrivialObjectAssignment
static bool isTrivialObjectAssignment(const CallEvent &Call)
Definition: ExprEngineCallAndReturn.cpp:1202
hlsl::uint64_t
unsigned long uint64_t
Definition: hlsl_basic_types.h:25
LiveVariables.h
isContainerMethod
static bool isContainerMethod(const ASTContext &Ctx, const FunctionDecl *FD)
Returns true if the given function refers to a method of a C++ container or iterator.
Definition: ExprEngineCallAndReturn.cpp:990
clang::ento::ExprEngine::evalCall
void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, const CallEvent &Call)
Evaluate a call, running pre- and post-call checkers and allowing checkers to be responsible for hand...
Definition: ExprEngineCallAndReturn.cpp:676
CheckerManager.h
clang::ento::RegionAndSymbolInvalidationTraits::setTrait
void setTrait(SymbolRef Sym, InvalidationKinds IK)
Definition: MemRegion.cpp:1732
getInlineFailedState
static ProgramStateRef getInlineFailedState(ProgramStateRef State, const Stmt *CallE)
Definition: ExprEngineCallAndReturn.cpp:592
clang::IPAK_DynamicDispatch
@ IPAK_DynamicDispatch
Enable inlining of dynamically dispatched methods.
Definition: AnalyzerOptions.h:101
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:209
wasDifferentDeclUsedForInlining
static bool wasDifferentDeclUsedForInlining(CallEventRef<> Call, const StackFrameContext *calleeCtx)
Definition: ExprEngineCallAndReturn.cpp:188
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:308
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::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::CallExitEnd
Represents a point when we finish the call exit sequence (for inlined call).
Definition: ProgramPoint.h:687
clang::ento::FunctionSummariesTy::mayInline
Optional< bool > mayInline(const Decl *D)
Definition: FunctionSummary.h:89
clang::ASTContext::getConstantArrayElementCount
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
Definition: ASTContext.cpp:7004
clang::ento::PSK_EscapeOutParameters
@ PSK_EscapeOutParameters
Escape for a new symbol that was generated into a region that the analyzer cannot follow during a con...
Definition: CheckerManager.h:94
clang::ento::CheckerManager::runCheckersForNewAllocator
void runCheckersForNewAllocator(const CXXAllocatorCall &Call, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, bool wasInlined=false)
Run checkers between C++ operator new and constructor calls.
Definition: CheckerManager.cpp:534
clang::Type::getPointeeCXXRecordDecl
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
Definition: Type.cpp:1745
clang::Decl::getCanonicalDecl
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:943
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:598
clang::ento::ExplodedNodeSet::end
iterator end()
Definition: ExplodedGraph.h:495
clang::CXXDestructorDecl
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2703
STATISTIC
STATISTIC(NumOfDynamicDispatchPathSplits, "The # of times we split the path due to imprecise dynamic dispatch info")
clang::CTUPhase1InliningKind::All
@ All
isContainerClass
static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD)
Returns true if the given C++ class is a container or iterator.
Definition: ExprEngineCallAndReturn.cpp:979
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:625
clang::CXXRecordDecl::isDerivedFrom
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Definition: CXXInheritance.cpp:67
clang::AnalysisDeclContext::isInStdNamespace
static bool isInStdNamespace(const Decl *D)
Definition: AnalysisDeclContext.cpp:325
clang::ento::getDynamicElementCount
DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB, QualType Ty)
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:231
clang::CallEnter::getEntry
const CFGBlock * getEntry() const
Returns the entry block in the CFG for the entered function.
Definition: ProgramPoint.h:644
clang::ento::ExprEngine::getCoreEngine
const CoreEngine & getCoreEngine() const
Definition: ExprEngine.h:440
clang::ento::CallEventManager::getCaller
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
Gets an outside caller given a callee context.
Definition: CallEvent.cpp:1398
clang::ento::CE_ObjCMessage
@ CE_ObjCMessage
Definition: CallEvent.h:75
clang::OMF_self
@ OMF_self
Definition: IdentifierTable.h:719
clang::ento::CheckerManager::runCheckersForPreCall
void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)
Run checkers for pre-visiting obj-c messages.
Definition: CheckerManager.h:310
clang::ento::CallEvent::cloneWithState
CallEventRef< T > cloneWithState(ProgramStateRef NewState) const
Returns a copy of this CallEvent, but using the given state.
Definition: CallEvent.h:1354
clang::AnalysisDeclContextManager::getContext
AnalysisDeclContext * getContext(const Decl *D)
Definition: AnalysisDeclContext.cpp:295
clang::ento::CallEventManager::getSimpleCall
CallEventRef getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx)
Definition: CallEvent.cpp:1377
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:282
PrettyStackTraceLocationContext.h
clang::ento::getElementExtent
DefinedOrUnknownSVal getElementExtent(QualType Ty, SValBuilder &SVB)
clang::Type::isObjCObjectPointerType
bool isObjCObjectPointerType() const
Definition: Type.h:7011
clang::CXXRecordDecl::hasMemberName
bool hasMemberName(DeclarationName N) const
Determine whether this class has a member with the given name, possibly in a non-dependent base class...
Definition: CXXInheritance.cpp:396
clang::LocationContext::getAnalysisDeclContext
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
Definition: AnalysisDeclContext.h:244
clang::LocationContext::getParent
const LocationContext * getParent() const
It might return null.
Definition: AnalysisDeclContext.h:247
clang::AnalyzerOptions::getIPAMode
IPAKind getIPAMode() const
Returns the inter-procedural analysis mode.
Definition: AnalyzerOptions.cpp:95
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
clang::PostStmt
Definition: ProgramPoint.h:310
clang::ento::FunctionSummariesTy::markShouldNotInline
void markShouldNotInline(const Decl *D)
Definition: FunctionSummary.h:79
clang::ento::FunctionSummariesTy::bumpNumTimesInlined
void bumpNumTimesInlined(const Decl *D)
Definition: FunctionSummary.h:121
clang::PreStmt
Definition: ProgramPoint.h:294
clang::ento::ExprEngine::getPendingInitLoop
static Optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives the size of the array in the pending ArrayInitLoopExpr.
Definition: ExprEngine.cpp:480
clang::ento::CE_CXXMember
@ CE_CXXMember
Definition: CallEvent.h:61
clang::ento::CallEventManager
Manages the lifetime of CallEvent objects.
Definition: CallEvent.h:1246
clang::AnalysisDeclContext::getCFGBuildOptions
CFG::BuildOptions & getCFGBuildOptions()
Definition: AnalysisDeclContext.h:110
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6883
clang::ento::CE_CXXMemberOperator
@ CE_CXXMemberOperator
Definition: CallEvent.h:62
clang::syntax::NodeRole::Size
@ Size
clang::ento::SValBuilder::evalCast
SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy)
Cast a given SVal to another SVal using given QualType's.
Definition: SValBuilder.cpp:1092
clang::ento::AnalysisManager::options
AnalyzerOptions & options
Definition: AnalysisManager.h:47
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::ento::ProgramStateManager::getCallEventManager
CallEventManager & getCallEventManager()
Definition: ProgramState.h:576
hasMember
static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD, StringRef Name)
Returns true if the given C++ class contains a member with the given name.
Definition: ExprEngineCallAndReturn.cpp:969
getLastStmt
static std::pair< const Stmt *, const CFGBlock * > getLastStmt(const ExplodedNode *Node)
Definition: ExprEngineCallAndReturn.cpp:77
clang::ASTContext::Idents
IdentifierTable & Idents
Definition: ASTContext.h:660
clang::ento::CoreEngine::getCTUWorkList
WorkList * getCTUWorkList() const
Definition: CoreEngine.h:176
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:802
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
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::SimpleProgramPointTag
Definition: ProgramPoint.h:51
clang::StackFrameContext::getCallSite
const Stmt * getCallSite() const
Definition: AnalysisDeclContext.h:325
clang::ento::SValBuilder::makeIntVal
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
Definition: SValBuilder.h:269
clang::FunctionDecl::TK_NonTemplate
@ TK_NonTemplate
Definition: Decl.h:1913
clang::AnalyzerOptions
Stores options for the analyzer from the command line.
Definition: AnalyzerOptions.h:150
State
LineState State
Definition: UnwrappedLineFormatter.cpp:1147
llvm::SaveAndRestore
Definition: LLVM.h:44
clang::ento::ObjCMethodCall
Represents any expression that calls an Objective-C method.
Definition: CallEvent.h:1131
clang::ento::ExprEngine::processBeginOfFunction
void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L)
Called by CoreEngine.
Definition: ExprEngine.cpp:2868
clang::ento::ExprEngine::getCurrentCFGElement
CFGElement getCurrentCFGElement()
Return the CFG element corresponding to the worklist element that is currently being processed by Exp...
Definition: ExprEngine.h:701
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:85
clang::ento::ExprEngine::getAnalysisManager
AnalysisManager & getAnalysisManager()
Definition: ExprEngine.h:205
clang::CallEnter::getCalleeContext
const StackFrameContext * getCalleeContext() const
Definition: ProgramPoint.h:639
clang::AnalyzerOptions::InlineMaxStackDepth
unsigned InlineMaxStackDepth
The inlining stack depth limit.
Definition: AnalyzerOptions.h:247
clang::AnalysisDeclContext::getBody
Stmt * getBody() const
Definition: AnalysisDeclContext.cpp:126
clang::ento::RuntimeDefinition::getDispatchRegion
const MemRegion * getDispatchRegion()
When other definitions are possible, returns the region whose runtime type determines the method defi...
Definition: CallEvent.h:136
clang::ento::ExprEngine::handleConstructionContext
std::pair< ProgramStateRef, SVal > handleConstructionContext(const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)
A convenient wrapper around computeObjectUnderConstruction and updateObjectsUnderConstruction.
Definition: ExprEngine.h:752
clang::DeclarationNameTable::getIdentifier
DeclarationName getIdentifier(const IdentifierInfo *ID)
Create a declaration name that is a simple identifier.
Definition: DeclarationName.h:622
clang::ento::ExplodedNodeSet::begin
iterator begin()
Definition: ExplodedGraph.h:494
clang::ento::CE_CXXAllocator
@ CE_CXXAllocator
Definition: CallEvent.h:70
clang::ento::CoreEngine::enqueue
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
Definition: CoreEngine.cpp:607
clang::CFG::BuildOptions::AddImplicitDtors
bool AddImplicitDtors
Definition: CFG.h:1244
clang::ento::CoreEngine::getWorkList
WorkList * getWorkList() const
Definition: CoreEngine.h:175
ExprEngine.h
clang::ento::CheckerManager::runCheckersForPostObjCMessage
void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
Definition: CheckerManager.h:284
clang::ento::ExprEngine::getStoreManager
StoreManager & getStoreManager()
Definition: ExprEngine.h:419
clang::interp::This
bool This(InterpState &S, CodePtr OpPC)
Definition: Interp.h:1137
clang::ento::FunctionSummariesTy::getNumTimesInlined
unsigned getNumTimesInlined(const Decl *D)
Definition: FunctionSummary.h:114
clang
Definition: CalledOnceCheck.h:17
clang::ento::CallEvent::isVariadic
static bool isVariadic(const Decl *D)
Returns true if the given decl is known to be variadic.
Definition: CallEvent.cpp:378
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:1023
getElementCountOfArrayBeingDestructed
static unsigned getElementCountOfArrayBeingDestructed(const CallEvent &Call, const ProgramStateRef State, SValBuilder &SVB)
Definition: ExprEngineCallAndReturn.cpp:200
clang::AnalysisDeclContext::getDecl
const Decl * getDecl() const
Definition: AnalysisDeclContext.h:106
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:71
clang::ento::CE_CXXDestructor
@ CE_CXXDestructor
Definition: CallEvent.h:63
clang::ento::NodeBuilder::generateNode
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
Definition: CoreEngine.h:300
clang::ento::NodeBuilderContext::getBlock
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
Definition: CoreEngine.h:227
clang::SourceManager::isInSystemHeader
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
Definition: SourceManager.h:1504
clang::ento::RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion
@ TK_DoNotInvalidateSuperRegion
Definition: MemRegion.h:1591
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::PrettyStackTraceLocationContext
While alive, includes the current analysis stack in a crash trace.
Definition: PrettyStackTraceLocationContext.h:28
ConstructionContext.h
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::NamedDecl::getDeclName
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:313
clang::RelaxedLiveVariables
Definition: LiveVariables.h:112
clang::CIMK_Destructors
@ CIMK_Destructors
Refers to destructors (implicit or explicit).
Definition: AnalyzerOptions.h:86
isCXXSharedPtrDtor
static bool isCXXSharedPtrDtor(const FunctionDecl *FD)
Returns true if the given function is the destructor of a class named "shared_ptr".
Definition: ExprEngineCallAndReturn.cpp:999
clang::ento::NodeBuilderContext
Definition: CoreEngine.h:212
clang::ento::ExprEngine::getIndexOfElementToConstruct
static Optional< unsigned > getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives which element is being constructed in a non-POD type array.
Definition: ExprEngine.cpp:508
clang::AnalysisDeclContextManager
Definition: AnalysisDeclContext.h:425
clang::CIMK_MemberFunctions
@ CIMK_MemberFunctions
Refers to regular member function and operator calls.
Definition: AnalyzerOptions.h:77
clang::CallEnter
Represents a point when we begin processing an inlined call.
Definition: ProgramPoint.h:629
clang::ento::ExprEngine::getPendingArrayDestruction
static Optional< unsigned > getPendingArrayDestruction(ProgramStateRef State, const LocationContext *LCtx)
Retreives which element is being destructed in a non-POD type array.
Definition: ExprEngine.cpp:527
clang::CXXBasePaths
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Definition: CXXInheritance.h:117
clang::BlockEdge
Definition: ProgramPoint.h:502
clang::ento::setDynamicExtent
ProgramStateRef setDynamicExtent(ProgramStateRef State, const MemRegion *MR, DefinedOrUnknownSVal Extent, SValBuilder &SVB)
Set the dynamic extent Extent of the region MR.
clang::ento::CE_CXXConstructor
@ CE_CXXConstructor
Definition: CallEvent.h:66
clang::ento::SVal
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:73
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:3456
adjustReturnValue
static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy, StoreManager &StoreMgr)
Adjusts a return value when the called function's return type does not match the caller's expression ...
Definition: ExprEngineCallAndReturn.cpp:129
clang::AnalysisDeclContext::getCFG
CFG * getCFG()
Definition: AnalysisDeclContext.cpp:213
clang::interp::Call
bool Call(InterpState &S, CodePtr &PC, const Function *Func)
Definition: Interp.h:1240
clang::ento::RegionAndSymbolInvalidationTraits
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1570
clang::ProgramPoint::getStackFrame
const StackFrameContext * getStackFrame() const
Definition: ProgramPoint.h:182
clang::Expr
This represents one expression.
Definition: Expr.h:109
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::ento::StmtNodeBuilder::generateNode
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:420
clang::LocationContext::getDecl
const Decl * getDecl() const
Definition: AnalysisDeclContext.h:251
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1904
clang::ento::ExplodedNodeSet
Definition: ExplodedGraph.h:461
clang::ProgramPoint
Definition: ProgramPoint.h:58
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2810
clang::Type::getCanonicalTypeUnqualified
CanQualType getCanonicalTypeUnqualified() const
Definition: CanonicalType.h:214
clang::ProgramPoint::PostStmtPurgeDeadSymbolsKind
@ PostStmtPurgeDeadSymbolsKind
Definition: ProgramPoint.h:65
clang::CXXConstructExpr
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1467
clang::ento::SVal::getType
QualType getType(const ASTContext &) const
Try to get a reasonable type for the given value.
Definition: SVals.cpp:184
clang::CXXConstructExpr::getConstructionKind
ConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
Definition: ExprCXX.h:1587
clang::ento::ExprEngine::defaultEvalCall
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
Definition: ExprEngineCallAndReturn.cpp:1216
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:791
llvm::IntrusiveRefCntPtr< const ProgramState >
clang::ReturnStmt
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:2796
clang::CFG::BuildOptions::AddInitializers
bool AddInitializers
Definition: CFG.h:1243
clang::CXXMethodDecl::getParent
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2098
clang::CXXMethodDecl
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1983
clang::ento::ExprEngine::getCheckerManager
CheckerManager & getCheckerManager() const
Definition: ExprEngine.h:211