clang  8.0.0svn
RetainCountChecker.cpp
Go to the documentation of this file.
1 //==-- RetainCountChecker.cpp - Checks for leaks and other issues -*- 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 the methods for RetainCountChecker, which implements
11 // a reference count checker for Core Foundation and Cocoa on (Mac OS X).
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "RetainCountChecker.h"
16 
17 using namespace clang;
18 using namespace ento;
19 using namespace retaincountchecker;
20 using llvm::StrInStrNoCase;
21 
22 REGISTER_MAP_WITH_PROGRAMSTATE(RefBindings, SymbolRef, RefVal)
23 
24 namespace clang {
25 namespace ento {
26 namespace retaincountchecker {
27 
29  return State->get<RefBindings>(Sym);
30 }
31 
33  RefVal Val) {
34  assert(Sym != nullptr);
35  return State->set<RefBindings>(Sym, Val);
36 }
37 
39  return State->remove<RefBindings>(Sym);
40 }
41 
42 } // end namespace retaincountchecker
43 } // end namespace ento
44 } // end namespace clang
45 
46 void RefVal::print(raw_ostream &Out) const {
47  if (!T.isNull())
48  Out << "Tracked " << T.getAsString() << " | ";
49 
50  switch (getKind()) {
51  default: llvm_unreachable("Invalid RefVal kind");
52  case Owned: {
53  Out << "Owned";
54  unsigned cnt = getCount();
55  if (cnt) Out << " (+ " << cnt << ")";
56  break;
57  }
58 
59  case NotOwned: {
60  Out << "NotOwned";
61  unsigned cnt = getCount();
62  if (cnt) Out << " (+ " << cnt << ")";
63  break;
64  }
65 
66  case ReturnedOwned: {
67  Out << "ReturnedOwned";
68  unsigned cnt = getCount();
69  if (cnt) Out << " (+ " << cnt << ")";
70  break;
71  }
72 
73  case ReturnedNotOwned: {
74  Out << "ReturnedNotOwned";
75  unsigned cnt = getCount();
76  if (cnt) Out << " (+ " << cnt << ")";
77  break;
78  }
79 
80  case Released:
81  Out << "Released";
82  break;
83 
84  case ErrorDeallocNotOwned:
85  Out << "-dealloc (not-owned)";
86  break;
87 
88  case ErrorLeak:
89  Out << "Leaked";
90  break;
91 
92  case ErrorLeakReturned:
93  Out << "Leaked (Bad naming)";
94  break;
95 
96  case ErrorUseAfterRelease:
97  Out << "Use-After-Release [ERROR]";
98  break;
99 
100  case ErrorReleaseNotOwned:
101  Out << "Release of Not-Owned [ERROR]";
102  break;
103 
105  Out << "Over-autoreleased";
106  break;
107 
109  Out << "Non-owned object returned instead of owned";
110  break;
111  }
112 
113  switch (getIvarAccessHistory()) {
115  break;
116  case IvarAccessHistory::AccessedDirectly:
117  Out << " [direct ivar access]";
118  break;
119  case IvarAccessHistory::ReleasedAfterDirectAccess:
120  Out << " [released after direct ivar access]";
121  }
122 
123  if (ACnt) {
124  Out << " [autorelease -" << ACnt << ']';
125  }
126 }
127 
128 namespace {
129 class StopTrackingCallback final : public SymbolVisitor {
131 public:
132  StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
133  ProgramStateRef getState() const { return state; }
134 
135  bool VisitSymbol(SymbolRef sym) override {
136  state = state->remove<RefBindings>(sym);
137  return true;
138  }
139 };
140 } // end anonymous namespace
141 
142 //===----------------------------------------------------------------------===//
143 // Handle statements that may have an effect on refcounts.
144 //===----------------------------------------------------------------------===//
145 
147  CheckerContext &C) const {
148 
149  // Scan the BlockDecRefExprs for any object the retain count checker
150  // may be tracking.
151  if (!BE->getBlockDecl()->hasCaptures())
152  return;
153 
155  auto *R = cast<BlockDataRegion>(C.getSVal(BE).getAsRegion());
156 
157  BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
158  E = R->referenced_vars_end();
159 
160  if (I == E)
161  return;
162 
163  // FIXME: For now we invalidate the tracking of all symbols passed to blocks
164  // via captured variables, even though captured variables result in a copy
165  // and in implicit increment/decrement of a retain count.
167  const LocationContext *LC = C.getLocationContext();
169 
170  for ( ; I != E; ++I) {
171  const VarRegion *VR = I.getCapturedRegion();
172  if (VR->getSuperRegion() == R) {
173  VR = MemMgr.getVarRegion(VR->getDecl(), LC);
174  }
175  Regions.push_back(VR);
176  }
177 
178  state = state->scanReachableSymbols<StopTrackingCallback>(Regions).getState();
179  C.addTransition(state);
180 }
181 
183  CheckerContext &C) const {
184  const ObjCBridgedCastExpr *BE = dyn_cast<ObjCBridgedCastExpr>(CE);
185  if (!BE)
186  return;
187 
188  ArgEffect AE = IncRef;
189 
190  switch (BE->getBridgeKind()) {
191  case OBC_Bridge:
192  // Do nothing.
193  return;
194  case OBC_BridgeRetained:
195  AE = IncRef;
196  break;
197  case OBC_BridgeTransfer:
199  break;
200  }
201 
203  SymbolRef Sym = C.getSVal(CE).getAsLocSymbol();
204  if (!Sym)
205  return;
206  const RefVal* T = getRefBinding(state, Sym);
207  if (!T)
208  return;
209 
210  RefVal::Kind hasErr = (RefVal::Kind) 0;
211  state = updateSymbol(state, Sym, *T, AE, hasErr, C);
212 
213  if (hasErr) {
214  // FIXME: If we get an error during a bridge cast, should we report it?
215  return;
216  }
217 
218  C.addTransition(state);
219 }
220 
222  const Expr *Ex) const {
224  const ExplodedNode *pred = C.getPredecessor();
225  for (const Stmt *Child : Ex->children()) {
226  SVal V = pred->getSVal(Child);
227  if (SymbolRef sym = V.getAsSymbol())
228  if (const RefVal* T = getRefBinding(state, sym)) {
229  RefVal::Kind hasErr = (RefVal::Kind) 0;
230  state = updateSymbol(state, sym, *T, MayEscape, hasErr, C);
231  if (hasErr) {
232  processNonLeakError(state, Child->getSourceRange(), hasErr, sym, C);
233  return;
234  }
235  }
236  }
237 
238  // Return the object as autoreleased.
239  // RetEffect RE = RetEffect::MakeNotOwned(RetEffect::ObjC);
240  if (SymbolRef sym =
241  state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
242  QualType ResultTy = Ex->getType();
243  state = setRefBinding(state, sym,
245  }
246 
247  C.addTransition(state);
248 }
249 
251  CheckerContext &C) const {
252  // Apply the 'MayEscape' to all values.
253  processObjCLiterals(C, AL);
254 }
255 
257  CheckerContext &C) const {
258  // Apply the 'MayEscape' to all keys and values.
259  processObjCLiterals(C, DL);
260 }
261 
263  CheckerContext &C) const {
264  const ExplodedNode *Pred = C.getPredecessor();
265  ProgramStateRef State = Pred->getState();
266 
267  if (SymbolRef Sym = Pred->getSVal(Ex).getAsSymbol()) {
268  QualType ResultTy = Ex->getType();
269  State = setRefBinding(State, Sym,
271  }
272 
273  C.addTransition(State);
274 }
275 
277  CheckerContext &C) const {
278  Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>();
279  if (!IVarLoc)
280  return;
281 
283  SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
284  if (!Sym || !dyn_cast_or_null<ObjCIvarRegion>(Sym->getOriginRegion()))
285  return;
286 
287  // Accessing an ivar directly is unusual. If we've done that, be more
288  // forgiving about what the surrounding code is allowed to do.
289 
290  QualType Ty = Sym->getType();
292  if (Ty->isObjCRetainableType())
293  Kind = RetEffect::ObjC;
294  else if (coreFoundation::isCFObjectRef(Ty))
295  Kind = RetEffect::CF;
296  else
297  return;
298 
299  // If the value is already known to be nil, don't bother tracking it.
300  ConstraintManager &CMgr = State->getConstraintManager();
301  if (CMgr.isNull(State, Sym).isConstrainedTrue())
302  return;
303 
304  if (const RefVal *RV = getRefBinding(State, Sym)) {
305  // If we've seen this symbol before, or we're only seeing it now because
306  // of something the analyzer has synthesized, don't do anything.
307  if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None ||
309  return;
310  }
311 
312  // Note that this value has been loaded from an ivar.
313  C.addTransition(setRefBinding(State, Sym, RV->withIvarAccess()));
314  return;
315  }
316 
317  RefVal PlusZero = RefVal::makeNotOwned(Kind, Ty);
318 
319  // In a synthesized accessor, the effective retain count is +0.
321  C.addTransition(setRefBinding(State, Sym, PlusZero));
322  return;
323  }
324 
325  State = setRefBinding(State, Sym, PlusZero.withIvarAccess());
326  C.addTransition(State);
327 }
328 
330  CheckerContext &C) const {
331  RetainSummaryManager &Summaries = getSummaryManager(C);
332 
333  // Leave null if no receiver.
334  QualType ReceiverType;
335  if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
336  if (MC->isInstanceMessage()) {
337  SVal ReceiverV = MC->getReceiverSVal();
338  if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
339  if (const RefVal *T = getRefBinding(C.getState(), Sym))
340  ReceiverType = T->getType();
341  }
342  }
343 
344  const RetainSummary *Summ = Summaries.getSummary(Call, ReceiverType);
345 
346  if (C.wasInlined) {
347  processSummaryOfInlined(*Summ, Call, C);
348  return;
349  }
350  checkSummary(*Summ, Call, C);
351 }
352 
353 /// GetReturnType - Used to get the return type of a message expression or
354 /// function call with the intention of affixing that type to a tracked symbol.
355 /// While the return type can be queried directly from RetEx, when
356 /// invoking class methods we augment to the return type to be that of
357 /// a pointer to the class (as opposed it just being id).
358 // FIXME: We may be able to do this with related result types instead.
359 // This function is probably overestimating.
360 static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) {
361  QualType RetTy = RetE->getType();
362  // If RetE is not a message expression just return its type.
363  // If RetE is a message expression, return its types if it is something
364  /// more specific than id.
365  if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
366  if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>())
367  if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
368  PT->isObjCClassType()) {
369  // At this point we know the return type of the message expression is
370  // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
371  // is a call to a class method whose type we can resolve. In such
372  // cases, promote the return type to XXX* (where XXX is the class).
373  const ObjCInterfaceDecl *D = ME->getReceiverInterface();
374  return !D ? RetTy :
376  }
377 
378  return RetTy;
379 }
380 
382  QualType ResultTy) {
383  if (RE.isOwned()) {
384  return RefVal::makeOwned(RE.getObjKind(), ResultTy);
385  } else if (RE.notOwned()) {
386  return RefVal::makeNotOwned(RE.getObjKind(), ResultTy);
387  }
388 
389  return None;
390 }
391 
392 // We don't always get the exact modeling of the function with regards to the
393 // retain count checker even when the function is inlined. For example, we need
394 // to stop tracking the symbols which were marked with StopTrackingHard.
396  const CallEvent &CallOrMsg,
397  CheckerContext &C) const {
399 
400  // Evaluate the effect of the arguments.
401  for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
402  if (Summ.getArg(idx) == StopTrackingHard) {
403  SVal V = CallOrMsg.getArgSVal(idx);
404  if (SymbolRef Sym = V.getAsLocSymbol()) {
405  state = removeRefBinding(state, Sym);
406  }
407  }
408  }
409 
410  // Evaluate the effect on the message receiver.
411  if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
412  if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
413  if (Summ.getReceiverEffect() == StopTrackingHard) {
414  state = removeRefBinding(state, Sym);
415  }
416  }
417  }
418 
419  // Consult the summary for the return value.
420  RetEffect RE = Summ.getRetEffect();
421 
422  if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
423  if (RE.getKind() == RetEffect::NoRetHard)
424  state = removeRefBinding(state, Sym);
425  }
426 
427  C.addTransition(state);
428 }
429 
431  SVal ArgVal,
432  ArgEffect Effect) {
433  auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.getAsRegion());
434  if (!ArgRegion)
435  return State;
436 
437  QualType PointeeTy = ArgRegion->getValueType();
438  if (!coreFoundation::isCFObjectRef(PointeeTy))
439  return State;
440 
441  SVal PointeeVal = State->getSVal(ArgRegion);
442  SymbolRef Pointee = PointeeVal.getAsLocSymbol();
443  if (!Pointee)
444  return State;
445 
446  switch (Effect) {
448  State = setRefBinding(State, Pointee,
449  RefVal::makeNotOwned(RetEffect::CF, PointeeTy));
450  break;
452  // Do nothing. Retained out parameters will either point to a +1 reference
453  // or NULL, but the way you check for failure differs depending on the API.
454  // Consequently, we don't have a good way to track them yet.
455  break;
456 
457  default:
458  llvm_unreachable("only for out parameters");
459  }
460 
461  return State;
462 }
463 
465  const CallEvent &CallOrMsg,
466  CheckerContext &C) const {
468 
469  // Evaluate the effect of the arguments.
470  RefVal::Kind hasErr = (RefVal::Kind) 0;
471  SourceRange ErrorRange;
472  SymbolRef ErrorSym = nullptr;
473 
474  for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
475  SVal V = CallOrMsg.getArgSVal(idx);
476 
477  ArgEffect Effect = Summ.getArg(idx);
478  if (Effect == RetainedOutParameter || Effect == UnretainedOutParameter) {
479  state = updateOutParameter(state, V, Effect);
480  } else if (SymbolRef Sym = V.getAsLocSymbol()) {
481  if (const RefVal *T = getRefBinding(state, Sym)) {
482  state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
483  if (hasErr) {
484  ErrorRange = CallOrMsg.getArgSourceRange(idx);
485  ErrorSym = Sym;
486  break;
487  }
488  }
489  }
490  }
491 
492  // Evaluate the effect on the message receiver / `this` argument.
493  bool ReceiverIsTracked = false;
494  if (!hasErr) {
495  if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
496  if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
497  if (const RefVal *T = getRefBinding(state, Sym)) {
498  ReceiverIsTracked = true;
499  state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
500  hasErr, C);
501  if (hasErr) {
502  ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
503  ErrorSym = Sym;
504  }
505  }
506  }
507  } else if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
508  if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
509  if (const RefVal *T = getRefBinding(state, Sym)) {
510  state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
511  hasErr, C);
512  if (hasErr) {
513  ErrorRange = MCall->getOriginExpr()->getSourceRange();
514  ErrorSym = Sym;
515  }
516  }
517  }
518  }
519  }
520 
521  // Process any errors.
522  if (hasErr) {
523  processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C);
524  return;
525  }
526 
527  // Consult the summary for the return value.
528  RetEffect RE = Summ.getRetEffect();
529 
531  if (ReceiverIsTracked)
532  RE = getSummaryManager(C).getObjAllocRetEffect();
533  else
534  RE = RetEffect::MakeNoRet();
535  }
536 
537  if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
538  QualType ResultTy = CallOrMsg.getResultType();
539  if (RE.notOwned()) {
540  const Expr *Ex = CallOrMsg.getOriginExpr();
541  assert(Ex);
542  ResultTy = GetReturnType(Ex, C.getASTContext());
543  }
544  if (Optional<RefVal> updatedRefVal = refValFromRetEffect(RE, ResultTy))
545  state = setRefBinding(state, Sym, *updatedRefVal);
546  }
547 
548  // This check is actually necessary; otherwise the statement builder thinks
549  // we've hit a previously-found path.
550  // Normally addTransition takes care of this, but we want the node pointer.
551  ExplodedNode *NewNode;
552  if (state == C.getState()) {
553  NewNode = C.getPredecessor();
554  } else {
555  NewNode = C.addTransition(state);
556  }
557 
558  // Annotate the node with summary we used.
559  if (NewNode) {
560  // FIXME: This is ugly. See checkEndAnalysis for why it's necessary.
561  if (ShouldResetSummaryLog) {
562  SummaryLog.clear();
563  ShouldResetSummaryLog = false;
564  }
565  SummaryLog[NewNode] = &Summ;
566  }
567 }
568 
571  RefVal V, ArgEffect E, RefVal::Kind &hasErr,
572  CheckerContext &C) const {
573  bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
574  switch (E) {
575  default:
576  break;
577  case IncRefMsg:
578  E = IgnoreRetainMsg ? DoNothing : IncRef;
579  break;
580  case DecRefMsg:
581  E = IgnoreRetainMsg ? DoNothing: DecRef;
582  break;
584  E = IgnoreRetainMsg ? StopTracking : DecRefAndStopTrackingHard;
585  break;
586  case MakeCollectable:
587  E = DoNothing;
588  }
589 
590  // Handle all use-after-releases.
591  if (V.getKind() == RefVal::Released) {
593  hasErr = V.getKind();
594  return setRefBinding(state, sym, V);
595  }
596 
597  switch (E) {
598  case DecRefMsg:
599  case IncRefMsg:
600  case MakeCollectable:
602  llvm_unreachable("DecRefMsg/IncRefMsg/MakeCollectable already converted");
603 
606  llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
607  "not have ref state.");
608 
609  case Dealloc:
610  switch (V.getKind()) {
611  default:
612  llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
613  case RefVal::Owned:
614  // The object immediately transitions to the released state.
615  V = V ^ RefVal::Released;
616  V.clearCounts();
617  return setRefBinding(state, sym, V);
618  case RefVal::NotOwned:
620  hasErr = V.getKind();
621  break;
622  }
623  break;
624 
625  case MayEscape:
626  if (V.getKind() == RefVal::Owned) {
627  V = V ^ RefVal::NotOwned;
628  break;
629  }
630 
631  LLVM_FALLTHROUGH;
632 
633  case DoNothing:
634  return state;
635 
636  case Autorelease:
637  // Update the autorelease counts.
638  V = V.autorelease();
639  break;
640 
641  case StopTracking:
642  case StopTrackingHard:
643  return removeRefBinding(state, sym);
644 
645  case IncRef:
646  switch (V.getKind()) {
647  default:
648  llvm_unreachable("Invalid RefVal state for a retain.");
649  case RefVal::Owned:
650  case RefVal::NotOwned:
651  V = V + 1;
652  break;
653  }
654  break;
655 
656  case DecRef:
659  switch (V.getKind()) {
660  default:
661  // case 'RefVal::Released' handled above.
662  llvm_unreachable("Invalid RefVal state for a release.");
663 
664  case RefVal::Owned:
665  assert(V.getCount() > 0);
666  if (V.getCount() == 1) {
667  if (E == DecRefBridgedTransferred ||
668  V.getIvarAccessHistory() ==
670  V = V ^ RefVal::NotOwned;
671  else
672  V = V ^ RefVal::Released;
673  } else if (E == DecRefAndStopTrackingHard) {
674  return removeRefBinding(state, sym);
675  }
676 
677  V = V - 1;
678  break;
679 
680  case RefVal::NotOwned:
681  if (V.getCount() > 0) {
682  if (E == DecRefAndStopTrackingHard)
683  return removeRefBinding(state, sym);
684  V = V - 1;
685  } else if (V.getIvarAccessHistory() ==
687  // Assume that the instance variable was holding on the object at
688  // +1, and we just didn't know.
689  if (E == DecRefAndStopTrackingHard)
690  return removeRefBinding(state, sym);
692  } else {
694  hasErr = V.getKind();
695  }
696  break;
697  }
698  break;
699  }
700  return setRefBinding(state, sym, V);
701 }
702 
704  SourceRange ErrorRange,
706  SymbolRef Sym,
707  CheckerContext &C) const {
708  // HACK: Ignore retain-count issues on values accessed through ivars,
709  // because of cases like this:
710  // [_contentView retain];
711  // [_contentView removeFromSuperview];
712  // [self addSubview:_contentView]; // invalidates 'self'
713  // [_contentView release];
714  if (const RefVal *RV = getRefBinding(St, Sym))
715  if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
716  return;
717 
718  ExplodedNode *N = C.generateErrorNode(St);
719  if (!N)
720  return;
721 
722  CFRefBug *BT;
723  switch (ErrorKind) {
724  default:
725  llvm_unreachable("Unhandled error.");
727  if (!useAfterRelease)
728  useAfterRelease.reset(new UseAfterRelease(this));
729  BT = useAfterRelease.get();
730  break;
732  if (!releaseNotOwned)
733  releaseNotOwned.reset(new BadRelease(this));
734  BT = releaseNotOwned.get();
735  break;
737  if (!deallocNotOwned)
738  deallocNotOwned.reset(new DeallocNotOwned(this));
739  BT = deallocNotOwned.get();
740  break;
741  }
742 
743  assert(BT);
744  auto report = llvm::make_unique<CFRefReport>(
745  *BT, C.getASTContext().getLangOpts(), SummaryLog, N, Sym);
746  report->addRange(ErrorRange);
747  C.emitReport(std::move(report));
748 }
749 
750 //===----------------------------------------------------------------------===//
751 // Handle the return values of retain-count-related functions.
752 //===----------------------------------------------------------------------===//
753 
755  // Get the callee. We're only interested in simple C functions.
757  const FunctionDecl *FD = C.getCalleeDecl(CE);
758  if (!FD)
759  return false;
760 
761  RetainSummaryManager &SmrMgr = getSummaryManager(C);
762  QualType ResultTy = CE->getCallReturnType(C.getASTContext());
763 
764  // See if the function has 'rc_ownership_trusted_implementation'
765  // annotate attribute. If it does, we will not inline it.
766  bool hasTrustedImplementationAnnotation = false;
767 
768  const LocationContext *LCtx = C.getLocationContext();
769 
770  using BehaviorSummary = RetainSummaryManager::BehaviorSummary;
772  SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation);
773 
774  // See if it's one of the specific functions we know how to eval.
775  if (!BSmr)
776  return false;
777 
778  // Bind the return value.
779  if (BSmr == BehaviorSummary::Identity ||
780  BSmr == BehaviorSummary::IdentityOrZero) {
781  SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
782 
783  // If the receiver is unknown or the function has
784  // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
785  // return value.
786  if (RetVal.isUnknown() ||
787  (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
788  SValBuilder &SVB = C.getSValBuilder();
789  RetVal =
790  SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
791  }
792  state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
793 
794  if (BSmr == BehaviorSummary::IdentityOrZero) {
795  // Add a branch where the output is zero.
796  ProgramStateRef NullOutputState = C.getState();
797 
798  // Assume that output is zero on the other branch.
799  NullOutputState = NullOutputState->BindExpr(
800  CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false);
801 
802  C.addTransition(NullOutputState);
803 
804  // And on the original branch assume that both input and
805  // output are non-zero.
806  if (auto L = RetVal.getAs<DefinedOrUnknownSVal>())
807  state = state->assume(*L, /*Assumption=*/true);
808 
809  }
810  }
811 
812  C.addTransition(state);
813  return true;
814 }
815 
816 ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
817  CheckerContext &C) const {
818  ExplodedNode *Pred = C.getPredecessor();
819 
820  // Only adjust the reference count if this is the top-level call frame,
821  // and not the result of inlining. In the future, we should do
822  // better checking even for inlined calls, and see if they match
823  // with their expected semantics (e.g., the method should return a retained
824  // object, etc.).
825  if (!C.inTopFrame())
826  return Pred;
827 
828  if (!S)
829  return Pred;
830 
831  const Expr *RetE = S->getRetValue();
832  if (!RetE)
833  return Pred;
834 
836  SymbolRef Sym =
837  state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
838  if (!Sym)
839  return Pred;
840 
841  // Get the reference count binding (if any).
842  const RefVal *T = getRefBinding(state, Sym);
843  if (!T)
844  return Pred;
845 
846  // Change the reference count.
847  RefVal X = *T;
848 
849  switch (X.getKind()) {
850  case RefVal::Owned: {
851  unsigned cnt = X.getCount();
852  assert(cnt > 0);
853  X.setCount(cnt - 1);
854  X = X ^ RefVal::ReturnedOwned;
855  break;
856  }
857 
858  case RefVal::NotOwned: {
859  unsigned cnt = X.getCount();
860  if (cnt) {
861  X.setCount(cnt - 1);
862  X = X ^ RefVal::ReturnedOwned;
863  } else {
864  X = X ^ RefVal::ReturnedNotOwned;
865  }
866  break;
867  }
868 
869  default:
870  return Pred;
871  }
872 
873  // Update the binding.
874  state = setRefBinding(state, Sym, X);
875  Pred = C.addTransition(state);
876 
877  // At this point we have updated the state properly.
878  // Everything after this is merely checking to see if the return value has
879  // been over- or under-retained.
880 
881  // Did we cache out?
882  if (!Pred)
883  return nullptr;
884 
885  // Update the autorelease counts.
886  static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
887  state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X, S);
888 
889  // Have we generated a sink node?
890  if (!state)
891  return nullptr;
892 
893  // Get the updated binding.
894  T = getRefBinding(state, Sym);
895  assert(T);
896  X = *T;
897 
898  // Consult the summary of the enclosing method.
899  RetainSummaryManager &Summaries = getSummaryManager(C);
900  const Decl *CD = &Pred->getCodeDecl();
902 
903  // FIXME: What is the convention for blocks? Is there one?
904  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
905  const RetainSummary *Summ = Summaries.getMethodSummary(MD);
906  RE = Summ->getRetEffect();
907  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
908  if (!isa<CXXMethodDecl>(FD)) {
909  const RetainSummary *Summ = Summaries.getFunctionSummary(FD);
910  RE = Summ->getRetEffect();
911  }
912  }
913 
914  return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
915 }
916 
918  CheckerContext &C,
919  ExplodedNode *Pred,
920  RetEffect RE, RefVal X,
921  SymbolRef Sym,
922  ProgramStateRef state) const {
923  // HACK: Ignore retain-count issues on values accessed through ivars,
924  // because of cases like this:
925  // [_contentView retain];
926  // [_contentView removeFromSuperview];
927  // [self addSubview:_contentView]; // invalidates 'self'
928  // [_contentView release];
930  return Pred;
931 
932  // Any leaks or other errors?
933  if (X.isReturnedOwned() && X.getCount() == 0) {
934  if (RE.getKind() != RetEffect::NoRet) {
935  if (!RE.isOwned()) {
936 
937  // The returning type is a CF, we expect the enclosing method should
938  // return ownership.
940 
941  // Generate an error node.
942  state = setRefBinding(state, Sym, X);
943 
944  static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
945  ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
946  if (N) {
947  const LangOptions &LOpts = C.getASTContext().getLangOpts();
948  auto R = llvm::make_unique<CFRefLeakReport>(
949  *getLeakAtReturnBug(LOpts), LOpts, SummaryLog, N, Sym, C,
950  IncludeAllocationLine);
951  C.emitReport(std::move(R));
952  }
953  return N;
954  }
955  }
956  } else if (X.isReturnedNotOwned()) {
957  if (RE.isOwned()) {
958  if (X.getIvarAccessHistory() ==
960  // Assume the method was trying to transfer a +1 reference from a
961  // strong ivar to the caller.
962  state = setRefBinding(state, Sym,
964  } else {
965  // Trying to return a not owned object to a caller expecting an
966  // owned object.
967  state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
968 
970  ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
971 
972  ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
973  if (N) {
974  if (!returnNotOwnedForOwned)
975  returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
976 
977  auto R = llvm::make_unique<CFRefReport>(
978  *returnNotOwnedForOwned, C.getASTContext().getLangOpts(),
979  SummaryLog, N, Sym);
980  C.emitReport(std::move(R));
981  }
982  return N;
983  }
984  }
985  }
986  return Pred;
987 }
988 
989 //===----------------------------------------------------------------------===//
990 // Check various ways a symbol can be invalidated.
991 //===----------------------------------------------------------------------===//
992 
993 void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
994  CheckerContext &C) const {
995  // Are we storing to something that causes the value to "escape"?
996  bool escapes = true;
997 
998  // A value escapes in three possible cases (this may change):
999  //
1000  // (1) we are binding to something that is not a memory region.
1001  // (2) we are binding to a memregion that does not have stack storage
1002  // (3) we are binding to a memregion with stack storage that the store
1003  // does not understand.
1005 
1006  if (auto regionLoc = loc.getAs<loc::MemRegionVal>()) {
1007  escapes = !regionLoc->getRegion()->hasStackStorage();
1008 
1009  if (!escapes) {
1010  // To test (3), generate a new state with the binding added. If it is
1011  // the same state, then it escapes (since the store cannot represent
1012  // the binding).
1013  // Do this only if we know that the store is not supposed to generate the
1014  // same state.
1015  SVal StoredVal = state->getSVal(regionLoc->getRegion());
1016  if (StoredVal != val)
1017  escapes = (state == (state->bindLoc(*regionLoc, val, C.getLocationContext())));
1018  }
1019  if (!escapes) {
1020  // Case 4: We do not currently model what happens when a symbol is
1021  // assigned to a struct field, so be conservative here and let the symbol
1022  // go. TODO: This could definitely be improved upon.
1023  escapes = !isa<VarRegion>(regionLoc->getRegion());
1024  }
1025  }
1026 
1027  // If we are storing the value into an auto function scope variable annotated
1028  // with (__attribute__((cleanup))), stop tracking the value to avoid leak
1029  // false positives.
1030  if (const auto *LVR = dyn_cast_or_null<VarRegion>(loc.getAsRegion())) {
1031  const VarDecl *VD = LVR->getDecl();
1032  if (VD->hasAttr<CleanupAttr>()) {
1033  escapes = true;
1034  }
1035  }
1036 
1037  // If our store can represent the binding and we aren't storing to something
1038  // that doesn't have local storage then just return and have the simulation
1039  // state continue as is.
1040  if (!escapes)
1041  return;
1042 
1043  // Otherwise, find all symbols referenced by 'val' that we are tracking
1044  // and stop tracking them.
1045  state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1046  C.addTransition(state);
1047 }
1048 
1050  SVal Cond,
1051  bool Assumption) const {
1052  // FIXME: We may add to the interface of evalAssume the list of symbols
1053  // whose assumptions have changed. For now we just iterate through the
1054  // bindings and check if any of the tracked symbols are NULL. This isn't
1055  // too bad since the number of symbols we will track in practice are
1056  // probably small and evalAssume is only called at branches and a few
1057  // other places.
1058  RefBindingsTy B = state->get<RefBindings>();
1059 
1060  if (B.isEmpty())
1061  return state;
1062 
1063  bool changed = false;
1064  RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1065 
1066  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1067  // Check if the symbol is null stop tracking the symbol.
1068  ConstraintManager &CMgr = state->getConstraintManager();
1069  ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
1070  if (AllocFailed.isConstrainedTrue()) {
1071  changed = true;
1072  B = RefBFactory.remove(B, I.getKey());
1073  }
1074  }
1075 
1076  if (changed)
1077  state = state->set<RefBindings>(B);
1078 
1079  return state;
1080 }
1081 
1084  const InvalidatedSymbols *invalidated,
1085  ArrayRef<const MemRegion *> ExplicitRegions,
1087  const LocationContext *LCtx,
1088  const CallEvent *Call) const {
1089  if (!invalidated)
1090  return state;
1091 
1092  llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
1093  for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
1094  E = ExplicitRegions.end(); I != E; ++I) {
1095  if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>())
1096  WhitelistedSymbols.insert(SR->getSymbol());
1097  }
1098 
1099  for (SymbolRef sym :
1100  llvm::make_range(invalidated->begin(), invalidated->end())) {
1101  if (WhitelistedSymbols.count(sym))
1102  continue;
1103  // Remove any existing reference-count binding.
1104  state = removeRefBinding(state, sym);
1105  }
1106  return state;
1107 }
1108 
1111  ExplodedNode *Pred,
1112  const ProgramPointTag *Tag,
1113  CheckerContext &Ctx,
1114  SymbolRef Sym,
1115  RefVal V,
1116  const ReturnStmt *S) const {
1117  unsigned ACnt = V.getAutoreleaseCount();
1118 
1119  // No autorelease counts? Nothing to be done.
1120  if (!ACnt)
1121  return state;
1122 
1123  unsigned Cnt = V.getCount();
1124 
1125  // FIXME: Handle sending 'autorelease' to already released object.
1126 
1127  if (V.getKind() == RefVal::ReturnedOwned)
1128  ++Cnt;
1129 
1130  // If we would over-release here, but we know the value came from an ivar,
1131  // assume it was a strong ivar that's just been relinquished.
1132  if (ACnt > Cnt &&
1134  V = V.releaseViaIvar();
1135  --ACnt;
1136  }
1137 
1138  if (ACnt <= Cnt) {
1139  if (ACnt == Cnt) {
1140  V.clearCounts();
1141  if (V.getKind() == RefVal::ReturnedOwned) {
1142  V = V ^ RefVal::ReturnedNotOwned;
1143  } else {
1144  V = V ^ RefVal::NotOwned;
1145  }
1146  } else {
1147  V.setCount(V.getCount() - ACnt);
1148  V.setAutoreleaseCount(0);
1149  }
1150  return setRefBinding(state, Sym, V);
1151  }
1152 
1153  // HACK: Ignore retain-count issues on values accessed through ivars,
1154  // because of cases like this:
1155  // [_contentView retain];
1156  // [_contentView removeFromSuperview];
1157  // [self addSubview:_contentView]; // invalidates 'self'
1158  // [_contentView release];
1160  return state;
1161 
1162  // Woah! More autorelease counts then retain counts left.
1163  // Emit hard error.
1165  state = setRefBinding(state, Sym, V);
1166 
1167  ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
1168  if (N) {
1169  SmallString<128> sbuf;
1170  llvm::raw_svector_ostream os(sbuf);
1171  os << "Object was autoreleased ";
1172  if (V.getAutoreleaseCount() > 1)
1173  os << V.getAutoreleaseCount() << " times but the object ";
1174  else
1175  os << "but ";
1176  os << "has a +" << V.getCount() << " retain count";
1177 
1178  if (!overAutorelease)
1179  overAutorelease.reset(new OverAutorelease(this));
1180 
1181  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1182  auto R = llvm::make_unique<CFRefReport>(*overAutorelease, LOpts, SummaryLog,
1183  N, Sym, os.str());
1184  Ctx.emitReport(std::move(R));
1185  }
1186 
1187  return nullptr;
1188 }
1189 
1192  SymbolRef sid, RefVal V,
1193  SmallVectorImpl<SymbolRef> &Leaked) const {
1194  bool hasLeak;
1195 
1196  // HACK: Ignore retain-count issues on values accessed through ivars,
1197  // because of cases like this:
1198  // [_contentView retain];
1199  // [_contentView removeFromSuperview];
1200  // [self addSubview:_contentView]; // invalidates 'self'
1201  // [_contentView release];
1203  hasLeak = false;
1204  else if (V.isOwned())
1205  hasLeak = true;
1206  else if (V.isNotOwned() || V.isReturnedOwned())
1207  hasLeak = (V.getCount() > 0);
1208  else
1209  hasLeak = false;
1210 
1211  if (!hasLeak)
1212  return removeRefBinding(state, sid);
1213 
1214  Leaked.push_back(sid);
1215  return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
1216 }
1217 
1218 ExplodedNode *
1221  CheckerContext &Ctx,
1222  ExplodedNode *Pred) const {
1223  // Generate an intermediate node representing the leak point.
1224  ExplodedNode *N = Ctx.addTransition(state, Pred);
1225 
1226  if (N) {
1228  I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
1229 
1230  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1231  CFRefBug *BT = Pred ? getLeakWithinFunctionBug(LOpts)
1232  : getLeakAtReturnBug(LOpts);
1233  assert(BT && "BugType not initialized.");
1234 
1235  Ctx.emitReport(llvm::make_unique<CFRefLeakReport>(
1236  *BT, LOpts, SummaryLog, N, *I, Ctx, IncludeAllocationLine));
1237  }
1238  }
1239 
1240  return N;
1241 }
1242 
1243 static bool isISLObjectRef(QualType Ty) {
1244  return StringRef(Ty.getAsString()).startswith("isl_");
1245 }
1246 
1248  if (!Ctx.inTopFrame())
1249  return;
1250 
1251  RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
1252  const LocationContext *LCtx = Ctx.getLocationContext();
1253  const FunctionDecl *FD = dyn_cast<FunctionDecl>(LCtx->getDecl());
1254 
1255  if (!FD || SmrMgr.isTrustedReferenceCountImplementation(FD))
1256  return;
1257 
1258  ProgramStateRef state = Ctx.getState();
1259  const RetainSummary *FunctionSummary = SmrMgr.getFunctionSummary(FD);
1260  ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
1261 
1262  for (unsigned idx = 0, e = FD->getNumParams(); idx != e; ++idx) {
1263  const ParmVarDecl *Param = FD->getParamDecl(idx);
1264  SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1265 
1266  QualType Ty = Param->getType();
1267  const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
1268  if (AE && *AE == DecRef && isISLObjectRef(Ty)) {
1269  state = setRefBinding(
1270  state, Sym, RefVal::makeOwned(RetEffect::ObjKind::Generalized, Ty));
1271  } else if (isISLObjectRef(Ty)) {
1272  state = setRefBinding(
1273  state, Sym,
1274  RefVal::makeNotOwned(RetEffect::ObjKind::Generalized, Ty));
1275  }
1276  }
1277 
1278  Ctx.addTransition(state);
1279 }
1280 
1282  CheckerContext &Ctx) const {
1283  ExplodedNode *Pred = processReturn(RS, Ctx);
1284 
1285  // Created state cached out.
1286  if (!Pred) {
1287  return;
1288  }
1289 
1290  ProgramStateRef state = Pred->getState();
1291  RefBindingsTy B = state->get<RefBindings>();
1292 
1293  // Don't process anything within synthesized bodies.
1294  const LocationContext *LCtx = Pred->getLocationContext();
1295  if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
1296  assert(!LCtx->inTopFrame());
1297  return;
1298  }
1299 
1300  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1301  state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
1302  I->first, I->second);
1303  if (!state)
1304  return;
1305  }
1306 
1307  // If the current LocationContext has a parent, don't check for leaks.
1308  // We will do that later.
1309  // FIXME: we should instead check for imbalances of the retain/releases,
1310  // and suggest annotations.
1311  if (LCtx->getParent())
1312  return;
1313 
1314  B = state->get<RefBindings>();
1316 
1317  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
1318  state = handleSymbolDeath(state, I->first, I->second, Leaked);
1319 
1320  processLeaks(state, Leaked, Ctx, Pred);
1321 }
1322 
1324  CheckerContext &C) const {
1325  ExplodedNode *Pred = C.getPredecessor();
1326 
1328  RefBindingsTy B = state->get<RefBindings>();
1330 
1331  // Update counts from autorelease pools
1332  for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
1333  E = SymReaper.dead_end(); I != E; ++I) {
1334  SymbolRef Sym = *I;
1335  if (const RefVal *T = B.lookup(Sym)){
1336  // Use the symbol as the tag.
1337  // FIXME: This might not be as unique as we would like.
1338  static CheckerProgramPointTag Tag(this, "DeadSymbolAutorelease");
1339  state = handleAutoreleaseCounts(state, Pred, &Tag, C, Sym, *T);
1340  if (!state)
1341  return;
1342 
1343  // Fetch the new reference count from the state, and use it to handle
1344  // this symbol.
1345  state = handleSymbolDeath(state, *I, *getRefBinding(state, Sym), Leaked);
1346  }
1347  }
1348 
1349  if (Leaked.empty()) {
1350  C.addTransition(state);
1351  return;
1352  }
1353 
1354  Pred = processLeaks(state, Leaked, C, Pred);
1355 
1356  // Did we cache out?
1357  if (!Pred)
1358  return;
1359 
1360  // Now generate a new node that nukes the old bindings.
1361  // The only bindings left at this point are the leaked symbols.
1362  RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1363  B = state->get<RefBindings>();
1364 
1365  for (SmallVectorImpl<SymbolRef>::iterator I = Leaked.begin(),
1366  E = Leaked.end();
1367  I != E; ++I)
1368  B = F.remove(B, *I);
1369 
1370  state = state->set<RefBindings>(B);
1371  C.addTransition(state, Pred);
1372 }
1373 
1375  const char *NL, const char *Sep) const {
1376 
1377  RefBindingsTy B = State->get<RefBindings>();
1378 
1379  if (B.isEmpty())
1380  return;
1381 
1382  Out << Sep << NL;
1383 
1384  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1385  Out << I->first << " : ";
1386  I->second.print(Out);
1387  Out << NL;
1388  }
1389 }
1390 
1391 //===----------------------------------------------------------------------===//
1392 // Checker registration.
1393 //===----------------------------------------------------------------------===//
1394 
1395 void ento::registerRetainCountChecker(CheckerManager &Mgr) {
1396  auto *Chk = Mgr.registerChecker<RetainCountChecker>();
1397 
1398  AnalyzerOptions &Options = Mgr.getAnalyzerOptions();
1399 
1400  Chk->IncludeAllocationLine = Options.getCheckerBooleanOption(
1401  "leak-diagnostics-reference-allocation", false, Chk);
1402  Chk->ShouldCheckOSObjectRetainCount = Options.getCheckerBooleanOption(
1403  "CheckOSObject", true, Chk);
1404 }
const RetainSummary * getFunctionSummary(const FunctionDecl *FD)
const BlockDecl * getBlockDecl() const
Definition: Expr.h:5084
ProgramStateRef handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred, const ProgramPointTag *Tag, CheckerContext &Ctx, SymbolRef Sym, RefVal V, const ReturnStmt *S=nullptr) const
Represents a function declaration or definition.
Definition: Decl.h:1732
A (possibly-)qualified type.
Definition: Type.h:642
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:2446
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
Definition: Decl.h:3973
ProgramStateRef handleSymbolDeath(ProgramStateRef state, SymbolRef sid, RefVal V, SmallVectorImpl< SymbolRef > &Leaked) const
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +0 v...
ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym, RefVal Val)
bool evalCall(const CallExpr *CE, CheckerContext &C) const
Stmt - This represents one statement.
Definition: Stmt.h:66
The argument is treated as potentially escaping, meaning that even when its reference count hits 0 it...
Bridging via __bridge, which does nothing but reinterpret the bits.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
There is no effect.
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
const ProgramStateRef & getState() const
Indicates that no retain count information is tracked for the return value.
ArgEffect getArg(unsigned idx) const
getArg - Return the argument effect on the argument specified by idx (starting from 0)...
const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Definition: CallEvent.h:255
The argument has its reference count decreased by 1.
static RetEffect MakeNoRet()
Represents a variable declaration or definition.
Definition: Decl.h:812
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
Definition: SVals.cpp:85
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6716
const FunctionDecl * getCalleeDecl(const CallExpr *CE) const
Get the declaration of the called function (path-sensitive).
const Decl & getCodeDecl() const
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
virtual const MemRegion * getOriginRegion() const
Find the region from which this symbol originates.
Definition: SymExpr.h:102
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
Represents a parameter to a function.
Definition: Decl.h:1551
const bool wasInlined
If we are post visiting a call, this flag will be set if the call was inlined.
Performs the combined functionality of DecRefMsg and StopTrackingHard.
Symbolic value.
Definition: SymExpr.h:30
const MemRegion * getSuperRegion() const
Definition: MemRegion.h:443
ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym)
Convenience method to query the state to see if a symbol is null or not null, or if neither assumptio...
MemRegionManager & getRegionManager()
Definition: SValBuilder.h:175
All typestate tracking of the object ceases.
llvm::ImmutableMap< unsigned, ArgEffect > ArgEffects
ArgEffects summarizes the effects of a function/method call on all of its arguments.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
LineState State
static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t)
Create a state for an object whose lifetime is not the responsibility of the current function...
void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange, RefVal::Kind ErrorKind, SymbolRef Sym, CheckerContext &C) const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
Definition: ExprObjC.h:171
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
bool getCheckerBooleanOption(StringRef Name, bool DefaultVal, const ento::CheckerBase *C, bool SearchInParents=false) const
Interprets an option&#39;s string value as a boolean.
Summary for a function with respect to ownership changes.
The argument is treated as if an -autorelease message had been sent to the referenced object...
void checkPostCall(const CallEvent &Call, CheckerContext &C) const
Indicates that the return value is an owned object when the receiver is also a tracked object...
child_range children()
Definition: Stmt.cpp:229
const LocationContext * getLocationContext() const
bool isUnknown() const
Definition: SVals.h:137
SVal getReturnValue() const
Returns the return value of the call.
Definition: CallEvent.cpp:415
const RetainSummary * getSummary(const CallEvent &Call, QualType ReceiverType=QualType())
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:2882
Represents an ObjC class declaration.
Definition: DeclObjC.h:1164
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC...
Indicates that the tracked object is an Objective-C object.
virtual QualType getType() const =0
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
Definition: SVals.cpp:127
bool hasAttr() const
Definition: DeclBase.h:531
bool isConstrainedTrue() const
Return true if the constraint is perfectly constrained to &#39;true&#39;.
void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const
bool isSynthesizedAccessor(const StackFrameContext *SFC)
Returns true if this stack frame is for an Objective-C method that is a property getter or setter who...
IvarAccessHistory getIvarAccessHistory() const
Returns what the analyzer knows about direct accesses to a particular instance variable.
const RegionTy * getAs() const
Definition: MemRegion.h:1226
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:759
The argument has its reference count increased by 1.
void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const
This represents one expression.
Definition: Expr.h:106
RetEffect getRetEffect() const
getRetEffect - Returns the effect on the return value of the call.
bool isObjCRetainableType() const
Definition: Type.cpp:3896
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5070
static RefVal makeOwned(RetEffect::ObjKind o, QualType t)
Create a state for an object whose lifetime is the responsibility of the current function, at least partially.
#define bool
Definition: stdbool.h:31
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:288
void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const override
See CheckerManager::runCheckersForPrintState.
const RetainSummary * getMethodSummary(Selector S, const ObjCInterfaceDecl *ID, const ObjCMethodDecl *MD, QualType RetTy, ObjCMethodSummariesTy &CachedSummaries)
QualType getType() const
Definition: Expr.h:128
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:2005
ExplodedNode * checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, ExplodedNode *Pred, RetEffect RE, RefVal X, SymbolRef Sym, ProgramStateRef state) const
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:904
void processObjCLiterals(CheckerContext &C, const Expr *Ex) const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
The argument is treated as if an -dealloc message had been sent to the referenced object...
ObjKind
Determines the object kind of a tracked object.
ArgEffect
An ArgEffect summarizes the retain count behavior on an argument or receiver to a function or method...
ObjCBridgeCastKind getBridgeKind() const
Determine which kind of bridge is being performed via this cast.
Definition: ExprObjC.h:1607
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:707
ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym, RefVal V, ArgEffect E, RefVal::Kind &hasErr, CheckerContext &C) 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:112
const VarDecl * getDecl() const
Definition: MemRegion.h:948
Indicates that the tracked object is a CF object.
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
Optional< BehaviorSummary > canEval(const CallExpr *CE, const FunctionDecl *FD, bool &hasTrustedImplementationAnnotation)
static bool isISLObjectRef(QualType Ty)
Kind
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique &#39;name&#39;.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
Expr * getRetValue()
Definition: Stmt.h:2038
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a sink node.
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
Definition: ProgramPoint.h:40
const MemRegion * getAsRegion() const
Definition: SVals.cpp:151
ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, bool Assumption) const
static ProgramStateRef updateOutParameter(ProgramStateRef State, SVal ArgVal, ArgEffect Effect)
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2273
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:76
ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym)
A class responsible for cleaning up unused symbols.
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
ObjCBoxedExpr - used for generalized expression boxing.
Definition: ExprObjC.h:117
The argument has its reference count decreased by 1.
unsigned blockCount() const
Returns the number of times the current block has been visited along the analyzed path...
SymbolSetTy::const_iterator dead_iterator
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers...
Definition: ExprObjC.h:1575
Dataflow Directional Tag Classes.
virtual SourceRange getArgSourceRange(unsigned Index) const
Returns the source range for errors associated with this argument.
Definition: CallEvent.cpp:408
const VarRegion * getVarRegion(const VarDecl *D, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
Definition: MemRegion.cpp:846
static Optional< RefVal > refValFromRetEffect(RetEffect RE, QualType ResultTy)
ProgramStateRef checkRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call) const
ExplodedNode * processLeaks(ProgramStateRef state, SmallVectorImpl< SymbolRef > &Leaked, CheckerContext &Ctx, ExplodedNode *Pred=nullptr) const
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:975
const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1186
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition: Expr.cpp:1367
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:171
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
AnalyzerOptions & getAnalyzerOptions()
const Decl * getDecl() const
dead_iterator dead_begin() const
Represents a pointer to an Objective C object.
Definition: Type.h:5780
const StackFrameContext * getStackFrame() const
const ProgramStateRef & getState() const
void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const
const RefVal * getRefBinding(ProgramStateRef State, SymbolRef Sym)
bool isTrustedReferenceCountImplementation(const FunctionDecl *FD)
All typestate tracking of the object ceases.
dead_iterator dead_end() const
Stores options for the analyzer from the command line.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:513
QualType getResultType() const
Returns the result type, adjusted for references.
Definition: CallEvent.cpp:70
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:13849
Performs the combined functionality of DecRef and StopTrackingHard.
The argument acts as if has been passed to CFMakeCollectable, which transfers the object to the Garba...
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
The argument has its reference count increased by 1.
void checkSummary(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const
SValBuilder & getSValBuilder()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2377
ArgEffect getReceiverEffect() const
getReceiverEffect - Returns the effect on the receiver of the call.
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:954
The argument has its reference count decreased by 1 to model a transferred bridge cast under ARC...
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
Definition: CallEvent.cpp:401
QualType getType() const
Definition: Decl.h:647
void processSummaryOfInlined(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const
A trivial tuple used to represent a source range.
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
Definition: Checker.h:509
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool inTopFrame() const
Return true if the current LocationContext has no caller context.
const LocationContext * getLocationContext() const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3042
const LangOptions & getLangOpts() const
Definition: ASTContext.h:716
static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx)
GetReturnType - Used to get the return type of a message expression or function call with the intenti...
RetEffect summarizes a call&#39;s retain/release behavior with respect to its return value.