clang  7.0.0svn
ExprEngineCallAndReturn.cpp
Go to the documentation of this file.
1 //=-- ExprEngineCallAndReturn.cpp - Support for call/return -----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines ExprEngine's support for calls and returns.
11 //
12 //===----------------------------------------------------------------------===//
13 
17 #include "clang/AST/DeclCXX.h"
21 #include "llvm/ADT/SmallSet.h"
22 #include "llvm/ADT/Statistic.h"
23 #include "llvm/Support/SaveAndRestore.h"
24 
25 using namespace clang;
26 using namespace ento;
27 
28 #define DEBUG_TYPE "ExprEngine"
29 
30 STATISTIC(NumOfDynamicDispatchPathSplits,
31  "The # of times we split the path due to imprecise dynamic dispatch info");
32 
33 STATISTIC(NumInlinedCalls,
34  "The # of times we inlined a call");
35 
36 STATISTIC(NumReachedInlineCountMax,
37  "The # of times we reached inline count maximum");
38 
40  ExplodedNode *Pred) {
41  // Get the entry block in the CFG of the callee.
42  const StackFrameContext *calleeCtx = CE.getCalleeContext();
43  PrettyStackTraceLocationContext CrashInfo(calleeCtx);
44  const CFGBlock *Entry = CE.getEntry();
45 
46  // Validate the CFG.
47  assert(Entry->empty());
48  assert(Entry->succ_size() == 1);
49 
50  // Get the solitary successor.
51  const CFGBlock *Succ = *(Entry->succ_begin());
52 
53  // Construct an edge representing the starting location in the callee.
54  BlockEdge Loc(Entry, Succ, calleeCtx);
55 
56  ProgramStateRef state = Pred->getState();
57 
58  // Construct a new node, notify checkers that analysis of the function has
59  // begun, and add the resultant nodes to the worklist.
60  bool isNew;
61  ExplodedNode *Node = G.getNode(Loc, state, false, &isNew);
62  Node->addPredecessor(Pred, G);
63  if (isNew) {
64  ExplodedNodeSet DstBegin;
65  processBeginOfFunction(BC, Node, DstBegin, Loc);
66  Engine.enqueue(DstBegin);
67  }
68 }
69 
70 // Find the last statement on the path to the exploded node and the
71 // corresponding Block.
72 static std::pair<const Stmt*,
74  const Stmt *S = nullptr;
75  const CFGBlock *Blk = nullptr;
76  const StackFrameContext *SF =
78 
79  // Back up through the ExplodedGraph until we reach a statement node in this
80  // stack frame.
81  while (Node) {
82  const ProgramPoint &PP = Node->getLocation();
83 
84  if (PP.getLocationContext()->getCurrentStackFrame() == SF) {
85  if (Optional<StmtPoint> SP = PP.getAs<StmtPoint>()) {
86  S = SP->getStmt();
87  break;
88  } else if (Optional<CallExitEnd> CEE = PP.getAs<CallExitEnd>()) {
89  S = CEE->getCalleeContext()->getCallSite();
90  if (S)
91  break;
92 
93  // If there is no statement, this is an implicitly-generated call.
94  // We'll walk backwards over it and then continue the loop to find
95  // an actual statement.
97  do {
98  Node = Node->getFirstPred();
99  CE = Node->getLocationAs<CallEnter>();
100  } while (!CE || CE->getCalleeContext() != CEE->getCalleeContext());
101 
102  // Continue searching the graph.
103  } else if (Optional<BlockEdge> BE = PP.getAs<BlockEdge>()) {
104  Blk = BE->getSrc();
105  }
106  } else if (Optional<CallEnter> CE = PP.getAs<CallEnter>()) {
107  // If we reached the CallEnter for this function, it has no statements.
108  if (CE->getCalleeContext() == SF)
109  break;
110  }
111 
112  if (Node->pred_empty())
113  return std::make_pair(nullptr, nullptr);
114 
115  Node = *Node->pred_begin();
116  }
117 
118  return std::make_pair(S, Blk);
119 }
120 
121 /// Adjusts a return value when the called function's return type does not
122 /// match the caller's expression type. This can happen when a dynamic call
123 /// is devirtualized, and the overridding method has a covariant (more specific)
124 /// return type than the parent's method. For C++ objects, this means we need
125 /// to add base casts.
126 static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy,
127  StoreManager &StoreMgr) {
128  // For now, the only adjustments we handle apply only to locations.
129  if (!V.getAs<Loc>())
130  return V;
131 
132  // If the types already match, don't do any unnecessary work.
133  ExpectedTy = ExpectedTy.getCanonicalType();
134  ActualTy = ActualTy.getCanonicalType();
135  if (ExpectedTy == ActualTy)
136  return V;
137 
138  // No adjustment is needed between Objective-C pointer types.
139  if (ExpectedTy->isObjCObjectPointerType() &&
140  ActualTy->isObjCObjectPointerType())
141  return V;
142 
143  // C++ object pointers may need "derived-to-base" casts.
144  const CXXRecordDecl *ExpectedClass = ExpectedTy->getPointeeCXXRecordDecl();
145  const CXXRecordDecl *ActualClass = ActualTy->getPointeeCXXRecordDecl();
146  if (ExpectedClass && ActualClass) {
147  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
148  /*DetectVirtual=*/false);
149  if (ActualClass->isDerivedFrom(ExpectedClass, Paths) &&
150  !Paths.isAmbiguous(ActualTy->getCanonicalTypeUnqualified())) {
151  return StoreMgr.evalDerivedToBase(V, Paths.front());
152  }
153  }
154 
155  // Unfortunately, Objective-C does not enforce that overridden methods have
156  // covariant return types, so we can't assert that that never happens.
157  // Be safe and return UnknownVal().
158  return UnknownVal();
159 }
160 
162  ExplodedNode *Pred,
163  ExplodedNodeSet &Dst) {
164  // Find the last statement in the function and the corresponding basic block.
165  const Stmt *LastSt = nullptr;
166  const CFGBlock *Blk = nullptr;
167  std::tie(LastSt, Blk) = getLastStmt(Pred);
168  if (!Blk || !LastSt) {
169  Dst.Add(Pred);
170  return;
171  }
172 
173  // Here, we destroy the current location context. We use the current
174  // function's entire body as a diagnostic statement, with which the program
175  // point will be associated. However, we only want to use LastStmt as a
176  // reference for what to clean up if it's a ReturnStmt; otherwise, everything
177  // is dead.
178  SaveAndRestore<const NodeBuilderContext *> NodeContextRAII(currBldrCtx, &BC);
179  const LocationContext *LCtx = Pred->getLocationContext();
180  removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt), LCtx,
181  LCtx->getAnalysisDeclContext()->getBody(),
183 }
184 
186  const StackFrameContext *calleeCtx) {
187  const Decl *RuntimeCallee = calleeCtx->getDecl();
188  const Decl *StaticDecl = Call->getDecl();
189  assert(RuntimeCallee);
190  if (!StaticDecl)
191  return true;
192  return RuntimeCallee->getCanonicalDecl() != StaticDecl->getCanonicalDecl();
193 }
194 
195 /// Returns true if the CXXConstructExpr \p E was intended to construct a
196 /// prvalue for the region in \p V.
197 ///
198 /// Note that we can't just test for rvalue vs. glvalue because
199 /// CXXConstructExprs embedded in DeclStmts and initializers are considered
200 /// rvalues by the AST, and the analyzer would like to treat them as lvalues.
201 static bool isTemporaryPRValue(const CXXConstructExpr *E, SVal V) {
202  if (E->isGLValue())
203  return false;
204 
205  const MemRegion *MR = V.getAsRegion();
206  if (!MR)
207  return false;
208 
209  return isa<CXXTempObjectRegion>(MR);
210 }
211 
212 /// The call exit is simulated with a sequence of nodes, which occur between
213 /// CallExitBegin and CallExitEnd. The following operations occur between the
214 /// two program points:
215 /// 1. CallExitBegin (triggers the start of call exit sequence)
216 /// 2. Bind the return value
217 /// 3. Run Remove dead bindings to clean up the dead symbols from the callee.
218 /// 4. CallExitEnd (switch to the caller context)
219 /// 5. PostStmt<CallExpr>
221  // Step 1 CEBNode was generated before the call.
223  const StackFrameContext *calleeCtx =
225 
226  // The parent context might not be a stack frame, so make sure we
227  // look up the first enclosing stack frame.
228  const StackFrameContext *callerCtx =
229  calleeCtx->getParent()->getCurrentStackFrame();
230 
231  const Stmt *CE = calleeCtx->getCallSite();
232  ProgramStateRef state = CEBNode->getState();
233  // Find the last statement in the function and the corresponding basic block.
234  const Stmt *LastSt = nullptr;
235  const CFGBlock *Blk = nullptr;
236  std::tie(LastSt, Blk) = getLastStmt(CEBNode);
237 
238  // Generate a CallEvent /before/ cleaning the state, so that we can get the
239  // correct value for 'this' (if necessary).
241  CallEventRef<> Call = CEMgr.getCaller(calleeCtx, state);
242 
243  // Step 2: generate node with bound return value: CEBNode -> BindedRetNode.
244 
245  // If the callee returns an expression, bind its value to CallExpr.
246  if (CE) {
247  if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
248  const LocationContext *LCtx = CEBNode->getLocationContext();
249  SVal V = state->getSVal(RS, LCtx);
250 
251  // Ensure that the return type matches the type of the returned Expr.
252  if (wasDifferentDeclUsedForInlining(Call, calleeCtx)) {
253  QualType ReturnedTy =
254  CallEvent::getDeclaredResultType(calleeCtx->getDecl());
255  if (!ReturnedTy.isNull()) {
256  if (const Expr *Ex = dyn_cast<Expr>(CE)) {
257  V = adjustReturnValue(V, Ex->getType(), ReturnedTy,
258  getStoreManager());
259  }
260  }
261  }
262 
263  state = state->BindExpr(CE, callerCtx, V);
264  }
265 
266  // Bind the constructed object value to CXXConstructExpr.
267  if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
268  loc::MemRegionVal This =
269  svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
270  SVal ThisV = state->getSVal(This);
271 
272  // If the constructed object is a temporary prvalue, get its bindings.
273  if (isTemporaryPRValue(CCE, ThisV))
274  ThisV = state->getSVal(ThisV.castAs<Loc>());
275 
276  state = state->BindExpr(CCE, callerCtx, ThisV);
277  }
278 
279  if (const auto *CNE = dyn_cast<CXXNewExpr>(CE)) {
280  // We are currently evaluating a CXXNewAllocator CFGElement. It takes a
281  // while to reach the actual CXXNewExpr element from here, so keep the
282  // region for later use.
283  // Additionally cast the return value of the inlined operator new
284  // (which is of type 'void *') to the correct object type.
285  SVal AllocV = state->getSVal(CNE, callerCtx);
286  AllocV = svalBuilder.evalCast(
287  AllocV, CNE->getType(),
288  getContext().getPointerType(getContext().VoidTy));
289 
290  state =
291  setCXXNewAllocatorValue(state, CNE, calleeCtx->getParent(), AllocV);
292  }
293  }
294 
295  // Step 3: BindedRetNode -> CleanedNodes
296  // If we can find a statement and a block in the inlined function, run remove
297  // dead bindings before returning from the call. This is important to ensure
298  // that we report the issues such as leaks in the stack contexts in which
299  // they occurred.
300  ExplodedNodeSet CleanedNodes;
301  if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
302  static SimpleProgramPointTag retValBind("ExprEngine", "Bind Return Value");
303  PostStmt Loc(LastSt, calleeCtx, &retValBind);
304  bool isNew;
305  ExplodedNode *BindedRetNode = G.getNode(Loc, state, false, &isNew);
306  BindedRetNode->addPredecessor(CEBNode, G);
307  if (!isNew)
308  return;
309 
310  NodeBuilderContext Ctx(getCoreEngine(), Blk, BindedRetNode);
311  currBldrCtx = &Ctx;
312  // Here, we call the Symbol Reaper with 0 statement and callee location
313  // context, telling it to clean up everything in the callee's context
314  // (and its children). We use the callee's function body as a diagnostic
315  // statement, with which the program point will be associated.
316  removeDead(BindedRetNode, CleanedNodes, nullptr, calleeCtx,
317  calleeCtx->getAnalysisDeclContext()->getBody(),
319  currBldrCtx = nullptr;
320  } else {
321  CleanedNodes.Add(CEBNode);
322  }
323 
324  for (ExplodedNodeSet::iterator I = CleanedNodes.begin(),
325  E = CleanedNodes.end(); I != E; ++I) {
326 
327  // Step 4: Generate the CallExit and leave the callee's context.
328  // CleanedNodes -> CEENode
329  CallExitEnd Loc(calleeCtx, callerCtx);
330  bool isNew;
331  ProgramStateRef CEEState = (*I == CEBNode) ? state : (*I)->getState();
332 
333  ExplodedNode *CEENode = G.getNode(Loc, CEEState, false, &isNew);
334  CEENode->addPredecessor(*I, G);
335  if (!isNew)
336  return;
337 
338  // Step 5: Perform the post-condition check of the CallExpr and enqueue the
339  // result onto the work list.
340  // CEENode -> Dst -> WorkList
341  NodeBuilderContext Ctx(Engine, calleeCtx->getCallSiteBlock(), CEENode);
342  SaveAndRestore<const NodeBuilderContext*> NBCSave(currBldrCtx,
343  &Ctx);
344  SaveAndRestore<unsigned> CBISave(currStmtIdx, calleeCtx->getIndex());
345 
346  CallEventRef<> UpdatedCall = Call.cloneWithState(CEEState);
347 
348  ExplodedNodeSet DstPostCall;
349  if (const CXXNewExpr *CNE = dyn_cast_or_null<CXXNewExpr>(CE)) {
350  ExplodedNodeSet DstPostPostCallCallback;
351  getCheckerManager().runCheckersForPostCall(DstPostPostCallCallback,
352  CEENode, *UpdatedCall, *this,
353  /*WasInlined=*/true);
354  for (auto I : DstPostPostCallCallback) {
356  CNE, getCXXNewAllocatorValue(I->getState(), CNE,
357  calleeCtx->getParent()),
358  DstPostCall, I, *this,
359  /*WasInlined=*/true);
360  }
361  } else {
362  getCheckerManager().runCheckersForPostCall(DstPostCall, CEENode,
363  *UpdatedCall, *this,
364  /*WasInlined=*/true);
365  }
366  ExplodedNodeSet Dst;
367  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
368  getCheckerManager().runCheckersForPostObjCMessage(Dst, DstPostCall, *Msg,
369  *this,
370  /*WasInlined=*/true);
371  } else if (CE &&
372  !(isa<CXXNewExpr>(CE) && // Called when visiting CXXNewExpr.
374  getCheckerManager().runCheckersForPostStmt(Dst, DstPostCall, CE,
375  *this, /*WasInlined=*/true);
376  } else {
377  Dst.insert(DstPostCall);
378  }
379 
380  // Enqueue the next element in the block.
381  for (ExplodedNodeSet::iterator PSI = Dst.begin(), PSE = Dst.end();
382  PSI != PSE; ++PSI) {
383  Engine.getWorkList()->enqueue(*PSI, calleeCtx->getCallSiteBlock(),
384  calleeCtx->getIndex()+1);
385  }
386  }
387 }
388 
389 void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx,
390  bool &IsRecursive, unsigned &StackDepth) {
391  IsRecursive = false;
392  StackDepth = 0;
393 
394  while (LCtx) {
395  if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LCtx)) {
396  const Decl *DI = SFC->getDecl();
397 
398  // Mark recursive (and mutually recursive) functions and always count
399  // them when measuring the stack depth.
400  if (DI == D) {
401  IsRecursive = true;
402  ++StackDepth;
403  LCtx = LCtx->getParent();
404  continue;
405  }
406 
407  // Do not count the small functions when determining the stack depth.
408  AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI);
409  const CFG *CalleeCFG = CalleeADC->getCFG();
410  if (CalleeCFG->getNumBlockIDs() > AMgr.options.getAlwaysInlineSize())
411  ++StackDepth;
412  }
413  LCtx = LCtx->getParent();
414  }
415 }
416 
417 // The GDM component containing the dynamic dispatch bifurcation info. When
418 // the exact type of the receiver is not known, we want to explore both paths -
419 // one on which we do inline it and the other one on which we don't. This is
420 // done to ensure we do not drop coverage.
421 // This is the map from the receiver region to a bool, specifying either we
422 // consider this region's information precise or not along the given path.
423 namespace {
425  DynamicDispatchModeInlined = 1,
426  DynamicDispatchModeConservative
427  };
428 } // end anonymous namespace
429 
430 REGISTER_TRAIT_WITH_PROGRAMSTATE(DynamicDispatchBifurcationMap,
432  unsigned))
433 
434 bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
435  NodeBuilder &Bldr, ExplodedNode *Pred,
437  assert(D);
438 
439  const LocationContext *CurLC = Pred->getLocationContext();
440  const StackFrameContext *CallerSFC = CurLC->getCurrentStackFrame();
441  const LocationContext *ParentOfCallee = CallerSFC;
442  if (Call.getKind() == CE_Block &&
443  !cast<BlockCall>(Call).isConversionFromLambda()) {
444  const BlockDataRegion *BR = cast<BlockCall>(Call).getBlockRegion();
445  assert(BR && "If we have the block definition we should have its region");
446  AnalysisDeclContext *BlockCtx = AMgr.getAnalysisDeclContext(D);
447  ParentOfCallee = BlockCtx->getBlockInvocationContext(CallerSFC,
448  cast<BlockDecl>(D),
449  BR);
450  }
451 
452  // This may be NULL, but that's fine.
453  const Expr *CallE = Call.getOriginExpr();
454 
455  // Construct a new stack frame for the callee.
456  AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
457  const StackFrameContext *CalleeSFC =
458  CalleeADC->getStackFrame(ParentOfCallee, CallE,
459  currBldrCtx->getBlock(),
460  currStmtIdx);
461 
462  CallEnter Loc(CallE, CalleeSFC, CurLC);
463 
464  // Construct a new state which contains the mapping from actual to
465  // formal arguments.
466  State = State->enterStackFrame(Call, CalleeSFC);
467 
468  bool isNew;
469  if (ExplodedNode *N = G.getNode(Loc, State, false, &isNew)) {
470  N->addPredecessor(Pred, G);
471  if (isNew)
472  Engine.getWorkList()->enqueue(N);
473  }
474 
475  // If we decided to inline the call, the successor has been manually
476  // added onto the work list so remove it from the node builder.
477  Bldr.takeNodes(Pred);
478 
479  NumInlinedCalls++;
480  Engine.FunctionSummaries->bumpNumTimesInlined(D);
481 
482  // Mark the decl as visited.
483  if (VisitedCallees)
484  VisitedCallees->insert(D);
485 
486  return true;
487 }
488 
490  const Stmt *CallE) {
491  const void *ReplayState = State->get<ReplayWithoutInlining>();
492  if (!ReplayState)
493  return nullptr;
494 
495  assert(ReplayState == CallE && "Backtracked to the wrong call.");
496  (void)CallE;
497 
498  return State->remove<ReplayWithoutInlining>();
499 }
500 
502  ExplodedNodeSet &dst) {
503  // Perform the previsit of the CallExpr.
504  ExplodedNodeSet dstPreVisit;
505  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, CE, *this);
506 
507  // Get the call in its initial state. We use this as a template to perform
508  // all the checks.
510  CallEventRef<> CallTemplate
511  = CEMgr.getSimpleCall(CE, Pred->getState(), Pred->getLocationContext());
512 
513  // Evaluate the function call. We try each of the checkers
514  // to see if the can evaluate the function call.
515  ExplodedNodeSet dstCallEvaluated;
516  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
517  I != E; ++I) {
518  evalCall(dstCallEvaluated, *I, *CallTemplate);
519  }
520 
521  // Finally, perform the post-condition check of the CallExpr and store
522  // the created nodes in 'Dst'.
523  // Note that if the call was inlined, dstCallEvaluated will be empty.
524  // The post-CallExpr check will occur in processCallExit.
525  getCheckerManager().runCheckersForPostStmt(dst, dstCallEvaluated, CE,
526  *this);
527 }
528 
530  const CallEvent &Call) {
531  // WARNING: At this time, the state attached to 'Call' may be older than the
532  // state in 'Pred'. This is a minor optimization since CheckerManager will
533  // use an updated CallEvent instance when calling checkers, but if 'Call' is
534  // ever used directly in this function all callers should be updated to pass
535  // the most recent state. (It is probably not worth doing the work here since
536  // for some callers this will not be necessary.)
537 
538  // Run any pre-call checks using the generic call interface.
539  ExplodedNodeSet dstPreVisit;
540  getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred, Call, *this);
541 
542  // Actually evaluate the function call. We try each of the checkers
543  // to see if the can evaluate the function call, and get a callback at
544  // defaultEvalCall if all of them fail.
545  ExplodedNodeSet dstCallEvaluated;
546  getCheckerManager().runCheckersForEvalCall(dstCallEvaluated, dstPreVisit,
547  Call, *this);
548 
549  // Finally, run any post-call checks.
550  getCheckerManager().runCheckersForPostCall(Dst, dstCallEvaluated,
551  Call, *this);
552 }
553 
555  const LocationContext *LCtx,
557  const Expr *E = Call.getOriginExpr();
558  if (!E)
559  return State;
560 
561  // Some method families have known return values.
562  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
563  switch (Msg->getMethodFamily()) {
564  default:
565  break;
566  case OMF_autorelease:
567  case OMF_retain:
568  case OMF_self: {
569  // These methods return their receivers.
570  return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
571  }
572  }
573  } else if (const CXXConstructorCall *C = dyn_cast<CXXConstructorCall>(&Call)){
574  SVal ThisV = C->getCXXThisVal();
575 
576  // If the constructed object is a temporary prvalue, get its bindings.
577  if (isTemporaryPRValue(cast<CXXConstructExpr>(E), ThisV))
578  ThisV = State->getSVal(ThisV.castAs<Loc>());
579 
580  return State->BindExpr(E, LCtx, ThisV);
581  }
582 
583  // Conjure a symbol if the return value is unknown.
584  QualType ResultTy = Call.getResultType();
585  SValBuilder &SVB = getSValBuilder();
586  unsigned Count = currBldrCtx->blockCount();
587 
588  // See if we need to conjure a heap pointer instead of
589  // a regular unknown pointer.
590  bool IsHeapPointer = false;
591  if (const auto *CNE = dyn_cast<CXXNewExpr>(E))
592  if (CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
593  // FIXME: Delegate this to evalCall in MallocChecker?
594  IsHeapPointer = true;
595  }
596 
597  SVal R = IsHeapPointer
598  ? SVB.getConjuredHeapSymbolVal(E, LCtx, Count)
599  : SVB.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count);
600  return State->BindExpr(E, LCtx, R);
601 }
602 
603 // Conservatively evaluate call by invalidating regions and binding
604 // a conjured return value.
605 void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
606  ExplodedNode *Pred,
608  State = Call.invalidateRegions(currBldrCtx->blockCount(), State);
609  State = bindReturnValue(Call, Pred->getLocationContext(), State);
610 
611  // And make the result node.
612  Bldr.generateNode(Call.getProgramPoint(), State, Pred);
613 }
614 
615 ExprEngine::CallInlinePolicy
616 ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred,
617  AnalyzerOptions &Opts,
618  const ExprEngine::EvalCallOptions &CallOpts) {
619  const LocationContext *CurLC = Pred->getLocationContext();
620  const StackFrameContext *CallerSFC = CurLC->getCurrentStackFrame();
621  switch (Call.getKind()) {
622  case CE_Function:
623  case CE_Block:
624  break;
625  case CE_CXXMember:
628  return CIP_DisallowedAlways;
629  break;
630  case CE_CXXConstructor: {
632  return CIP_DisallowedAlways;
633 
634  const CXXConstructorCall &Ctor = cast<CXXConstructorCall>(Call);
635 
636  const CXXConstructExpr *CtorExpr = Ctor.getOriginExpr();
637 
639  const Stmt *ParentExpr = CC ? CC->getTriggerStmt() : nullptr;
640 
641  if (ParentExpr && isa<CXXNewExpr>(ParentExpr) &&
642  !Opts.mayInlineCXXAllocator())
643  return CIP_DisallowedOnce;
644 
645  // FIXME: We don't handle constructors or destructors for arrays properly.
646  // Even once we do, we still need to be careful about implicitly-generated
647  // initializers for array fields in default move/copy constructors.
648  // We still allow construction into ElementRegion targets when they don't
649  // represent array elements.
650  if (CallOpts.IsArrayCtorOrDtor)
651  return CIP_DisallowedOnce;
652 
653  // Inlining constructors requires including initializers in the CFG.
654  const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
655  assert(ADC->getCFGBuildOptions().AddInitializers && "No CFG initializers");
656  (void)ADC;
657 
658  // If the destructor is trivial, it's always safe to inline the constructor.
659  if (Ctor.getDecl()->getParent()->hasTrivialDestructor())
660  break;
661 
662  // For other types, only inline constructors if destructor inlining is
663  // also enabled.
665  return CIP_DisallowedAlways;
666 
667  if (CtorExpr->getConstructionKind() == CXXConstructExpr::CK_Complete) {
668  // If we don't handle temporary destructors, we shouldn't inline
669  // their constructors.
670  if (CallOpts.IsTemporaryCtorOrDtor &&
672  return CIP_DisallowedOnce;
673 
674  // If we did not find the correct this-region, it would be pointless
675  // to inline the constructor. Instead we will simply invalidate
676  // the fake temporary target.
678  return CIP_DisallowedOnce;
679  }
680 
681  break;
682  }
683  case CE_CXXDestructor: {
685  return CIP_DisallowedAlways;
686 
687  // Inlining destructors requires building the CFG correctly.
688  const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
689  assert(ADC->getCFGBuildOptions().AddImplicitDtors && "No CFG destructors");
690  (void)ADC;
691 
692  // FIXME: We don't handle constructors or destructors for arrays properly.
693  if (CallOpts.IsArrayCtorOrDtor)
694  return CIP_DisallowedOnce;
695 
696  // Allow disabling temporary destructor inlining with a separate option.
697  if (CallOpts.IsTemporaryCtorOrDtor && !Opts.mayInlineCXXTemporaryDtors())
698  return CIP_DisallowedOnce;
699 
700  // If we did not find the correct this-region, it would be pointless
701  // to inline the destructor. Instead we will simply invalidate
702  // the fake temporary target.
704  return CIP_DisallowedOnce;
705  break;
706  }
707  case CE_CXXAllocator:
708  if (Opts.mayInlineCXXAllocator())
709  break;
710  // Do not inline allocators until we model deallocators.
711  // This is unfortunate, but basically necessary for smart pointers and such.
712  return CIP_DisallowedAlways;
713  case CE_ObjCMessage:
714  if (!Opts.mayInlineObjCMethod())
715  return CIP_DisallowedAlways;
716  if (!(Opts.getIPAMode() == IPAK_DynamicDispatch ||
718  return CIP_DisallowedAlways;
719  break;
720  }
721 
722  return CIP_Allowed;
723 }
724 
725 /// Returns true if the given C++ class contains a member with the given name.
726 static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD,
727  StringRef Name) {
728  const IdentifierInfo &II = Ctx.Idents.get(Name);
729  DeclarationName DeclName = Ctx.DeclarationNames.getIdentifier(&II);
730  if (!RD->lookup(DeclName).empty())
731  return true;
732 
733  CXXBasePaths Paths(false, false, false);
734  if (RD->lookupInBases(
735  [DeclName](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
736  return CXXRecordDecl::FindOrdinaryMember(Specifier, Path, DeclName);
737  },
738  Paths))
739  return true;
740 
741  return false;
742 }
743 
744 /// Returns true if the given C++ class is a container or iterator.
745 ///
746 /// Our heuristic for this is whether it contains a method named 'begin()' or a
747 /// nested type named 'iterator' or 'iterator_category'.
748 static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD) {
749  return hasMember(Ctx, RD, "begin") ||
750  hasMember(Ctx, RD, "iterator") ||
751  hasMember(Ctx, RD, "iterator_category");
752 }
753 
754 /// Returns true if the given function refers to a method of a C++ container
755 /// or iterator.
756 ///
757 /// We generally do a poor job modeling most containers right now, and might
758 /// prefer not to inline their methods.
759 static bool isContainerMethod(const ASTContext &Ctx,
760  const FunctionDecl *FD) {
761  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
762  return isContainerClass(Ctx, MD->getParent());
763  return false;
764 }
765 
766 /// Returns true if the given function is the destructor of a class named
767 /// "shared_ptr".
768 static bool isCXXSharedPtrDtor(const FunctionDecl *FD) {
769  const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(FD);
770  if (!Dtor)
771  return false;
772 
773  const CXXRecordDecl *RD = Dtor->getParent();
774  if (const IdentifierInfo *II = RD->getDeclName().getAsIdentifierInfo())
775  if (II->isStr("shared_ptr"))
776  return true;
777 
778  return false;
779 }
780 
781 /// Returns true if the function in \p CalleeADC may be inlined in general.
782 ///
783 /// This checks static properties of the function, such as its signature and
784 /// CFG, to determine whether the analyzer should ever consider inlining it,
785 /// in any context.
786 static bool mayInlineDecl(AnalysisDeclContext *CalleeADC,
787  AnalyzerOptions &Opts) {
788  // FIXME: Do not inline variadic calls.
789  if (CallEvent::isVariadic(CalleeADC->getDecl()))
790  return false;
791 
792  // Check certain C++-related inlining policies.
793  ASTContext &Ctx = CalleeADC->getASTContext();
794  if (Ctx.getLangOpts().CPlusPlus) {
795  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeADC->getDecl())) {
796  // Conditionally control the inlining of template functions.
797  if (!Opts.mayInlineTemplateFunctions())
798  if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate)
799  return false;
800 
801  // Conditionally control the inlining of C++ standard library functions.
802  if (!Opts.mayInlineCXXStandardLibrary())
803  if (Ctx.getSourceManager().isInSystemHeader(FD->getLocation()))
805  return false;
806 
807  // Conditionally control the inlining of methods on objects that look
808  // like C++ containers.
809  if (!Opts.mayInlineCXXContainerMethods())
810  if (!Ctx.getSourceManager().isInMainFile(FD->getLocation()))
811  if (isContainerMethod(Ctx, FD))
812  return false;
813 
814  // Conditionally control the inlining of the destructor of C++ shared_ptr.
815  // We don't currently do a good job modeling shared_ptr because we can't
816  // see the reference count, so treating as opaque is probably the best
817  // idea.
818  if (!Opts.mayInlineCXXSharedPtrDtor())
819  if (isCXXSharedPtrDtor(FD))
820  return false;
821  }
822  }
823 
824  // It is possible that the CFG cannot be constructed.
825  // Be safe, and check if the CalleeCFG is valid.
826  const CFG *CalleeCFG = CalleeADC->getCFG();
827  if (!CalleeCFG)
828  return false;
829 
830  // Do not inline large functions.
831  if (CalleeCFG->getNumBlockIDs() > Opts.getMaxInlinableSize())
832  return false;
833 
834  // It is possible that the live variables analysis cannot be
835  // run. If so, bail out.
836  if (!CalleeADC->getAnalysis<RelaxedLiveVariables>())
837  return false;
838 
839  return true;
840 }
841 
842 bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D,
843  const ExplodedNode *Pred,
844  const EvalCallOptions &CallOpts) {
845  if (!D)
846  return false;
847 
849  AnalyzerOptions &Opts = AMgr.options;
851  AnalysisDeclContext *CalleeADC = ADCMgr.getContext(D);
852 
853  // The auto-synthesized bodies are essential to inline as they are
854  // usually small and commonly used. Note: we should do this check early on to
855  // ensure we always inline these calls.
856  if (CalleeADC->isBodyAutosynthesized())
857  return true;
858 
859  if (!AMgr.shouldInlineCall())
860  return false;
861 
862  // Check if this function has been marked as non-inlinable.
863  Optional<bool> MayInline = Engine.FunctionSummaries->mayInline(D);
864  if (MayInline.hasValue()) {
865  if (!MayInline.getValue())
866  return false;
867 
868  } else {
869  // We haven't actually checked the static properties of this function yet.
870  // Do that now, and record our decision in the function summaries.
871  if (mayInlineDecl(CalleeADC, Opts)) {
872  Engine.FunctionSummaries->markMayInline(D);
873  } else {
874  Engine.FunctionSummaries->markShouldNotInline(D);
875  return false;
876  }
877  }
878 
879  // Check if we should inline a call based on its kind.
880  // FIXME: this checks both static and dynamic properties of the call, which
881  // means we're redoing a bit of work that could be cached in the function
882  // summary.
883  CallInlinePolicy CIP = mayInlineCallKind(Call, Pred, Opts, CallOpts);
884  if (CIP != CIP_Allowed) {
885  if (CIP == CIP_DisallowedAlways) {
886  assert(!MayInline.hasValue() || MayInline.getValue());
887  Engine.FunctionSummaries->markShouldNotInline(D);
888  }
889  return false;
890  }
891 
892  const CFG *CalleeCFG = CalleeADC->getCFG();
893 
894  // Do not inline if recursive or we've reached max stack frame count.
895  bool IsRecursive = false;
896  unsigned StackDepth = 0;
897  examineStackFrames(D, Pred->getLocationContext(), IsRecursive, StackDepth);
898  if ((StackDepth >= Opts.InlineMaxStackDepth) &&
899  ((CalleeCFG->getNumBlockIDs() > Opts.getAlwaysInlineSize())
900  || IsRecursive))
901  return false;
902 
903  // Do not inline large functions too many times.
904  if ((Engine.FunctionSummaries->getNumTimesInlined(D) >
905  Opts.getMaxTimesInlineLarge()) &&
906  CalleeCFG->getNumBlockIDs() >=
908  NumReachedInlineCountMax++;
909  return false;
910  }
911 
912  if (HowToInline == Inline_Minimal &&
913  (CalleeCFG->getNumBlockIDs() > Opts.getAlwaysInlineSize()
914  || IsRecursive))
915  return false;
916 
917  return true;
918 }
919 
920 static bool isTrivialObjectAssignment(const CallEvent &Call) {
921  const CXXInstanceCall *ICall = dyn_cast<CXXInstanceCall>(&Call);
922  if (!ICall)
923  return false;
924 
925  const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(ICall->getDecl());
926  if (!MD)
927  return false;
929  return false;
930 
931  return MD->isTrivial();
932 }
933 
935  const CallEvent &CallTemplate,
936  const EvalCallOptions &CallOpts) {
937  // Make sure we have the most recent state attached to the call.
938  ProgramStateRef State = Pred->getState();
939  CallEventRef<> Call = CallTemplate.cloneWithState(State);
940 
941  // Special-case trivial assignment operators.
942  if (isTrivialObjectAssignment(*Call)) {
943  performTrivialCopy(Bldr, Pred, *Call);
944  return;
945  }
946 
947  // Try to inline the call.
948  // The origin expression here is just used as a kind of checksum;
949  // this should still be safe even for CallEvents that don't come from exprs.
950  const Expr *E = Call->getOriginExpr();
951 
952  ProgramStateRef InlinedFailedState = getInlineFailedState(State, E);
953  if (InlinedFailedState) {
954  // If we already tried once and failed, make sure we don't retry later.
955  State = InlinedFailedState;
956  } else {
957  RuntimeDefinition RD = Call->getRuntimeDefinition();
958  const Decl *D = RD.getDecl();
959  if (shouldInlineCall(*Call, D, Pred, CallOpts)) {
960  if (RD.mayHaveOtherDefinitions()) {
962 
963  // Explore with and without inlining the call.
964  if (Options.getIPAMode() == IPAK_DynamicDispatchBifurcate) {
965  BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred);
966  return;
967  }
968 
969  // Don't inline if we're not in any dynamic dispatch mode.
970  if (Options.getIPAMode() != IPAK_DynamicDispatch) {
971  conservativeEvalCall(*Call, Bldr, Pred, State);
972  return;
973  }
974  }
975 
976  // We are not bifurcating and we do have a Decl, so just inline.
977  if (inlineCall(*Call, D, Bldr, Pred, State))
978  return;
979  }
980  }
981 
982  // If we can't inline it, handle the return value and invalidate the regions.
983  conservativeEvalCall(*Call, Bldr, Pred, State);
984 }
985 
986 void ExprEngine::BifurcateCall(const MemRegion *BifurReg,
987  const CallEvent &Call, const Decl *D,
988  NodeBuilder &Bldr, ExplodedNode *Pred) {
989  assert(BifurReg);
990  BifurReg = BifurReg->StripCasts();
991 
992  // Check if we've performed the split already - note, we only want
993  // to split the path once per memory region.
994  ProgramStateRef State = Pred->getState();
995  const unsigned *BState =
996  State->get<DynamicDispatchBifurcationMap>(BifurReg);
997  if (BState) {
998  // If we are on "inline path", keep inlining if possible.
999  if (*BState == DynamicDispatchModeInlined)
1000  if (inlineCall(Call, D, Bldr, Pred, State))
1001  return;
1002  // If inline failed, or we are on the path where we assume we
1003  // don't have enough info about the receiver to inline, conjure the
1004  // return value and invalidate the regions.
1005  conservativeEvalCall(Call, Bldr, Pred, State);
1006  return;
1007  }
1008 
1009  // If we got here, this is the first time we process a message to this
1010  // region, so split the path.
1011  ProgramStateRef IState =
1012  State->set<DynamicDispatchBifurcationMap>(BifurReg,
1013  DynamicDispatchModeInlined);
1014  inlineCall(Call, D, Bldr, Pred, IState);
1015 
1016  ProgramStateRef NoIState =
1017  State->set<DynamicDispatchBifurcationMap>(BifurReg,
1018  DynamicDispatchModeConservative);
1019  conservativeEvalCall(Call, Bldr, Pred, NoIState);
1020 
1021  NumOfDynamicDispatchPathSplits++;
1022 }
1023 
1025  ExplodedNodeSet &Dst) {
1026  ExplodedNodeSet dstPreVisit;
1027  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, RS, *this);
1028 
1029  StmtNodeBuilder B(dstPreVisit, Dst, *currBldrCtx);
1030 
1031  if (RS->getRetValue()) {
1032  for (ExplodedNodeSet::iterator it = dstPreVisit.begin(),
1033  ei = dstPreVisit.end(); it != ei; ++it) {
1034  B.generateNode(RS, *it, (*it)->getState());
1035  }
1036  }
1037 }
AnalysisDeclContextManager & getAnalysisDeclContextManager()
Represents a function declaration or definition.
Definition: Decl.h:1696
unsigned InlineMaxStackDepth
The inlining stack depth limit.
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
Definition: Store.cpp:237
bool empty() const
Definition: CFG.h:674
A (possibly-)qualified type.
Definition: Type.h:653
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:79
CallEventRef< T > cloneWithState(ProgramStateRef NewState) const
Returns a copy of this CallEvent, but using the given state.
const CXXConstructorDecl * getDecl() const override
Definition: CallEvent.h:793
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
Definition: ExprEngine.h:67
Stmt * getBody() const
Get the body of the Declaration.
succ_iterator succ_begin()
Definition: CFG.h:711
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
void processCallExit(ExplodedNode *Pred) override
Generate the sequence of nodes that simulate the call exit and the post visit for CallExpr...
Stmt - This represents one statement.
Definition: Stmt.h:66
This builder class is useful for generating nodes that resulted from visiting a statement.
Definition: CoreEngine.h:350
ProgramPoint getProgramPoint(bool IsPreVisit=false, const ProgramPointTag *Tag=nullptr) const
Returns an appropriate ProgramPoint for this call.
Definition: CallEvent.cpp:196
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool mayInlineCXXTemporaryDtors()
Returns true if C++ temporary destructors should be inlined during analysis.
Represents a point when we begin processing an inlined call.
Definition: ProgramPoint.h:600
static bool mayInlineDecl(AnalysisDeclContext *CalleeADC, AnalyzerOptions &Opts)
Returns true if the function in CalleeADC may be inlined in general.
Manages the lifetime of CallEvent objects.
Definition: CallEvent.h:982
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.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Hints for figuring out of a call should be inlined during evalCall().
Definition: ExprEngine.h:59
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1239
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:65
const NestedNameSpecifier * Specifier
CallEventRef getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx)
Definition: CallEvent.cpp:1141
const ProgramStateRef & getState() const
SVal evalCast(SVal val, QualType castTy, QualType originalType)
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
static bool wasDifferentDeclUsedForInlining(CallEventRef<> Call, const StackFrameContext *calleeCtx)
static std::pair< const Stmt *, const CFGBlock * > getLastStmt(const ExplodedNode *Node)
unsigned succ_size() const
Definition: CFG.h:729
const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Definition: CallEvent.h:225
void takeNodes(const ExplodedNodeSet &S)
Definition: CoreEngine.h:303
ASTContext & getASTContext() const
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the &#39;this&#39; object reference.
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.
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
Definition: CoreEngine.cpp:677
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const LocationContext *LC, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer&#39;s garbage collection - remove dead symbols and bindings from the state...
Definition: ExprEngine.cpp:547
bool mayInlineTemplateFunctions()
Returns whether or not templated functions may be considered for inlining.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Definition: DeclCXX.cpp:1937
const CFGBlock * getEntry() const
Returns the entry block in the CFG for the entered function.
Definition: ProgramPoint.h:615
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:297
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:149
LineState State
AnalysisDeclContext contains the context data for the function or method under analysis.
const Expr * getRetValue() const
Definition: Stmt.cpp:928
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
Optional< T > getLocationAs() const LLVM_LVALUE_FUNCTION
IdentifierTable & Idents
Definition: ASTContext.h:537
STATISTIC(NumOfDynamicDispatchPathSplits, "The # of times we split the path due to imprecise dynamic dispatch info")
bool isGLValue() const
Definition: Expr.h:252
BlockDataRegion - A region that represents a block instance.
Definition: MemRegion.h:657
Represents any expression that calls an Objective-C method.
Definition: CallEvent.h:870
virtual Kind getKind() const =0
Returns the kind of call this is.
static bool isInStdNamespace(const Decl *D)
Returns true if the root namespace of the given declaration is the &#39;std&#39; C++ namespace.
WorkList * getWorkList() const
Definition: CoreEngine.h:153
void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)
Run checkers for pre-visiting obj-c messages.
CFGElement getCurrentCFGElement()
Return the CFG element corresponding to the worklist element that is currently being processed by Exp...
Definition: ExprEngine.h:578
bool mayInlineCXXContainerMethods()
Returns whether or not methods of C++ container objects may be considered for inlining.
const StackFrameContext * getCurrentStackFrame() const
T * getAnalysis()
Return the specified analysis object, lazily running the analysis if necessary.
const LocationContext * getLocationContext() const
const LocationContext * getParent() const
virtual const CXXConstructExpr * getOriginExpr() const
Definition: CallEvent.h:789
unsigned getMinCFGSizeTreatFunctionsAsLarge()
Returns the number of basic blocks a function needs to have to be considered large for the &#39;max-times...
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
const CoreEngine & getCoreEngine() const
Definition: ExprEngine.h:342
ExplodedNode * getFirstPred()
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition: DeclCXX.h:1437
void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
static bool isCXXSharedPtrDtor(const FunctionDecl *FD)
Returns true if the given function is the destructor of a class named "shared_ptr".
static bool isVariadic(const Decl *D)
Returns true if the given decl is known to be variadic.
Definition: CallEvent.cpp:305
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:869
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1536
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
CheckerManager & getCheckerManager() const
Definition: ExprEngine.h:141
void removeDeadOnEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
static bool isTrivialObjectAssignment(const CallEvent &Call)
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.
Represents a non-static C++ member function call, no matter how it is written.
Definition: CallEvent.h:599
static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy, StoreManager &StoreMgr)
Adjusts a return value when the called function&#39;s return type does not match the caller&#39;s expression ...
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:540
CFGBlock - Represents a single basic block in a source-level CFG.
Definition: CFG.h:509
Represents a point when we finish the call exit sequence (for inlined call).
Definition: ProgramPoint.h:658
AnalysisDeclContext * getContext(const Decl *D)
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L) override
Called by CoreEngine.
Expr - This represents one expression.
Definition: Expr.h:106
IPAKind getIPAMode()
Returns the inter-procedural analysis mode.
CFG - Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Definition: CFG.h:926
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that that type refers to...
Definition: Type.cpp:1575
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
Definition: CallEvent.cpp:1163
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2675
AnalyzerOptions & getAnalyzerOptions() override
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition: CoreEngine.h:212
CFGConstructor - Represents C++ constructor call.
Definition: CFG.h:185
void Add(ExplodedNode *N)
Refers to regular member function and operator calls.
bool mayInlineObjCMethod()
Returns true if ObjectiveC inlining is enabled, false otherwise.
IdentifierInfo * getAsIdentifierInfo() const
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn&#39;t a simple identifier.
Refers to constructors (implicit or explicit).
void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &CE, ExprEngine &Eng)
Run checkers for evaluating a call.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Definition: ExprEngine.h:137
Traits for storing the call processing policy inside GDM.
Definition: ExprEngine.h:740
REGISTER_TRAIT_WITH_PROGRAMSTATE(DynamicDispatchBifurcationMap, CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, unsigned)) bool ExprEngine
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:1417
bool isBodyAutosynthesized() const
Checks if the body of the Decl is generated by the BodyFarm.
static bool isTemporaryPRValue(const CXXConstructExpr *E, SVal V)
Returns true if the CXXConstructExpr E was intended to construct a prvalue for the region in V...
ExplodedNode * getNode(const ProgramPoint &L, ProgramStateRef State, bool IsSink=false, bool *IsNew=nullptr)
Retrieve the node associated with a (Location,State) pair, where the &#39;Location&#39; is a ProgramPoint in ...
const StackFrameContext * getStackFrame(LocationContext const *Parent, const Stmt *S, const CFGBlock *Blk, unsigned Idx)
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2017
Enable inlining of dynamically dispatched methods.
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:719
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:100
While alive, includes the current analysis stack in a crash trace.
CanQualType getCanonicalTypeUnqualified() const
const MemRegion * StripCasts(bool StripBaseCasts=true) const
Definition: MemRegion.cpp:1119
void runCheckersForNewAllocator(const CXXNewExpr *NE, SVal Target, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, bool wasInlined=false)
Run checkers between C++ operator new and constructor calls.
Defines the runtime definition of the called function.
Definition: CallEvent.h:104
QualType getCanonicalType() const
Definition: Type.h:5763
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique &#39;name&#39;.
const FunctionDecl * getDecl() const override
Definition: CallEvent.cpp:455
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
AnalysisManager & getAnalysisManager() override
Definition: ExprEngine.h:139
const MemRegion * getAsRegion() const
Definition: SVals.cpp:140
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Definition: ExprCXX.h:1845
CallEventManager & getCallEventManager()
Definition: ProgramState.h:539
void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, const CallEvent &Call)
Evaluate a call, running pre- and post-call checks and allowing checkers to be responsible for handli...
bool mayInlineCXXStandardLibrary()
Returns whether or not C++ standard library functions may be considered for inlining.
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2019
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...
Definition: ExprEngine.h:62
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:63
DeclarationName getIdentifier(const IdentifierInfo *ID)
getIdentifier - Create a declaration name that is a simple identifier.
#define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value)
Helper for registering a map trait.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
const Decl * getDecl() const
bool isObjCObjectPointerType() const
Definition: Type.h:6045
Do minimal inlining of callees.
Definition: ExprEngine.h:55
unsigned getNumBlockIDs() const
getNumBlockIDs - Returns the total number of BlockIDs allocated (which start at 0).
Definition: CFG.h:1091
Refers to destructors (implicit or explicit).
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E, const LocationContext *LCtx, unsigned Count)
Conjure a symbol representing heap allocated memory region.
static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD)
Returns true if the given C++ class is a container or iterator.
const MemRegion * getDispatchRegion()
When other definitions are possible, returns the region whose runtime type determines the method defi...
Definition: CallEvent.h:128
void insert(const ExplodedNodeSet &S)
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
Definition: CFG.h:105
ast_type_traits::DynTypedNode Node
static ProgramStateRef getInlineFailedState(ProgramStateRef State, const Stmt *CallE)
Dataflow Directional Tag Classes.
CFG::BuildOptions & getCFGBuildOptions()
Return the build options used to construct the CFG.
SValBuilder & getSValBuilder()
Definition: ExprEngine.h:145
StoreManager & getStoreManager()
Definition: ExprEngine.h:322
const StackFrameContext * getCalleeContext() const
Definition: ProgramPoint.h:610
DeclarationName - The name of a declaration.
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
Definition: DeclCXX.h:2140
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition: DeclCXX.cpp:1916
bool mayHaveOtherDefinitions()
Check if the definition we have is precise.
Definition: CallEvent.h:124
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:140
ProgramStateManager & getStateManager() override
Definition: ExprEngine.h:320
const Decl * getDecl() const
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths, bool LookupInDependent=false) const
Look for entities within the base classes of this C++ class, transitively searching all base class su...
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition: SVals.h:92
bool includeTemporaryDtorsInCFG()
Returns whether or not the destructors for C++ temporary objects should be included in the CFG...
const LocationContext * getLocationContext() const
Definition: ProgramPoint.h:180
static QualType getDeclaredResultType(const Decl *D)
Returns the result type of a function or method declaration.
Definition: CallEvent.cpp:276
CXXBasePath & front()
Represents a base class of a C++ class.
Definition: DeclCXX.h:191
SourceManager & getSourceManager()
Definition: ASTContext.h:643
QualType getResultType() const
Returns the result type, adjusted for references.
Definition: CallEvent.cpp:31
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
Definition: CoreEngine.h:265
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Represents a C++ struct/union/class.
Definition: DeclCXX.h:299
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K)
Returns the option controlling which C++ member functions will be considered for inlining.
pred_iterator pred_begin()
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2218
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:380
unsigned getMaxTimesInlineLarge()
Returns the maximum times a large function could be inlined.
ProgramStateRef invalidateRegions(unsigned BlockCount, ProgramStateRef Orig=nullptr) const
Returns a new state with all argument regions invalidated.
Definition: CallEvent.cpp:156
virtual void enqueue(const WorkListUnit &U)=0
const BlockInvocationContext * getBlockInvocationContext(const LocationContext *parent, const BlockDecl *BD, const void *ContextData)
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool mayInlineCXXAllocator()
Returns whether or not allocator call may be considered for inlining.
AnalysisPurgeMode AnalysisPurgeOpt
Enable inlining of dynamically dispatched methods, bifurcate paths when exact type info is unavailabl...
bool mayInlineCXXSharedPtrDtor()
Returns whether or not the destructor of C++ &#39;shared_ptr&#39; may be considered for inlining.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
Definition: ProgramPoint.h:152
AnalysisDeclContext * getAnalysisDeclContext() const
Represents a call to a C++ constructor.
Definition: CallEvent.h:765
const LangOptions & getLangOpts() const
Definition: ASTContext.h:688
void processCallEnter(NodeBuilderContext &BC, CallEnter CE, ExplodedNode *Pred) override
Generate the entry node of the callee.
CallEventRef< T > cloneWithState(ProgramStateRef State) const
Definition: CallEvent.h:85