clang  6.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"
18 #include "clang/AST/ParentMap.h"
22 #include "llvm/ADT/SmallSet.h"
23 #include "llvm/ADT/Statistic.h"
24 #include "llvm/Support/SaveAndRestore.h"
25 
26 using namespace clang;
27 using namespace ento;
28 
29 #define DEBUG_TYPE "ExprEngine"
30 
31 STATISTIC(NumOfDynamicDispatchPathSplits,
32  "The # of times we split the path due to imprecise dynamic dispatch info");
33 
34 STATISTIC(NumInlinedCalls,
35  "The # of times we inlined a call");
36 
37 STATISTIC(NumReachedInlineCountMax,
38  "The # of times we reached inline count maximum");
39 
41  ExplodedNode *Pred) {
42  // Get the entry block in the CFG of the callee.
43  const StackFrameContext *calleeCtx = CE.getCalleeContext();
44  PrettyStackTraceLocationContext CrashInfo(calleeCtx);
45  const CFGBlock *Entry = CE.getEntry();
46 
47  // Validate the CFG.
48  assert(Entry->empty());
49  assert(Entry->succ_size() == 1);
50 
51  // Get the solitary successor.
52  const CFGBlock *Succ = *(Entry->succ_begin());
53 
54  // Construct an edge representing the starting location in the callee.
55  BlockEdge Loc(Entry, Succ, calleeCtx);
56 
57  ProgramStateRef state = Pred->getState();
58 
59  // Construct a new node, notify checkers that analysis of the function has
60  // begun, and add the resultant nodes to the worklist.
61  bool isNew;
62  ExplodedNode *Node = G.getNode(Loc, state, false, &isNew);
63  Node->addPredecessor(Pred, G);
64  if (isNew) {
65  ExplodedNodeSet DstBegin;
66  processBeginOfFunction(BC, Node, DstBegin, Loc);
67  Engine.enqueue(DstBegin);
68  }
69 }
70 
71 // Find the last statement on the path to the exploded node and the
72 // corresponding Block.
73 static std::pair<const Stmt*,
75  const Stmt *S = nullptr;
76  const CFGBlock *Blk = nullptr;
77  const StackFrameContext *SF =
79 
80  // Back up through the ExplodedGraph until we reach a statement node in this
81  // stack frame.
82  while (Node) {
83  const ProgramPoint &PP = Node->getLocation();
84 
85  if (PP.getLocationContext()->getCurrentStackFrame() == SF) {
86  if (Optional<StmtPoint> SP = PP.getAs<StmtPoint>()) {
87  S = SP->getStmt();
88  break;
89  } else if (Optional<CallExitEnd> CEE = PP.getAs<CallExitEnd>()) {
90  S = CEE->getCalleeContext()->getCallSite();
91  if (S)
92  break;
93 
94  // If there is no statement, this is an implicitly-generated call.
95  // We'll walk backwards over it and then continue the loop to find
96  // an actual statement.
98  do {
99  Node = Node->getFirstPred();
100  CE = Node->getLocationAs<CallEnter>();
101  } while (!CE || CE->getCalleeContext() != CEE->getCalleeContext());
102 
103  // Continue searching the graph.
104  } else if (Optional<BlockEdge> BE = PP.getAs<BlockEdge>()) {
105  Blk = BE->getSrc();
106  }
107  } else if (Optional<CallEnter> CE = PP.getAs<CallEnter>()) {
108  // If we reached the CallEnter for this function, it has no statements.
109  if (CE->getCalleeContext() == SF)
110  break;
111  }
112 
113  if (Node->pred_empty())
114  return std::make_pair(nullptr, nullptr);
115 
116  Node = *Node->pred_begin();
117  }
118 
119  return std::make_pair(S, Blk);
120 }
121 
122 /// Adjusts a return value when the called function's return type does not
123 /// match the caller's expression type. This can happen when a dynamic call
124 /// is devirtualized, and the overridding method has a covariant (more specific)
125 /// return type than the parent's method. For C++ objects, this means we need
126 /// to add base casts.
127 static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy,
128  StoreManager &StoreMgr) {
129  // For now, the only adjustments we handle apply only to locations.
130  if (!V.getAs<Loc>())
131  return V;
132 
133  // If the types already match, don't do any unnecessary work.
134  ExpectedTy = ExpectedTy.getCanonicalType();
135  ActualTy = ActualTy.getCanonicalType();
136  if (ExpectedTy == ActualTy)
137  return V;
138 
139  // No adjustment is needed between Objective-C pointer types.
140  if (ExpectedTy->isObjCObjectPointerType() &&
141  ActualTy->isObjCObjectPointerType())
142  return V;
143 
144  // C++ object pointers may need "derived-to-base" casts.
145  const CXXRecordDecl *ExpectedClass = ExpectedTy->getPointeeCXXRecordDecl();
146  const CXXRecordDecl *ActualClass = ActualTy->getPointeeCXXRecordDecl();
147  if (ExpectedClass && ActualClass) {
148  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
149  /*DetectVirtual=*/false);
150  if (ActualClass->isDerivedFrom(ExpectedClass, Paths) &&
151  !Paths.isAmbiguous(ActualTy->getCanonicalTypeUnqualified())) {
152  return StoreMgr.evalDerivedToBase(V, Paths.front());
153  }
154  }
155 
156  // Unfortunately, Objective-C does not enforce that overridden methods have
157  // covariant return types, so we can't assert that that never happens.
158  // Be safe and return UnknownVal().
159  return UnknownVal();
160 }
161 
163  ExplodedNode *Pred,
164  ExplodedNodeSet &Dst) {
165  // Find the last statement in the function and the corresponding basic block.
166  const Stmt *LastSt = nullptr;
167  const CFGBlock *Blk = nullptr;
168  std::tie(LastSt, Blk) = getLastStmt(Pred);
169  if (!Blk || !LastSt) {
170  Dst.Add(Pred);
171  return;
172  }
173 
174  // Here, we destroy the current location context. We use the current
175  // function's entire body as a diagnostic statement, with which the program
176  // point will be associated. However, we only want to use LastStmt as a
177  // reference for what to clean up if it's a ReturnStmt; otherwise, everything
178  // is dead.
179  SaveAndRestore<const NodeBuilderContext *> NodeContextRAII(currBldrCtx, &BC);
180  const LocationContext *LCtx = Pred->getLocationContext();
181  removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt), LCtx,
182  LCtx->getAnalysisDeclContext()->getBody(),
184 }
185 
187  const StackFrameContext *calleeCtx) {
188  const Decl *RuntimeCallee = calleeCtx->getDecl();
189  const Decl *StaticDecl = Call->getDecl();
190  assert(RuntimeCallee);
191  if (!StaticDecl)
192  return true;
193  return RuntimeCallee->getCanonicalDecl() != StaticDecl->getCanonicalDecl();
194 }
195 
196 /// Returns true if the CXXConstructExpr \p E was intended to construct a
197 /// prvalue for the region in \p V.
198 ///
199 /// Note that we can't just test for rvalue vs. glvalue because
200 /// CXXConstructExprs embedded in DeclStmts and initializers are considered
201 /// rvalues by the AST, and the analyzer would like to treat them as lvalues.
202 static bool isTemporaryPRValue(const CXXConstructExpr *E, SVal V) {
203  if (E->isGLValue())
204  return false;
205 
206  const MemRegion *MR = V.getAsRegion();
207  if (!MR)
208  return false;
209 
210  return isa<CXXTempObjectRegion>(MR);
211 }
212 
213 /// The call exit is simulated with a sequence of nodes, which occur between
214 /// CallExitBegin and CallExitEnd. The following operations occur between the
215 /// two program points:
216 /// 1. CallExitBegin (triggers the start of call exit sequence)
217 /// 2. Bind the return value
218 /// 3. Run Remove dead bindings to clean up the dead symbols from the callee.
219 /// 4. CallExitEnd (switch to the caller context)
220 /// 5. PostStmt<CallExpr>
222  // Step 1 CEBNode was generated before the call.
224  const StackFrameContext *calleeCtx =
226 
227  // The parent context might not be a stack frame, so make sure we
228  // look up the first enclosing stack frame.
229  const StackFrameContext *callerCtx =
230  calleeCtx->getParent()->getCurrentStackFrame();
231 
232  const Stmt *CE = calleeCtx->getCallSite();
233  ProgramStateRef state = CEBNode->getState();
234  // Find the last statement in the function and the corresponding basic block.
235  const Stmt *LastSt = nullptr;
236  const CFGBlock *Blk = nullptr;
237  std::tie(LastSt, Blk) = getLastStmt(CEBNode);
238 
239  // Generate a CallEvent /before/ cleaning the state, so that we can get the
240  // correct value for 'this' (if necessary).
242  CallEventRef<> Call = CEMgr.getCaller(calleeCtx, state);
243 
244  // Step 2: generate node with bound return value: CEBNode -> BindedRetNode.
245 
246  // If the callee returns an expression, bind its value to CallExpr.
247  if (CE) {
248  if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
249  const LocationContext *LCtx = CEBNode->getLocationContext();
250  SVal V = state->getSVal(RS, LCtx);
251 
252  // Ensure that the return type matches the type of the returned Expr.
253  if (wasDifferentDeclUsedForInlining(Call, calleeCtx)) {
254  QualType ReturnedTy =
255  CallEvent::getDeclaredResultType(calleeCtx->getDecl());
256  if (!ReturnedTy.isNull()) {
257  if (const Expr *Ex = dyn_cast<Expr>(CE)) {
258  V = adjustReturnValue(V, Ex->getType(), ReturnedTy,
259  getStoreManager());
260  }
261  }
262  }
263 
264  state = state->BindExpr(CE, callerCtx, V);
265  }
266 
267  // Bind the constructed object value to CXXConstructExpr.
268  if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
269  loc::MemRegionVal This =
270  svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
271  SVal ThisV = state->getSVal(This);
272 
273  // If the constructed object is a temporary prvalue, get its bindings.
274  if (isTemporaryPRValue(CCE, ThisV))
275  ThisV = state->getSVal(ThisV.castAs<Loc>());
276 
277  state = state->BindExpr(CCE, callerCtx, ThisV);
278  }
279  }
280 
281  // Step 3: BindedRetNode -> CleanedNodes
282  // If we can find a statement and a block in the inlined function, run remove
283  // dead bindings before returning from the call. This is important to ensure
284  // that we report the issues such as leaks in the stack contexts in which
285  // they occurred.
286  ExplodedNodeSet CleanedNodes;
287  if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
288  static SimpleProgramPointTag retValBind("ExprEngine", "Bind Return Value");
289  PostStmt Loc(LastSt, calleeCtx, &retValBind);
290  bool isNew;
291  ExplodedNode *BindedRetNode = G.getNode(Loc, state, false, &isNew);
292  BindedRetNode->addPredecessor(CEBNode, G);
293  if (!isNew)
294  return;
295 
296  NodeBuilderContext Ctx(getCoreEngine(), Blk, BindedRetNode);
297  currBldrCtx = &Ctx;
298  // Here, we call the Symbol Reaper with 0 statement and callee location
299  // context, telling it to clean up everything in the callee's context
300  // (and its children). We use the callee's function body as a diagnostic
301  // statement, with which the program point will be associated.
302  removeDead(BindedRetNode, CleanedNodes, nullptr, calleeCtx,
303  calleeCtx->getAnalysisDeclContext()->getBody(),
305  currBldrCtx = nullptr;
306  } else {
307  CleanedNodes.Add(CEBNode);
308  }
309 
310  for (ExplodedNodeSet::iterator I = CleanedNodes.begin(),
311  E = CleanedNodes.end(); I != E; ++I) {
312 
313  // Step 4: Generate the CallExit and leave the callee's context.
314  // CleanedNodes -> CEENode
315  CallExitEnd Loc(calleeCtx, callerCtx);
316  bool isNew;
317  ProgramStateRef CEEState = (*I == CEBNode) ? state : (*I)->getState();
318  ExplodedNode *CEENode = G.getNode(Loc, CEEState, false, &isNew);
319  CEENode->addPredecessor(*I, G);
320  if (!isNew)
321  return;
322 
323  // Step 5: Perform the post-condition check of the CallExpr and enqueue the
324  // result onto the work list.
325  // CEENode -> Dst -> WorkList
326  NodeBuilderContext Ctx(Engine, calleeCtx->getCallSiteBlock(), CEENode);
327  SaveAndRestore<const NodeBuilderContext*> NBCSave(currBldrCtx,
328  &Ctx);
329  SaveAndRestore<unsigned> CBISave(currStmtIdx, calleeCtx->getIndex());
330 
331  CallEventRef<> UpdatedCall = Call.cloneWithState(CEEState);
332 
333  ExplodedNodeSet DstPostCall;
334  getCheckerManager().runCheckersForPostCall(DstPostCall, CEENode,
335  *UpdatedCall, *this,
336  /*WasInlined=*/true);
337 
338  ExplodedNodeSet Dst;
339  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
340  getCheckerManager().runCheckersForPostObjCMessage(Dst, DstPostCall, *Msg,
341  *this,
342  /*WasInlined=*/true);
343  } else if (CE) {
344  getCheckerManager().runCheckersForPostStmt(Dst, DstPostCall, CE,
345  *this, /*WasInlined=*/true);
346  } else {
347  Dst.insert(DstPostCall);
348  }
349 
350  // Enqueue the next element in the block.
351  for (ExplodedNodeSet::iterator PSI = Dst.begin(), PSE = Dst.end();
352  PSI != PSE; ++PSI) {
353  Engine.getWorkList()->enqueue(*PSI, calleeCtx->getCallSiteBlock(),
354  calleeCtx->getIndex()+1);
355  }
356  }
357 }
358 
359 void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx,
360  bool &IsRecursive, unsigned &StackDepth) {
361  IsRecursive = false;
362  StackDepth = 0;
363 
364  while (LCtx) {
365  if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LCtx)) {
366  const Decl *DI = SFC->getDecl();
367 
368  // Mark recursive (and mutually recursive) functions and always count
369  // them when measuring the stack depth.
370  if (DI == D) {
371  IsRecursive = true;
372  ++StackDepth;
373  LCtx = LCtx->getParent();
374  continue;
375  }
376 
377  // Do not count the small functions when determining the stack depth.
378  AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI);
379  const CFG *CalleeCFG = CalleeADC->getCFG();
380  if (CalleeCFG->getNumBlockIDs() > AMgr.options.getAlwaysInlineSize())
381  ++StackDepth;
382  }
383  LCtx = LCtx->getParent();
384  }
385 }
386 
387 // The GDM component containing the dynamic dispatch bifurcation info. When
388 // the exact type of the receiver is not known, we want to explore both paths -
389 // one on which we do inline it and the other one on which we don't. This is
390 // done to ensure we do not drop coverage.
391 // This is the map from the receiver region to a bool, specifying either we
392 // consider this region's information precise or not along the given path.
393 namespace {
395  DynamicDispatchModeInlined = 1,
396  DynamicDispatchModeConservative
397  };
398 } // end anonymous namespace
399 
400 REGISTER_TRAIT_WITH_PROGRAMSTATE(DynamicDispatchBifurcationMap,
402  unsigned))
403 
404 bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
405  NodeBuilder &Bldr, ExplodedNode *Pred,
407  assert(D);
408 
409  const LocationContext *CurLC = Pred->getLocationContext();
410  const StackFrameContext *CallerSFC = CurLC->getCurrentStackFrame();
411  const LocationContext *ParentOfCallee = CallerSFC;
412  if (Call.getKind() == CE_Block &&
413  !cast<BlockCall>(Call).isConversionFromLambda()) {
414  const BlockDataRegion *BR = cast<BlockCall>(Call).getBlockRegion();
415  assert(BR && "If we have the block definition we should have its region");
416  AnalysisDeclContext *BlockCtx = AMgr.getAnalysisDeclContext(D);
417  ParentOfCallee = BlockCtx->getBlockInvocationContext(CallerSFC,
418  cast<BlockDecl>(D),
419  BR);
420  }
421 
422  // This may be NULL, but that's fine.
423  const Expr *CallE = Call.getOriginExpr();
424 
425  // Construct a new stack frame for the callee.
426  AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
427  const StackFrameContext *CalleeSFC =
428  CalleeADC->getStackFrame(ParentOfCallee, CallE,
429  currBldrCtx->getBlock(),
430  currStmtIdx);
431 
432  CallEnter Loc(CallE, CalleeSFC, CurLC);
433 
434  // Construct a new state which contains the mapping from actual to
435  // formal arguments.
436  State = State->enterStackFrame(Call, CalleeSFC);
437 
438  bool isNew;
439  if (ExplodedNode *N = G.getNode(Loc, State, false, &isNew)) {
440  N->addPredecessor(Pred, G);
441  if (isNew)
442  Engine.getWorkList()->enqueue(N);
443  }
444 
445  // If we decided to inline the call, the successor has been manually
446  // added onto the work list so remove it from the node builder.
447  Bldr.takeNodes(Pred);
448 
449  NumInlinedCalls++;
450  Engine.FunctionSummaries->bumpNumTimesInlined(D);
451 
452  // Mark the decl as visited.
453  if (VisitedCallees)
454  VisitedCallees->insert(D);
455 
456  return true;
457 }
458 
460  const Stmt *CallE) {
461  const void *ReplayState = State->get<ReplayWithoutInlining>();
462  if (!ReplayState)
463  return nullptr;
464 
465  assert(ReplayState == CallE && "Backtracked to the wrong call.");
466  (void)CallE;
467 
468  return State->remove<ReplayWithoutInlining>();
469 }
470 
472  ExplodedNodeSet &dst) {
473  // Perform the previsit of the CallExpr.
474  ExplodedNodeSet dstPreVisit;
475  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, CE, *this);
476 
477  // Get the call in its initial state. We use this as a template to perform
478  // all the checks.
480  CallEventRef<> CallTemplate
481  = CEMgr.getSimpleCall(CE, Pred->getState(), Pred->getLocationContext());
482 
483  // Evaluate the function call. We try each of the checkers
484  // to see if the can evaluate the function call.
485  ExplodedNodeSet dstCallEvaluated;
486  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
487  I != E; ++I) {
488  evalCall(dstCallEvaluated, *I, *CallTemplate);
489  }
490 
491  // Finally, perform the post-condition check of the CallExpr and store
492  // the created nodes in 'Dst'.
493  // Note that if the call was inlined, dstCallEvaluated will be empty.
494  // The post-CallExpr check will occur in processCallExit.
495  getCheckerManager().runCheckersForPostStmt(dst, dstCallEvaluated, CE,
496  *this);
497 }
498 
500  const CallEvent &Call) {
501  // WARNING: At this time, the state attached to 'Call' may be older than the
502  // state in 'Pred'. This is a minor optimization since CheckerManager will
503  // use an updated CallEvent instance when calling checkers, but if 'Call' is
504  // ever used directly in this function all callers should be updated to pass
505  // the most recent state. (It is probably not worth doing the work here since
506  // for some callers this will not be necessary.)
507 
508  // Run any pre-call checks using the generic call interface.
509  ExplodedNodeSet dstPreVisit;
510  getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred, Call, *this);
511 
512  // Actually evaluate the function call. We try each of the checkers
513  // to see if the can evaluate the function call, and get a callback at
514  // defaultEvalCall if all of them fail.
515  ExplodedNodeSet dstCallEvaluated;
516  getCheckerManager().runCheckersForEvalCall(dstCallEvaluated, dstPreVisit,
517  Call, *this);
518 
519  // Finally, run any post-call checks.
520  getCheckerManager().runCheckersForPostCall(Dst, dstCallEvaluated,
521  Call, *this);
522 }
523 
525  const LocationContext *LCtx,
527  const Expr *E = Call.getOriginExpr();
528  if (!E)
529  return State;
530 
531  // Some method families have known return values.
532  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
533  switch (Msg->getMethodFamily()) {
534  default:
535  break;
536  case OMF_autorelease:
537  case OMF_retain:
538  case OMF_self: {
539  // These methods return their receivers.
540  return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
541  }
542  }
543  } else if (const CXXConstructorCall *C = dyn_cast<CXXConstructorCall>(&Call)){
544  SVal ThisV = C->getCXXThisVal();
545 
546  // If the constructed object is a temporary prvalue, get its bindings.
547  if (isTemporaryPRValue(cast<CXXConstructExpr>(E), ThisV))
548  ThisV = State->getSVal(ThisV.castAs<Loc>());
549 
550  return State->BindExpr(E, LCtx, ThisV);
551  }
552 
553  // Conjure a symbol if the return value is unknown.
554  QualType ResultTy = Call.getResultType();
555  SValBuilder &SVB = getSValBuilder();
556  unsigned Count = currBldrCtx->blockCount();
557  SVal R = SVB.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count);
558  return State->BindExpr(E, LCtx, R);
559 }
560 
561 // Conservatively evaluate call by invalidating regions and binding
562 // a conjured return value.
563 void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
564  ExplodedNode *Pred,
566  State = Call.invalidateRegions(currBldrCtx->blockCount(), State);
567  State = bindReturnValue(Call, Pred->getLocationContext(), State);
568 
569  // And make the result node.
570  Bldr.generateNode(Call.getProgramPoint(), State, Pred);
571 }
572 
577 };
578 
580  const ExplodedNode *Pred,
581  AnalyzerOptions &Opts) {
582  const LocationContext *CurLC = Pred->getLocationContext();
583  const StackFrameContext *CallerSFC = CurLC->getCurrentStackFrame();
584  switch (Call.getKind()) {
585  case CE_Function:
586  case CE_Block:
587  break;
588  case CE_CXXMember:
591  return CIP_DisallowedAlways;
592  break;
593  case CE_CXXConstructor: {
595  return CIP_DisallowedAlways;
596 
597  const CXXConstructorCall &Ctor = cast<CXXConstructorCall>(Call);
598 
599  // FIXME: We don't handle constructors or destructors for arrays properly.
600  // Even once we do, we still need to be careful about implicitly-generated
601  // initializers for array fields in default move/copy constructors.
602  const MemRegion *Target = Ctor.getCXXThisVal().getAsRegion();
603  if (Target && isa<ElementRegion>(Target))
604  return CIP_DisallowedOnce;
605 
606  // FIXME: This is a hack. We don't use the correct region for a new
607  // expression, so if we inline the constructor its result will just be
608  // thrown away. This short-term hack is tracked in <rdar://problem/12180598>
609  // and the longer-term possible fix is discussed in PR12014.
610  const CXXConstructExpr *CtorExpr = Ctor.getOriginExpr();
611  if (const Stmt *Parent = CurLC->getParentMap().getParent(CtorExpr))
612  if (isa<CXXNewExpr>(Parent))
613  return CIP_DisallowedOnce;
614 
615  // Inlining constructors requires including initializers in the CFG.
616  const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
617  assert(ADC->getCFGBuildOptions().AddInitializers && "No CFG initializers");
618  (void)ADC;
619 
620  // If the destructor is trivial, it's always safe to inline the constructor.
621  if (Ctor.getDecl()->getParent()->hasTrivialDestructor())
622  break;
623 
624  // For other types, only inline constructors if destructor inlining is
625  // also enabled.
627  return CIP_DisallowedAlways;
628 
629  // FIXME: This is a hack. We don't handle temporary destructors
630  // right now, so we shouldn't inline their constructors.
632  if (!Target || !isa<DeclRegion>(Target))
633  return CIP_DisallowedOnce;
634 
635  break;
636  }
637  case CE_CXXDestructor: {
639  return CIP_DisallowedAlways;
640 
641  // Inlining destructors requires building the CFG correctly.
642  const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
643  assert(ADC->getCFGBuildOptions().AddImplicitDtors && "No CFG destructors");
644  (void)ADC;
645 
646  const CXXDestructorCall &Dtor = cast<CXXDestructorCall>(Call);
647 
648  // FIXME: We don't handle constructors or destructors for arrays properly.
649  const MemRegion *Target = Dtor.getCXXThisVal().getAsRegion();
650  if (Target && isa<ElementRegion>(Target))
651  return CIP_DisallowedOnce;
652 
653  break;
654  }
655  case CE_CXXAllocator:
656  if (Opts.mayInlineCXXAllocator())
657  break;
658  // Do not inline allocators until we model deallocators.
659  // This is unfortunate, but basically necessary for smart pointers and such.
660  return CIP_DisallowedAlways;
661  case CE_ObjCMessage:
662  if (!Opts.mayInlineObjCMethod())
663  return CIP_DisallowedAlways;
664  if (!(Opts.getIPAMode() == IPAK_DynamicDispatch ||
666  return CIP_DisallowedAlways;
667  break;
668  }
669 
670  return CIP_Allowed;
671 }
672 
673 /// Returns true if the given C++ class contains a member with the given name.
674 static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD,
675  StringRef Name) {
676  const IdentifierInfo &II = Ctx.Idents.get(Name);
677  DeclarationName DeclName = Ctx.DeclarationNames.getIdentifier(&II);
678  if (!RD->lookup(DeclName).empty())
679  return true;
680 
681  CXXBasePaths Paths(false, false, false);
682  if (RD->lookupInBases(
683  [DeclName](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
684  return CXXRecordDecl::FindOrdinaryMember(Specifier, Path, DeclName);
685  },
686  Paths))
687  return true;
688 
689  return false;
690 }
691 
692 /// Returns true if the given C++ class is a container or iterator.
693 ///
694 /// Our heuristic for this is whether it contains a method named 'begin()' or a
695 /// nested type named 'iterator' or 'iterator_category'.
696 static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD) {
697  return hasMember(Ctx, RD, "begin") ||
698  hasMember(Ctx, RD, "iterator") ||
699  hasMember(Ctx, RD, "iterator_category");
700 }
701 
702 /// Returns true if the given function refers to a method of a C++ container
703 /// or iterator.
704 ///
705 /// We generally do a poor job modeling most containers right now, and might
706 /// prefer not to inline their methods.
707 static bool isContainerMethod(const ASTContext &Ctx,
708  const FunctionDecl *FD) {
709  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
710  return isContainerClass(Ctx, MD->getParent());
711  return false;
712 }
713 
714 /// Returns true if the given function is the destructor of a class named
715 /// "shared_ptr".
716 static bool isCXXSharedPtrDtor(const FunctionDecl *FD) {
717  const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(FD);
718  if (!Dtor)
719  return false;
720 
721  const CXXRecordDecl *RD = Dtor->getParent();
722  if (const IdentifierInfo *II = RD->getDeclName().getAsIdentifierInfo())
723  if (II->isStr("shared_ptr"))
724  return true;
725 
726  return false;
727 }
728 
729 /// Returns true if the function in \p CalleeADC may be inlined in general.
730 ///
731 /// This checks static properties of the function, such as its signature and
732 /// CFG, to determine whether the analyzer should ever consider inlining it,
733 /// in any context.
734 static bool mayInlineDecl(AnalysisDeclContext *CalleeADC,
735  AnalyzerOptions &Opts) {
736  // FIXME: Do not inline variadic calls.
737  if (CallEvent::isVariadic(CalleeADC->getDecl()))
738  return false;
739 
740  // Check certain C++-related inlining policies.
741  ASTContext &Ctx = CalleeADC->getASTContext();
742  if (Ctx.getLangOpts().CPlusPlus) {
743  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeADC->getDecl())) {
744  // Conditionally control the inlining of template functions.
745  if (!Opts.mayInlineTemplateFunctions())
746  if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate)
747  return false;
748 
749  // Conditionally control the inlining of C++ standard library functions.
750  if (!Opts.mayInlineCXXStandardLibrary())
751  if (Ctx.getSourceManager().isInSystemHeader(FD->getLocation()))
753  return false;
754 
755  // Conditionally control the inlining of methods on objects that look
756  // like C++ containers.
757  if (!Opts.mayInlineCXXContainerMethods())
758  if (!Ctx.getSourceManager().isInMainFile(FD->getLocation()))
759  if (isContainerMethod(Ctx, FD))
760  return false;
761 
762  // Conditionally control the inlining of the destructor of C++ shared_ptr.
763  // We don't currently do a good job modeling shared_ptr because we can't
764  // see the reference count, so treating as opaque is probably the best
765  // idea.
766  if (!Opts.mayInlineCXXSharedPtrDtor())
767  if (isCXXSharedPtrDtor(FD))
768  return false;
769  }
770  }
771 
772  // It is possible that the CFG cannot be constructed.
773  // Be safe, and check if the CalleeCFG is valid.
774  const CFG *CalleeCFG = CalleeADC->getCFG();
775  if (!CalleeCFG)
776  return false;
777 
778  // Do not inline large functions.
779  if (CalleeCFG->getNumBlockIDs() > Opts.getMaxInlinableSize())
780  return false;
781 
782  // It is possible that the live variables analysis cannot be
783  // run. If so, bail out.
784  if (!CalleeADC->getAnalysis<RelaxedLiveVariables>())
785  return false;
786 
787  return true;
788 }
789 
790 bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D,
791  const ExplodedNode *Pred) {
792  if (!D)
793  return false;
794 
796  AnalyzerOptions &Opts = AMgr.options;
798  AnalysisDeclContext *CalleeADC = ADCMgr.getContext(D);
799 
800  // Temporary object destructor processing is currently broken, so we never
801  // inline them.
802  // FIXME: Remove this once temp destructors are working.
803  if (isa<CXXDestructorCall>(Call)) {
804  if ((*currBldrCtx->getBlock())[currStmtIdx].getAs<CFGTemporaryDtor>())
805  return false;
806  }
807 
808  // The auto-synthesized bodies are essential to inline as they are
809  // usually small and commonly used. Note: we should do this check early on to
810  // ensure we always inline these calls.
811  if (CalleeADC->isBodyAutosynthesized())
812  return true;
813 
814  if (!AMgr.shouldInlineCall())
815  return false;
816 
817  // Check if this function has been marked as non-inlinable.
818  Optional<bool> MayInline = Engine.FunctionSummaries->mayInline(D);
819  if (MayInline.hasValue()) {
820  if (!MayInline.getValue())
821  return false;
822 
823  } else {
824  // We haven't actually checked the static properties of this function yet.
825  // Do that now, and record our decision in the function summaries.
826  if (mayInlineDecl(CalleeADC, Opts)) {
827  Engine.FunctionSummaries->markMayInline(D);
828  } else {
829  Engine.FunctionSummaries->markShouldNotInline(D);
830  return false;
831  }
832  }
833 
834  // Check if we should inline a call based on its kind.
835  // FIXME: this checks both static and dynamic properties of the call, which
836  // means we're redoing a bit of work that could be cached in the function
837  // summary.
838  CallInlinePolicy CIP = mayInlineCallKind(Call, Pred, Opts);
839  if (CIP != CIP_Allowed) {
840  if (CIP == CIP_DisallowedAlways) {
841  assert(!MayInline.hasValue() || MayInline.getValue());
842  Engine.FunctionSummaries->markShouldNotInline(D);
843  }
844  return false;
845  }
846 
847  const CFG *CalleeCFG = CalleeADC->getCFG();
848 
849  // Do not inline if recursive or we've reached max stack frame count.
850  bool IsRecursive = false;
851  unsigned StackDepth = 0;
852  examineStackFrames(D, Pred->getLocationContext(), IsRecursive, StackDepth);
853  if ((StackDepth >= Opts.InlineMaxStackDepth) &&
854  ((CalleeCFG->getNumBlockIDs() > Opts.getAlwaysInlineSize())
855  || IsRecursive))
856  return false;
857 
858  // Do not inline large functions too many times.
859  if ((Engine.FunctionSummaries->getNumTimesInlined(D) >
860  Opts.getMaxTimesInlineLarge()) &&
861  CalleeCFG->getNumBlockIDs() >=
863  NumReachedInlineCountMax++;
864  return false;
865  }
866 
867  if (HowToInline == Inline_Minimal &&
868  (CalleeCFG->getNumBlockIDs() > Opts.getAlwaysInlineSize()
869  || IsRecursive))
870  return false;
871 
872  return true;
873 }
874 
875 static bool isTrivialObjectAssignment(const CallEvent &Call) {
876  const CXXInstanceCall *ICall = dyn_cast<CXXInstanceCall>(&Call);
877  if (!ICall)
878  return false;
879 
880  const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(ICall->getDecl());
881  if (!MD)
882  return false;
884  return false;
885 
886  return MD->isTrivial();
887 }
888 
890  const CallEvent &CallTemplate) {
891  // Make sure we have the most recent state attached to the call.
892  ProgramStateRef State = Pred->getState();
893  CallEventRef<> Call = CallTemplate.cloneWithState(State);
894 
895  // Special-case trivial assignment operators.
896  if (isTrivialObjectAssignment(*Call)) {
897  performTrivialCopy(Bldr, Pred, *Call);
898  return;
899  }
900 
901  // Try to inline the call.
902  // The origin expression here is just used as a kind of checksum;
903  // this should still be safe even for CallEvents that don't come from exprs.
904  const Expr *E = Call->getOriginExpr();
905 
906  ProgramStateRef InlinedFailedState = getInlineFailedState(State, E);
907  if (InlinedFailedState) {
908  // If we already tried once and failed, make sure we don't retry later.
909  State = InlinedFailedState;
910  } else {
911  RuntimeDefinition RD = Call->getRuntimeDefinition();
912  const Decl *D = RD.getDecl();
913  if (shouldInlineCall(*Call, D, Pred)) {
914  if (RD.mayHaveOtherDefinitions()) {
916 
917  // Explore with and without inlining the call.
918  if (Options.getIPAMode() == IPAK_DynamicDispatchBifurcate) {
919  BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred);
920  return;
921  }
922 
923  // Don't inline if we're not in any dynamic dispatch mode.
924  if (Options.getIPAMode() != IPAK_DynamicDispatch) {
925  conservativeEvalCall(*Call, Bldr, Pred, State);
926  return;
927  }
928  }
929 
930  // We are not bifurcating and we do have a Decl, so just inline.
931  if (inlineCall(*Call, D, Bldr, Pred, State))
932  return;
933  }
934  }
935 
936  // If we can't inline it, handle the return value and invalidate the regions.
937  conservativeEvalCall(*Call, Bldr, Pred, State);
938 }
939 
940 void ExprEngine::BifurcateCall(const MemRegion *BifurReg,
941  const CallEvent &Call, const Decl *D,
942  NodeBuilder &Bldr, ExplodedNode *Pred) {
943  assert(BifurReg);
944  BifurReg = BifurReg->StripCasts();
945 
946  // Check if we've performed the split already - note, we only want
947  // to split the path once per memory region.
948  ProgramStateRef State = Pred->getState();
949  const unsigned *BState =
950  State->get<DynamicDispatchBifurcationMap>(BifurReg);
951  if (BState) {
952  // If we are on "inline path", keep inlining if possible.
953  if (*BState == DynamicDispatchModeInlined)
954  if (inlineCall(Call, D, Bldr, Pred, State))
955  return;
956  // If inline failed, or we are on the path where we assume we
957  // don't have enough info about the receiver to inline, conjure the
958  // return value and invalidate the regions.
959  conservativeEvalCall(Call, Bldr, Pred, State);
960  return;
961  }
962 
963  // If we got here, this is the first time we process a message to this
964  // region, so split the path.
965  ProgramStateRef IState =
966  State->set<DynamicDispatchBifurcationMap>(BifurReg,
967  DynamicDispatchModeInlined);
968  inlineCall(Call, D, Bldr, Pred, IState);
969 
970  ProgramStateRef NoIState =
971  State->set<DynamicDispatchBifurcationMap>(BifurReg,
972  DynamicDispatchModeConservative);
973  conservativeEvalCall(Call, Bldr, Pred, NoIState);
974 
975  NumOfDynamicDispatchPathSplits++;
976 }
977 
979  ExplodedNodeSet &Dst) {
980  ExplodedNodeSet dstPreVisit;
981  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, RS, *this);
982 
983  StmtNodeBuilder B(dstPreVisit, Dst, *currBldrCtx);
984 
985  if (RS->getRetValue()) {
986  for (ExplodedNodeSet::iterator it = dstPreVisit.begin(),
987  ei = dstPreVisit.end(); it != ei; ++it) {
988  B.generateNode(RS, *it, (*it)->getState());
989  }
990  }
991 }
AnalysisDeclContextManager & getAnalysisDeclContextManager()
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1698
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:587
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
Stmt * getBody() const
Get the body of the Declaration.
succ_iterator succ_begin()
Definition: CFG.h:624
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:349
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
Represents a point when we begin processing an inlined call.
Definition: ProgramPoint.h:585
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.
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:122
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1239
const NestedNameSpecifier * Specifier
CallEventRef getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx)
Definition: CallEvent.cpp:1136
const ProgramStateRef & getState() const
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:642
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:302
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:621
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:402
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:1882
const CFGBlock * getEntry() const
Returns the entry block in the CFG for the entered function.
Definition: ProgramPoint.h:600
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
Definition: Decl.h:291
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:925
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:656
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:152
void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)
Run checkers for pre-visiting obj-c messages.
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:327
ExplodedNode * getFirstPred()
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition: DeclCXX.h:1404
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:865
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1521
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
CheckerManager & getCheckerManager() const
Definition: ExprEngine.h:127
NodeId Parent
Definition: ASTDiff.cpp:192
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:422
Represents a point when we finish the call exit sequence (for inlined call).
Definition: ProgramPoint.h:639
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:834
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:1158
Represents an implicit call to a C++ destructor.
Definition: CallEvent.h:717
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2620
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition: CoreEngine.h:211
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.
Traits for storing the call processing policy inside GDM.
Definition: ExprEngine.h:664
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:1413
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:2004
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
ParentMap & getParentMap() const
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
Defines the runtime definition of the called function.
Definition: CallEvent.h:104
QualType getCanonicalType() const
Definition: Type.h:5759
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:125
const MemRegion * getAsRegion() const
Definition: SVals.cpp:140
CallEventManager & getCallEventManager()
Definition: ProgramState.h:531
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:1964
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:6041
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:998
Refers to destructors (implicit or explicit).
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
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)
ast_type_traits::DynTypedNode Node
static ProgramStateRef getInlineFailedState(ProgramStateRef State, const Stmt *CallE)
SVal getCXXThisVal() const
Returns the value of the implicit &#39;this&#39; object.
Definition: CallEvent.cpp:667
Dataflow Directional Tag Classes.
CFG::BuildOptions & getCFGBuildOptions()
Return the build options used to construct the CFG.
SValBuilder & getSValBuilder()
Definition: ExprEngine.h:131
StoreManager & getStoreManager()
Definition: ExprEngine.h:307
const StackFrameContext * getCalleeContext() const
Definition: ProgramPoint.h:595
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:2085
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:1861
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:305
const Decl * getDecl() const
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
const LocationContext * getLocationContext() const
Definition: ProgramPoint.h:179
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
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call)
Default implementation of call evaluation.
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
Definition: CoreEngine.h:264
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()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2209
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:379
unsigned getMaxTimesInlineLarge()
Returns the maximum times a large function could be inlined.
static CallInlinePolicy mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred, AnalyzerOptions &Opts)
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:151
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
ConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
Definition: ExprCXX.h:1336