clang  9.0.0svn
RetainCountChecker.cpp
Go to the documentation of this file.
1 //==-- RetainCountChecker.cpp - Checks for leaks and other issues -*- C++ -*--//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the methods for RetainCountChecker, which implements
10 // a reference count checker for Core Foundation and Cocoa on (Mac OS X).
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #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 
32 } // end namespace retaincountchecker
33 } // end namespace ento
34 } // end namespace clang
35 
37  RefVal Val) {
38  assert(Sym != nullptr);
39  return State->set<RefBindings>(Sym, Val);
40 }
41 
43  return State->remove<RefBindings>(Sym);
44 }
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 = removeRefBinding(state, 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  QualType QT = CE->getType();
189  ObjKind K;
190  if (QT->isObjCObjectPointerType()) {
191  K = ObjKind::ObjC;
192  } else {
193  K = ObjKind::CF;
194  }
195 
196  ArgEffect AE = ArgEffect(IncRef, K);
197 
198  switch (BE->getBridgeKind()) {
199  case OBC_Bridge:
200  // Do nothing.
201  return;
202  case OBC_BridgeRetained:
203  AE = AE.withKind(IncRef);
204  break;
205  case OBC_BridgeTransfer:
207  break;
208  }
209 
211  SymbolRef Sym = C.getSVal(CE).getAsLocSymbol();
212  if (!Sym)
213  return;
214  const RefVal* T = getRefBinding(state, Sym);
215  if (!T)
216  return;
217 
218  RefVal::Kind hasErr = (RefVal::Kind) 0;
219  state = updateSymbol(state, Sym, *T, AE, hasErr, C);
220 
221  if (hasErr) {
222  // FIXME: If we get an error during a bridge cast, should we report it?
223  return;
224  }
225 
226  C.addTransition(state);
227 }
228 
230  const Expr *Ex) const {
232  const ExplodedNode *pred = C.getPredecessor();
233  for (const Stmt *Child : Ex->children()) {
234  SVal V = pred->getSVal(Child);
235  if (SymbolRef sym = V.getAsSymbol())
236  if (const RefVal* T = getRefBinding(state, sym)) {
237  RefVal::Kind hasErr = (RefVal::Kind) 0;
238  state = updateSymbol(state, sym, *T,
239  ArgEffect(MayEscape, ObjKind::ObjC), hasErr, C);
240  if (hasErr) {
241  processNonLeakError(state, Child->getSourceRange(), hasErr, sym, C);
242  return;
243  }
244  }
245  }
246 
247  // Return the object as autoreleased.
248  // RetEffect RE = RetEffect::MakeNotOwned(ObjKind::ObjC);
249  if (SymbolRef sym =
250  state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
251  QualType ResultTy = Ex->getType();
252  state = setRefBinding(state, sym,
254  }
255 
256  C.addTransition(state);
257 }
258 
260  CheckerContext &C) const {
261  // Apply the 'MayEscape' to all values.
262  processObjCLiterals(C, AL);
263 }
264 
266  CheckerContext &C) const {
267  // Apply the 'MayEscape' to all keys and values.
268  processObjCLiterals(C, DL);
269 }
270 
272  CheckerContext &C) const {
273  const ExplodedNode *Pred = C.getPredecessor();
274  ProgramStateRef State = Pred->getState();
275 
276  if (SymbolRef Sym = Pred->getSVal(Ex).getAsSymbol()) {
277  QualType ResultTy = Ex->getType();
278  State = setRefBinding(State, Sym,
280  }
281 
282  C.addTransition(State);
283 }
284 
286  CheckerContext &C) const {
287  Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>();
288  if (!IVarLoc)
289  return;
290 
292  SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
293  if (!Sym || !dyn_cast_or_null<ObjCIvarRegion>(Sym->getOriginRegion()))
294  return;
295 
296  // Accessing an ivar directly is unusual. If we've done that, be more
297  // forgiving about what the surrounding code is allowed to do.
298 
299  QualType Ty = Sym->getType();
300  ObjKind Kind;
301  if (Ty->isObjCRetainableType())
302  Kind = ObjKind::ObjC;
303  else if (coreFoundation::isCFObjectRef(Ty))
304  Kind = ObjKind::CF;
305  else
306  return;
307 
308  // If the value is already known to be nil, don't bother tracking it.
309  ConstraintManager &CMgr = State->getConstraintManager();
310  if (CMgr.isNull(State, Sym).isConstrainedTrue())
311  return;
312 
313  if (const RefVal *RV = getRefBinding(State, Sym)) {
314  // If we've seen this symbol before, or we're only seeing it now because
315  // of something the analyzer has synthesized, don't do anything.
316  if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None ||
318  return;
319  }
320 
321  // Note that this value has been loaded from an ivar.
322  C.addTransition(setRefBinding(State, Sym, RV->withIvarAccess()));
323  return;
324  }
325 
326  RefVal PlusZero = RefVal::makeNotOwned(Kind, Ty);
327 
328  // In a synthesized accessor, the effective retain count is +0.
330  C.addTransition(setRefBinding(State, Sym, PlusZero));
331  return;
332  }
333 
334  State = setRefBinding(State, Sym, PlusZero.withIvarAccess());
335  C.addTransition(State);
336 }
337 
338 static bool isReceiverUnconsumedSelf(const CallEvent &Call) {
339  if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
340 
341  // Check if the message is not consumed, we know it will not be used in
342  // an assignment, ex: "self = [super init]".
343  return MC->getMethodFamily() == OMF_init && MC->isReceiverSelfOrSuper() &&
344  !Call.getLocationContext()
346  ->getParentMap()
347  .isConsumedExpr(Call.getOriginExpr());
348  }
349  return false;
350 }
351 
352 const static RetainSummary *getSummary(RetainSummaryManager &Summaries,
353  const CallEvent &Call,
354  QualType ReceiverType) {
355  const Expr *CE = Call.getOriginExpr();
356  AnyCall C =
357  CE ? *AnyCall::forExpr(CE)
358  : AnyCall(cast<CXXDestructorDecl>(Call.getDecl()));
359  return Summaries.getSummary(C, Call.hasNonZeroCallbackArg(),
360  isReceiverUnconsumedSelf(Call), ReceiverType);
361 }
362 
364  CheckerContext &C) const {
365  RetainSummaryManager &Summaries = getSummaryManager(C);
366 
367  // Leave null if no receiver.
368  QualType ReceiverType;
369  if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
370  if (MC->isInstanceMessage()) {
371  SVal ReceiverV = MC->getReceiverSVal();
372  if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
373  if (const RefVal *T = getRefBinding(C.getState(), Sym))
374  ReceiverType = T->getType();
375  }
376  }
377 
378  const RetainSummary *Summ = getSummary(Summaries, Call, ReceiverType);
379 
380  if (C.wasInlined) {
381  processSummaryOfInlined(*Summ, Call, C);
382  return;
383  }
384  checkSummary(*Summ, Call, C);
385 }
386 
387 /// GetReturnType - Used to get the return type of a message expression or
388 /// function call with the intention of affixing that type to a tracked symbol.
389 /// While the return type can be queried directly from RetEx, when
390 /// invoking class methods we augment to the return type to be that of
391 /// a pointer to the class (as opposed it just being id).
392 // FIXME: We may be able to do this with related result types instead.
393 // This function is probably overestimating.
394 static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) {
395  QualType RetTy = RetE->getType();
396  // If RetE is not a message expression just return its type.
397  // If RetE is a message expression, return its types if it is something
398  /// more specific than id.
399  if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
400  if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>())
401  if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
402  PT->isObjCClassType()) {
403  // At this point we know the return type of the message expression is
404  // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
405  // is a call to a class method whose type we can resolve. In such
406  // cases, promote the return type to XXX* (where XXX is the class).
407  const ObjCInterfaceDecl *D = ME->getReceiverInterface();
408  return !D ? RetTy :
410  }
411 
412  return RetTy;
413 }
414 
415 static Optional<RefVal> refValFromRetEffect(RetEffect RE,
416  QualType ResultTy) {
417  if (RE.isOwned()) {
418  return RefVal::makeOwned(RE.getObjKind(), ResultTy);
419  } else if (RE.notOwned()) {
420  return RefVal::makeNotOwned(RE.getObjKind(), ResultTy);
421  }
422 
423  return None;
424 }
425 
426 static bool isPointerToObject(QualType QT) {
427  QualType PT = QT->getPointeeType();
428  if (!PT.isNull())
429  if (PT->getAsCXXRecordDecl())
430  return true;
431  return false;
432 }
433 
434 /// Whether the tracked value should be escaped on a given call.
435 /// OSObjects are escaped when passed to void * / etc.
436 static bool shouldEscapeOSArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
437  const RefVal *TrackedValue) {
438  if (TrackedValue->getObjKind() != ObjKind::OS)
439  return false;
440  if (ArgIdx >= CE.parameters().size())
441  return false;
442  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
443 }
444 
445 // We don't always get the exact modeling of the function with regards to the
446 // retain count checker even when the function is inlined. For example, we need
447 // to stop tracking the symbols which were marked with StopTrackingHard.
448 void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
449  const CallEvent &CallOrMsg,
450  CheckerContext &C) const {
452 
453  // Evaluate the effect of the arguments.
454  for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
455  SVal V = CallOrMsg.getArgSVal(idx);
456 
457  if (SymbolRef Sym = V.getAsLocSymbol()) {
458  bool ShouldRemoveBinding = Summ.getArg(idx).getKind() == StopTrackingHard;
459  if (const RefVal *T = getRefBinding(state, Sym))
460  if (shouldEscapeOSArgumentOnCall(CallOrMsg, idx, T))
461  ShouldRemoveBinding = true;
462 
463  if (ShouldRemoveBinding)
464  state = removeRefBinding(state, Sym);
465  }
466  }
467 
468  // Evaluate the effect on the message receiver.
469  if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
470  if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
471  if (Summ.getReceiverEffect().getKind() == StopTrackingHard) {
472  state = removeRefBinding(state, Sym);
473  }
474  }
475  }
476 
477  // Consult the summary for the return value.
478  RetEffect RE = Summ.getRetEffect();
479 
480  if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
481  if (RE.getKind() == RetEffect::NoRetHard)
482  state = removeRefBinding(state, Sym);
483  }
484 
485  C.addTransition(state);
486 }
487 
488 static bool isSmartPtrField(const MemRegion *MR) {
489  const auto *TR = dyn_cast<TypedValueRegion>(
490  cast<SubRegion>(MR)->getSuperRegion());
491  return TR && RetainSummaryManager::isKnownSmartPointer(TR->getValueType());
492 }
493 
494 
495 /// A value escapes in these possible cases:
496 ///
497 /// - binding to something that is not a memory region.
498 /// - binding to a memregion that does not have stack storage
499 /// - binding to a variable that has a destructor attached using CleanupAttr
500 ///
501 /// We do not currently model what happens when a symbol is
502 /// assigned to a struct field, unless it is a known smart pointer
503 /// implementation, about which we know that it is inlined.
504 /// FIXME: This could definitely be improved upon.
505 static bool shouldEscapeRegion(const MemRegion *R) {
506  if (isSmartPtrField(R))
507  return false;
508 
509  const auto *VR = dyn_cast<VarRegion>(R);
510 
511  if (!R->hasStackStorage() || !VR)
512  return true;
513 
514  const VarDecl *VD = VR->getDecl();
515  if (!VD->hasAttr<CleanupAttr>())
516  return false; // CleanupAttr attaches destructors, which cause escaping.
517  return true;
518 }
519 
521 updateOutParameters(ProgramStateRef State, const RetainSummary &Summ,
522  const CallEvent &CE) {
523 
524  SVal L = CE.getReturnValue();
525 
526  // Splitting is required to support out parameters,
527  // as out parameters might be created only on the "success" branch.
528  // We want to avoid eagerly splitting unless out parameters are actually
529  // needed.
530  bool SplitNecessary = false;
531  for (auto &P : Summ.getArgEffects())
532  if (P.second.getKind() == RetainedOutParameterOnNonZero ||
533  P.second.getKind() == RetainedOutParameterOnZero)
534  SplitNecessary = true;
535 
536  ProgramStateRef AssumeNonZeroReturn = State;
537  ProgramStateRef AssumeZeroReturn = State;
538 
539  if (SplitNecessary) {
540  if (!CE.getResultType()->isScalarType()) {
541  // Structures cannot be assumed. This probably deserves
542  // a compiler warning for invalid annotations.
543  return {State};
544  }
545  if (auto DL = L.getAs<DefinedOrUnknownSVal>()) {
546  AssumeNonZeroReturn = AssumeNonZeroReturn->assume(*DL, true);
547  AssumeZeroReturn = AssumeZeroReturn->assume(*DL, false);
548  }
549  }
550 
551  for (unsigned idx = 0, e = CE.getNumArgs(); idx != e; ++idx) {
552  SVal ArgVal = CE.getArgSVal(idx);
553  ArgEffect AE = Summ.getArg(idx);
554 
555  auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.getAsRegion());
556  if (!ArgRegion)
557  continue;
558 
559  QualType PointeeTy = ArgRegion->getValueType();
560  SVal PointeeVal = State->getSVal(ArgRegion);
561  SymbolRef Pointee = PointeeVal.getAsLocSymbol();
562  if (!Pointee)
563  continue;
564 
565  if (shouldEscapeRegion(ArgRegion))
566  continue;
567 
568  auto makeNotOwnedParameter = [&](ProgramStateRef St) {
569  return setRefBinding(St, Pointee,
570  RefVal::makeNotOwned(AE.getObjKind(), PointeeTy));
571  };
572  auto makeOwnedParameter = [&](ProgramStateRef St) {
573  return setRefBinding(St, Pointee,
574  RefVal::makeOwned(ObjKind::OS, PointeeTy));
575  };
576 
577  switch (AE.getKind()) {
579  AssumeNonZeroReturn = makeNotOwnedParameter(AssumeNonZeroReturn);
580  AssumeZeroReturn = makeNotOwnedParameter(AssumeZeroReturn);
581  break;
583  AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
584  AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
585  break;
587  AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
588  break;
590  AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
591  break;
592  default:
593  break;
594  }
595  }
596 
597  if (SplitNecessary) {
598  return {AssumeNonZeroReturn, AssumeZeroReturn};
599  } else {
600  assert(AssumeZeroReturn == AssumeNonZeroReturn);
601  return {AssumeZeroReturn};
602  }
603 }
604 
605 void RetainCountChecker::checkSummary(const RetainSummary &Summ,
606  const CallEvent &CallOrMsg,
607  CheckerContext &C) const {
609 
610  // Evaluate the effect of the arguments.
611  RefVal::Kind hasErr = (RefVal::Kind) 0;
612  SourceRange ErrorRange;
613  SymbolRef ErrorSym = nullptr;
614 
615  // Helper tag for providing diagnostics: indicate whether dealloc was sent
616  // at this location.
617  bool DeallocSent = false;
618 
619  for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
620  SVal V = CallOrMsg.getArgSVal(idx);
621 
622  ArgEffect Effect = Summ.getArg(idx);
623  if (SymbolRef Sym = V.getAsLocSymbol()) {
624  if (const RefVal *T = getRefBinding(state, Sym)) {
625 
626  if (shouldEscapeOSArgumentOnCall(CallOrMsg, idx, T))
628 
629  state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
630  if (hasErr) {
631  ErrorRange = CallOrMsg.getArgSourceRange(idx);
632  ErrorSym = Sym;
633  break;
634  } else if (Effect.getKind() == Dealloc) {
635  DeallocSent = true;
636  }
637  }
638  }
639  }
640 
641  // Evaluate the effect on the message receiver / `this` argument.
642  bool ReceiverIsTracked = false;
643  if (!hasErr) {
644  if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
645  if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
646  if (const RefVal *T = getRefBinding(state, Sym)) {
647  ReceiverIsTracked = true;
648  state = updateSymbol(state, Sym, *T,
649  Summ.getReceiverEffect(), hasErr, C);
650  if (hasErr) {
651  ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
652  ErrorSym = Sym;
653  } else if (Summ.getReceiverEffect().getKind() == Dealloc) {
654  DeallocSent = true;
655  }
656  }
657  }
658  } else if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
659  if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
660  if (const RefVal *T = getRefBinding(state, Sym)) {
661  state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
662  hasErr, C);
663  if (hasErr) {
664  ErrorRange = MCall->getOriginExpr()->getSourceRange();
665  ErrorSym = Sym;
666  }
667  }
668  }
669  }
670  }
671 
672  // Process any errors.
673  if (hasErr) {
674  processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C);
675  return;
676  }
677 
678  // Consult the summary for the return value.
679  RetEffect RE = Summ.getRetEffect();
680 
682  if (ReceiverIsTracked)
683  RE = getSummaryManager(C).getObjAllocRetEffect();
684  else
685  RE = RetEffect::MakeNoRet();
686  }
687 
688  if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
689  QualType ResultTy = CallOrMsg.getResultType();
690  if (RE.notOwned()) {
691  const Expr *Ex = CallOrMsg.getOriginExpr();
692  assert(Ex);
693  ResultTy = GetReturnType(Ex, C.getASTContext());
694  }
695  if (Optional<RefVal> updatedRefVal = refValFromRetEffect(RE, ResultTy))
696  state = setRefBinding(state, Sym, *updatedRefVal);
697  }
698 
700  updateOutParameters(state, Summ, CallOrMsg);
701 
702  for (ProgramStateRef St : Out) {
703  if (DeallocSent) {
704  C.addTransition(St, C.getPredecessor(), &DeallocSentTag);
705  } else {
706  C.addTransition(St);
707  }
708  }
709 }
710 
712  SymbolRef sym, RefVal V,
713  ArgEffect AE,
714  RefVal::Kind &hasErr,
715  CheckerContext &C) const {
716  bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
717  if (AE.getObjKind() == ObjKind::ObjC && IgnoreRetainMsg) {
718  switch (AE.getKind()) {
719  default:
720  break;
721  case IncRef:
722  AE = AE.withKind(DoNothing);
723  break;
724  case DecRef:
725  AE = AE.withKind(DoNothing);
726  break;
728  AE = AE.withKind(StopTracking);
729  break;
730  }
731  }
732 
733  // Handle all use-after-releases.
734  if (V.getKind() == RefVal::Released) {
736  hasErr = V.getKind();
737  return setRefBinding(state, sym, V);
738  }
739 
740  switch (AE.getKind()) {
745  llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
746  "not have ref state.");
747 
748  case Dealloc: // NB. we only need to add a note in a non-error case.
749  switch (V.getKind()) {
750  default:
751  llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
752  case RefVal::Owned:
753  // The object immediately transitions to the released state.
754  V = V ^ RefVal::Released;
755  V.clearCounts();
756  return setRefBinding(state, sym, V);
757  case RefVal::NotOwned:
759  hasErr = V.getKind();
760  break;
761  }
762  break;
763 
764  case MayEscape:
765  if (V.getKind() == RefVal::Owned) {
766  V = V ^ RefVal::NotOwned;
767  break;
768  }
769 
770  LLVM_FALLTHROUGH;
771 
772  case DoNothing:
773  return state;
774 
775  case Autorelease:
776  // Update the autorelease counts.
777  V = V.autorelease();
778  break;
779 
780  case StopTracking:
781  case StopTrackingHard:
782  return removeRefBinding(state, sym);
783 
784  case IncRef:
785  switch (V.getKind()) {
786  default:
787  llvm_unreachable("Invalid RefVal state for a retain.");
788  case RefVal::Owned:
789  case RefVal::NotOwned:
790  V = V + 1;
791  break;
792  }
793  break;
794 
795  case DecRef:
798  switch (V.getKind()) {
799  default:
800  // case 'RefVal::Released' handled above.
801  llvm_unreachable("Invalid RefVal state for a release.");
802 
803  case RefVal::Owned:
804  assert(V.getCount() > 0);
805  if (V.getCount() == 1) {
806  if (AE.getKind() == DecRefBridgedTransferred ||
807  V.getIvarAccessHistory() ==
809  V = V ^ RefVal::NotOwned;
810  else
811  V = V ^ RefVal::Released;
812  } else if (AE.getKind() == DecRefAndStopTrackingHard) {
813  return removeRefBinding(state, sym);
814  }
815 
816  V = V - 1;
817  break;
818 
819  case RefVal::NotOwned:
820  if (V.getCount() > 0) {
822  return removeRefBinding(state, sym);
823  V = V - 1;
824  } else if (V.getIvarAccessHistory() ==
826  // Assume that the instance variable was holding on the object at
827  // +1, and we just didn't know.
829  return removeRefBinding(state, sym);
831  } else {
833  hasErr = V.getKind();
834  }
835  break;
836  }
837  break;
838  }
839  return setRefBinding(state, sym, V);
840 }
841 
842 const RefCountBug &
844  SymbolRef Sym) const {
845  switch (ErrorKind) {
847  return useAfterRelease;
849  return releaseNotOwned;
851  if (Sym->getType()->getPointeeCXXRecordDecl())
852  return freeNotOwned;
853  return deallocNotOwned;
854  default:
855  llvm_unreachable("Unhandled error.");
856  }
857 }
858 
860  SourceRange ErrorRange,
862  SymbolRef Sym,
863  CheckerContext &C) const {
864  // HACK: Ignore retain-count issues on values accessed through ivars,
865  // because of cases like this:
866  // [_contentView retain];
867  // [_contentView removeFromSuperview];
868  // [self addSubview:_contentView]; // invalidates 'self'
869  // [_contentView release];
870  if (const RefVal *RV = getRefBinding(St, Sym))
871  if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
872  return;
873 
874  ExplodedNode *N = C.generateErrorNode(St);
875  if (!N)
876  return;
877 
878  auto report = llvm::make_unique<RefCountReport>(
879  errorKindToBugKind(ErrorKind, Sym),
880  C.getASTContext().getLangOpts(), N, Sym);
881  report->addRange(ErrorRange);
882  C.emitReport(std::move(report));
883 }
884 
885 //===----------------------------------------------------------------------===//
886 // Handle the return values of retain-count-related functions.
887 //===----------------------------------------------------------------------===//
888 
891  const FunctionDecl *FD = C.getCalleeDecl(CE);
892  if (!FD)
893  return false;
894 
895  RetainSummaryManager &SmrMgr = getSummaryManager(C);
896  QualType ResultTy = CE->getCallReturnType(C.getASTContext());
897 
898  // See if the function has 'rc_ownership_trusted_implementation'
899  // annotate attribute. If it does, we will not inline it.
900  bool hasTrustedImplementationAnnotation = false;
901 
902  const LocationContext *LCtx = C.getLocationContext();
903 
904  using BehaviorSummary = RetainSummaryManager::BehaviorSummary;
906  SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation);
907 
908  // See if it's one of the specific functions we know how to eval.
909  if (!BSmr)
910  return false;
911 
912  // Bind the return value.
913  if (BSmr == BehaviorSummary::Identity ||
914  BSmr == BehaviorSummary::IdentityOrZero ||
915  BSmr == BehaviorSummary::IdentityThis) {
916 
917  const Expr *BindReturnTo =
918  (BSmr == BehaviorSummary::IdentityThis)
919  ? cast<CXXMemberCallExpr>(CE)->getImplicitObjectArgument()
920  : CE->getArg(0);
921  SVal RetVal = state->getSVal(BindReturnTo, LCtx);
922 
923  // If the receiver is unknown or the function has
924  // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
925  // return value.
926  // FIXME: this branch is very strange.
927  if (RetVal.isUnknown() ||
928  (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
929  SValBuilder &SVB = C.getSValBuilder();
930  RetVal =
931  SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
932  }
933 
934  // Bind the value.
935  state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
936 
937  if (BSmr == BehaviorSummary::IdentityOrZero) {
938  // Add a branch where the output is zero.
939  ProgramStateRef NullOutputState = C.getState();
940 
941  // Assume that output is zero on the other branch.
942  NullOutputState = NullOutputState->BindExpr(
943  CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false);
944  C.addTransition(NullOutputState, &CastFailTag);
945 
946  // And on the original branch assume that both input and
947  // output are non-zero.
948  if (auto L = RetVal.getAs<DefinedOrUnknownSVal>())
949  state = state->assume(*L, /*Assumption=*/true);
950 
951  }
952  }
953 
954  C.addTransition(state);
955  return true;
956 }
957 
958 ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
959  CheckerContext &C) const {
960  ExplodedNode *Pred = C.getPredecessor();
961 
962  // Only adjust the reference count if this is the top-level call frame,
963  // and not the result of inlining. In the future, we should do
964  // better checking even for inlined calls, and see if they match
965  // with their expected semantics (e.g., the method should return a retained
966  // object, etc.).
967  if (!C.inTopFrame())
968  return Pred;
969 
970  if (!S)
971  return Pred;
972 
973  const Expr *RetE = S->getRetValue();
974  if (!RetE)
975  return Pred;
976 
978  // We need to dig down to the symbolic base here because various
979  // custom allocators do sometimes return the symbol with an offset.
980  SymbolRef Sym = state->getSValAsScalarOrLoc(RetE, C.getLocationContext())
981  .getAsLocSymbol(/*IncludeBaseRegions=*/true);
982  if (!Sym)
983  return Pred;
984 
985  // Get the reference count binding (if any).
986  const RefVal *T = getRefBinding(state, Sym);
987  if (!T)
988  return Pred;
989 
990  // Change the reference count.
991  RefVal X = *T;
992 
993  switch (X.getKind()) {
994  case RefVal::Owned: {
995  unsigned cnt = X.getCount();
996  assert(cnt > 0);
997  X.setCount(cnt - 1);
998  X = X ^ RefVal::ReturnedOwned;
999  break;
1000  }
1001 
1002  case RefVal::NotOwned: {
1003  unsigned cnt = X.getCount();
1004  if (cnt) {
1005  X.setCount(cnt - 1);
1006  X = X ^ RefVal::ReturnedOwned;
1007  } else {
1008  X = X ^ RefVal::ReturnedNotOwned;
1009  }
1010  break;
1011  }
1012 
1013  default:
1014  return Pred;
1015  }
1016 
1017  // Update the binding.
1018  state = setRefBinding(state, Sym, X);
1019  Pred = C.addTransition(state);
1020 
1021  // At this point we have updated the state properly.
1022  // Everything after this is merely checking to see if the return value has
1023  // been over- or under-retained.
1024 
1025  // Did we cache out?
1026  if (!Pred)
1027  return nullptr;
1028 
1029  // Update the autorelease counts.
1030  static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
1031  state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X, S);
1032 
1033  // Have we generated a sink node?
1034  if (!state)
1035  return nullptr;
1036 
1037  // Get the updated binding.
1038  T = getRefBinding(state, Sym);
1039  assert(T);
1040  X = *T;
1041 
1042  // Consult the summary of the enclosing method.
1043  RetainSummaryManager &Summaries = getSummaryManager(C);
1044  const Decl *CD = &Pred->getCodeDecl();
1046 
1047  // FIXME: What is the convention for blocks? Is there one?
1048  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
1049  const RetainSummary *Summ = Summaries.getSummary(AnyCall(MD));
1050  RE = Summ->getRetEffect();
1051  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
1052  if (!isa<CXXMethodDecl>(FD)) {
1053  const RetainSummary *Summ = Summaries.getSummary(AnyCall(FD));
1054  RE = Summ->getRetEffect();
1055  }
1056  }
1057 
1058  return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
1059 }
1060 
1062  CheckerContext &C,
1063  ExplodedNode *Pred,
1064  RetEffect RE, RefVal X,
1065  SymbolRef Sym,
1066  ProgramStateRef state) const {
1067  // HACK: Ignore retain-count issues on values accessed through ivars,
1068  // because of cases like this:
1069  // [_contentView retain];
1070  // [_contentView removeFromSuperview];
1071  // [self addSubview:_contentView]; // invalidates 'self'
1072  // [_contentView release];
1074  return Pred;
1075 
1076  // Any leaks or other errors?
1077  if (X.isReturnedOwned() && X.getCount() == 0) {
1078  if (RE.getKind() != RetEffect::NoRet) {
1079  if (!RE.isOwned()) {
1080 
1081  // The returning type is a CF, we expect the enclosing method should
1082  // return ownership.
1083  X = X ^ RefVal::ErrorLeakReturned;
1084 
1085  // Generate an error node.
1086  state = setRefBinding(state, Sym, X);
1087 
1088  static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
1089  ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
1090  if (N) {
1091  const LangOptions &LOpts = C.getASTContext().getLangOpts();
1092  auto R =
1093  llvm::make_unique<RefLeakReport>(leakAtReturn, LOpts, N, Sym, C);
1094  C.emitReport(std::move(R));
1095  }
1096  return N;
1097  }
1098  }
1099  } else if (X.isReturnedNotOwned()) {
1100  if (RE.isOwned()) {
1101  if (X.getIvarAccessHistory() ==
1103  // Assume the method was trying to transfer a +1 reference from a
1104  // strong ivar to the caller.
1105  state = setRefBinding(state, Sym,
1107  } else {
1108  // Trying to return a not owned object to a caller expecting an
1109  // owned object.
1110  state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
1111 
1112  static CheckerProgramPointTag
1113  ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
1114 
1115  ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
1116  if (N) {
1117  auto R = llvm::make_unique<RefCountReport>(
1118  returnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
1119  C.emitReport(std::move(R));
1120  }
1121  return N;
1122  }
1123  }
1124  }
1125  return Pred;
1126 }
1127 
1128 //===----------------------------------------------------------------------===//
1129 // Check various ways a symbol can be invalidated.
1130 //===----------------------------------------------------------------------===//
1131 
1133  CheckerContext &C) const {
1135  const MemRegion *MR = loc.getAsRegion();
1136 
1137  // Find all symbols referenced by 'val' that we are tracking
1138  // and stop tracking them.
1139  if (MR && shouldEscapeRegion(MR)) {
1140  state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1141  C.addTransition(state);
1142  }
1143 }
1144 
1146  SVal Cond,
1147  bool Assumption) const {
1148  // FIXME: We may add to the interface of evalAssume the list of symbols
1149  // whose assumptions have changed. For now we just iterate through the
1150  // bindings and check if any of the tracked symbols are NULL. This isn't
1151  // too bad since the number of symbols we will track in practice are
1152  // probably small and evalAssume is only called at branches and a few
1153  // other places.
1154  RefBindingsTy B = state->get<RefBindings>();
1155 
1156  if (B.isEmpty())
1157  return state;
1158 
1159  bool changed = false;
1160  RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1161  ConstraintManager &CMgr = state->getConstraintManager();
1162 
1163  for (auto &I : B) {
1164  // Check if the symbol is null stop tracking the symbol.
1165  ConditionTruthVal AllocFailed = CMgr.isNull(state, I.first);
1166  if (AllocFailed.isConstrainedTrue()) {
1167  changed = true;
1168  B = RefBFactory.remove(B, I.first);
1169  }
1170  }
1171 
1172  if (changed)
1173  state = state->set<RefBindings>(B);
1174 
1175  return state;
1176 }
1177 
1179  ProgramStateRef state, const InvalidatedSymbols *invalidated,
1180  ArrayRef<const MemRegion *> ExplicitRegions,
1181  ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx,
1182  const CallEvent *Call) const {
1183  if (!invalidated)
1184  return state;
1185 
1186  llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
1187 
1188  for (const MemRegion *I : ExplicitRegions)
1189  if (const SymbolicRegion *SR = I->StripCasts()->getAs<SymbolicRegion>())
1190  WhitelistedSymbols.insert(SR->getSymbol());
1191 
1192  for (SymbolRef sym : *invalidated) {
1193  if (WhitelistedSymbols.count(sym))
1194  continue;
1195  // Remove any existing reference-count binding.
1196  state = removeRefBinding(state, sym);
1197  }
1198  return state;
1199 }
1200 
1203  ExplodedNode *Pred,
1204  const ProgramPointTag *Tag,
1205  CheckerContext &Ctx,
1206  SymbolRef Sym,
1207  RefVal V,
1208  const ReturnStmt *S) const {
1209  unsigned ACnt = V.getAutoreleaseCount();
1210 
1211  // No autorelease counts? Nothing to be done.
1212  if (!ACnt)
1213  return state;
1214 
1215  unsigned Cnt = V.getCount();
1216 
1217  // FIXME: Handle sending 'autorelease' to already released object.
1218 
1219  if (V.getKind() == RefVal::ReturnedOwned)
1220  ++Cnt;
1221 
1222  // If we would over-release here, but we know the value came from an ivar,
1223  // assume it was a strong ivar that's just been relinquished.
1224  if (ACnt > Cnt &&
1226  V = V.releaseViaIvar();
1227  --ACnt;
1228  }
1229 
1230  if (ACnt <= Cnt) {
1231  if (ACnt == Cnt) {
1232  V.clearCounts();
1233  if (V.getKind() == RefVal::ReturnedOwned) {
1234  V = V ^ RefVal::ReturnedNotOwned;
1235  } else {
1236  V = V ^ RefVal::NotOwned;
1237  }
1238  } else {
1239  V.setCount(V.getCount() - ACnt);
1240  V.setAutoreleaseCount(0);
1241  }
1242  return setRefBinding(state, Sym, V);
1243  }
1244 
1245  // HACK: Ignore retain-count issues on values accessed through ivars,
1246  // because of cases like this:
1247  // [_contentView retain];
1248  // [_contentView removeFromSuperview];
1249  // [self addSubview:_contentView]; // invalidates 'self'
1250  // [_contentView release];
1252  return state;
1253 
1254  // Woah! More autorelease counts then retain counts left.
1255  // Emit hard error.
1257  state = setRefBinding(state, Sym, V);
1258 
1259  ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
1260  if (N) {
1261  SmallString<128> sbuf;
1262  llvm::raw_svector_ostream os(sbuf);
1263  os << "Object was autoreleased ";
1264  if (V.getAutoreleaseCount() > 1)
1265  os << V.getAutoreleaseCount() << " times but the object ";
1266  else
1267  os << "but ";
1268  os << "has a +" << V.getCount() << " retain count";
1269 
1270  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1271  auto R = llvm::make_unique<RefCountReport>(overAutorelease, LOpts, N, Sym,
1272  os.str());
1273  Ctx.emitReport(std::move(R));
1274  }
1275 
1276  return nullptr;
1277 }
1278 
1281  SymbolRef sid, RefVal V,
1282  SmallVectorImpl<SymbolRef> &Leaked) const {
1283  bool hasLeak;
1284 
1285  // HACK: Ignore retain-count issues on values accessed through ivars,
1286  // because of cases like this:
1287  // [_contentView retain];
1288  // [_contentView removeFromSuperview];
1289  // [self addSubview:_contentView]; // invalidates 'self'
1290  // [_contentView release];
1292  hasLeak = false;
1293  else if (V.isOwned())
1294  hasLeak = true;
1295  else if (V.isNotOwned() || V.isReturnedOwned())
1296  hasLeak = (V.getCount() > 0);
1297  else
1298  hasLeak = false;
1299 
1300  if (!hasLeak)
1301  return removeRefBinding(state, sid);
1302 
1303  Leaked.push_back(sid);
1304  return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
1305 }
1306 
1307 ExplodedNode *
1310  CheckerContext &Ctx,
1311  ExplodedNode *Pred) const {
1312  // Generate an intermediate node representing the leak point.
1313  ExplodedNode *N = Ctx.addTransition(state, Pred);
1314  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1315 
1316  if (N) {
1317  for (SymbolRef L : Leaked) {
1318  const RefCountBug &BT = Pred ? leakWithinFunction : leakAtReturn;
1319  Ctx.emitReport(llvm::make_unique<RefLeakReport>(BT, LOpts, N, L, Ctx));
1320  }
1321  }
1322 
1323  return N;
1324 }
1325 
1327  if (!Ctx.inTopFrame())
1328  return;
1329 
1330  RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
1331  const LocationContext *LCtx = Ctx.getLocationContext();
1332  const Decl *D = LCtx->getDecl();
1333  Optional<AnyCall> C = AnyCall::forDecl(D);
1334 
1335  if (!C || SmrMgr.isTrustedReferenceCountImplementation(D))
1336  return;
1337 
1338  ProgramStateRef state = Ctx.getState();
1339  const RetainSummary *FunctionSummary = SmrMgr.getSummary(*C);
1340  ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
1341 
1342  for (unsigned idx = 0, e = C->param_size(); idx != e; ++idx) {
1343  const ParmVarDecl *Param = C->parameters()[idx];
1344  SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1345 
1346  QualType Ty = Param->getType();
1347  const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
1348  if (AE) {
1349  ObjKind K = AE->getObjKind();
1350  if (K == ObjKind::Generalized || K == ObjKind::OS ||
1351  (TrackNSCFStartParam && (K == ObjKind::ObjC || K == ObjKind::CF))) {
1352  RefVal NewVal = AE->getKind() == DecRef ? RefVal::makeOwned(K, Ty)
1353  : RefVal::makeNotOwned(K, Ty);
1354  state = setRefBinding(state, Sym, NewVal);
1355  }
1356  }
1357  }
1358 
1359  Ctx.addTransition(state);
1360 }
1361 
1363  CheckerContext &Ctx) const {
1364  ExplodedNode *Pred = processReturn(RS, Ctx);
1365 
1366  // Created state cached out.
1367  if (!Pred) {
1368  return;
1369  }
1370 
1371  ProgramStateRef state = Pred->getState();
1372  RefBindingsTy B = state->get<RefBindings>();
1373 
1374  // Don't process anything within synthesized bodies.
1375  const LocationContext *LCtx = Pred->getLocationContext();
1376  if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
1377  assert(!LCtx->inTopFrame());
1378  return;
1379  }
1380 
1381  for (auto &I : B) {
1382  state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
1383  I.first, I.second);
1384  if (!state)
1385  return;
1386  }
1387 
1388  // If the current LocationContext has a parent, don't check for leaks.
1389  // We will do that later.
1390  // FIXME: we should instead check for imbalances of the retain/releases,
1391  // and suggest annotations.
1392  if (LCtx->getParent())
1393  return;
1394 
1395  B = state->get<RefBindings>();
1397 
1398  for (auto &I : B)
1399  state = handleSymbolDeath(state, I.first, I.second, Leaked);
1400 
1401  processLeaks(state, Leaked, Ctx, Pred);
1402 }
1403 
1405  CheckerContext &C) const {
1406  ExplodedNode *Pred = C.getPredecessor();
1407 
1410 
1411  // Update counts from autorelease pools
1412  for (const auto &I: state->get<RefBindings>()) {
1413  SymbolRef Sym = I.first;
1414  if (SymReaper.isDead(Sym)) {
1415  static CheckerProgramPointTag Tag(this, "DeadSymbolAutorelease");
1416  const RefVal &V = I.second;
1417  state = handleAutoreleaseCounts(state, Pred, &Tag, C, Sym, V);
1418  if (!state)
1419  return;
1420 
1421  // Fetch the new reference count from the state, and use it to handle
1422  // this symbol.
1423  state = handleSymbolDeath(state, Sym, *getRefBinding(state, Sym), Leaked);
1424  }
1425  }
1426 
1427  if (Leaked.empty()) {
1428  C.addTransition(state);
1429  return;
1430  }
1431 
1432  Pred = processLeaks(state, Leaked, C, Pred);
1433 
1434  // Did we cache out?
1435  if (!Pred)
1436  return;
1437 
1438  // Now generate a new node that nukes the old bindings.
1439  // The only bindings left at this point are the leaked symbols.
1440  RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1441  RefBindingsTy B = state->get<RefBindings>();
1442 
1443  for (SymbolRef L : Leaked)
1444  B = F.remove(B, L);
1445 
1446  state = state->set<RefBindings>(B);
1447  C.addTransition(state, Pred);
1448 }
1449 
1451  const char *NL, const char *Sep) const {
1452 
1453  RefBindingsTy B = State->get<RefBindings>();
1454 
1455  if (B.isEmpty())
1456  return;
1457 
1458  Out << Sep << NL;
1459 
1460  for (auto &I : B) {
1461  Out << I.first << " : ";
1462  I.second.print(Out);
1463  Out << NL;
1464  }
1465 }
1466 
1467 //===----------------------------------------------------------------------===//
1468 // Checker registration.
1469 //===----------------------------------------------------------------------===//
1470 
1471 void ento::registerRetainCountBase(CheckerManager &Mgr) {
1473 }
1474 
1475 bool ento::shouldRegisterRetainCountBase(const LangOptions &LO) {
1476  return true;
1477 }
1478 
1479 // FIXME: remove this, hack for backwards compatibility:
1480 // it should be possible to enable the NS/CF retain count checker as
1481 // osx.cocoa.RetainCount, and it should be possible to disable
1482 // osx.OSObjectRetainCount using osx.cocoa.RetainCount:CheckOSObject=false.
1483 static bool getOption(AnalyzerOptions &Options,
1484  StringRef Postfix,
1485  StringRef Value) {
1486  auto I = Options.Config.find(
1487  (StringRef("osx.cocoa.RetainCount:") + Postfix).str());
1488  if (I != Options.Config.end())
1489  return I->getValue() == Value;
1490  return false;
1491 }
1492 
1493 void ento::registerRetainCountChecker(CheckerManager &Mgr) {
1494  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1495  Chk->TrackObjCAndCFObjects = true;
1496  Chk->TrackNSCFStartParam = getOption(Mgr.getAnalyzerOptions(),
1497  "TrackNSCFStartParam",
1498  "true");
1499 }
1500 
1501 bool ento::shouldRegisterRetainCountChecker(const LangOptions &LO) {
1502  return true;
1503 }
1504 
1505 void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
1506  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1507  if (!getOption(Mgr.getAnalyzerOptions(),
1508  "CheckOSObject",
1509  "false"))
1510  Chk->TrackOSObjects = true;
1511 }
1512 
1513 bool ento::shouldRegisterOSObjectRetainCountChecker(const LangOptions &LO) {
1514  return true;
1515 }
Indicates that the tracked object is a generalized object.
Indicates that the tracked object is a CF object.
const BlockDecl * getBlockDecl() const
Definition: Expr.h:5488
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:1748
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:529
There is no effect.
ObjKind
Determines the object kind of a tracked object.
A (possibly-)qualified type.
Definition: Type.h:643
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
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:2606
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
Definition: Decl.h:4003
ProgramStateRef handleSymbolDeath(ProgramStateRef state, SymbolRef sid, RefVal V, SmallVectorImpl< SymbolRef > &Leaked) const
bool isDead(SymbolRef sym)
Returns whether or not a symbol has been confirmed dead.
The argument has its reference count decreased by 1 to model a transferred bridge cast under ARC...
bool evalCall(const CallExpr *CE, CheckerContext &C) const
Stmt - This represents one statement.
Definition: Stmt.h:66
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:505
Bridging via __bridge, which does nothing but reinterpret the bits.
static ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym)
All typestate tracking of the object ceases.
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:88
The argument has its reference count increased by 1.
StringRef P
static SmallVector< ProgramStateRef, 2 > updateOutParameters(ProgramStateRef State, const RetainSummary &Summ, const CallEvent &CE)
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const
The argument is treated as if an -autorelease message had been sent to the referenced object...
const ProgramStateRef & getState() const
Indicates that no retain count information is tracked for the return value.
static bool isSmartPtrField(const MemRegion *MR)
static bool isPointerToObject(QualType QT)
const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Definition: CallEvent.h:254
bool isConsumedExpr(Expr *E) const
Definition: ParentMap.cpp:159
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:6818
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:138
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:101
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:1564
const bool wasInlined
If we are post visiting a call, this flag will be set if the call was inlined.
Symbolic value.
Definition: SymExpr.h:29
const MemRegion * getSuperRegion() const
Definition: MemRegion.h:447
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:174
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
LineState State
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:49
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
Definition: ExprObjC.h:188
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
The argument has its reference count decreased by 1.
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +0 v...
static bool getOption(AnalyzerOptions &Options, StringRef Postfix, StringRef Value)
void checkPostCall(const CallEvent &Call, CheckerContext &C) const
bool hasNonZeroCallbackArg() const
Returns true if any of the arguments appear to represent callbacks.
Definition: CallEvent.cpp:153
Indicates that the return value is an owned object when the receiver is also a tracked object...
child_range children()
Definition: Stmt.cpp:212
const LocationContext * getLocationContext() const
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
bool isUnknown() const
Definition: SVals.h:136
SVal getReturnValue() const
Returns the return value of the call.
Definition: CallEvent.cpp:414
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3054
bool isScalarType() const
Definition: Type.h:6699
Represents an ObjC class declaration.
Definition: DeclObjC.h:1171
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC...
static bool shouldEscapeOSArgumentOnCall(const CallEvent &CE, unsigned ArgIdx, const RefVal *TrackedValue)
Whether the tracked value should be escaped on a given call.
virtual QualType getType() const =0
virtual ArrayRef< ParmVarDecl * > parameters() const =0
Return call&#39;s formal parameters.
static bool isReceiverUnconsumedSelf(const CallEvent &Call)
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:542
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
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1636
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...
static const RetainSummary * getSummary(RetainSummaryManager &Summaries, const CallEvent &Call, QualType ReceiverType)
IvarAccessHistory getIvarAccessHistory() const
Returns what the analyzer knows about direct accesses to a particular instance variable.
const RegionTy * getAs() const
Definition: MemRegion.h:1227
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:763
const LocationContext * getLocationContext() const
The context in which the call is being evaluated.
Definition: CallEvent.h:244
The argument is treated as potentially escaping, meaning that even when its reference count hits 0 it...
void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const
This represents one expression.
Definition: Expr.h:108
static bool shouldEscapeRegion(const MemRegion *R)
A value escapes in these possible cases:
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to...
Definition: Type.cpp:1621
bool isObjCRetainableType() const
Definition: Type.cpp:4028
#define V(N, I)
Definition: ASTContext.h:2905
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5474
#define bool
Definition: stdbool.h:15
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:304
void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const override
See CheckerManager::runCheckersForPrintState.
QualType getType() const
Definition: Expr.h:137
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called.
Definition: CallEvent.h:234
The argument is treated as if the referenced object was deallocated.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:2575
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:950
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...
ObjCBridgeCastKind getBridgeKind() const
Determine which kind of bridge is being performed via this cast.
Definition: ExprObjC.h:1665
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:708
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:111
const VarDecl * getDecl() const
Definition: MemRegion.h:949
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
Kind
ArgEffectKind getKind() const
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:2608
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:39
Indicates that the tracked object is an Objective-C object.
const MemRegion * getAsRegion() const
Definition: SVals.cpp:151
ConfigTable Config
A key-value table of use-specified configuration values.
ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, bool Assumption) const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:75
Performs the combined functionality of DecRef and StopTrackingHard.
bool isObjCObjectPointerType() const
Definition: Type.h:6455
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:124
unsigned blockCount() const
Returns the number of times the current block has been visited along the analyzed path...
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers...
Definition: ExprObjC.h:1638
static ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym, RefVal Val)
Dataflow Directional Tag Classes.
virtual SourceRange getArgSourceRange(unsigned Index) const
Returns the source range for errors associated with this argument.
Definition: CallEvent.cpp:407
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:845
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
const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1196
static RefVal makeOwned(ObjKind o, QualType t)
Create a state for an object whose lifetime is the responsibility of the current function, at least partially.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition: Expr.cpp:1398
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:170
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
AnalyzerOptions & getAnalyzerOptions()
const Decl * getDecl() const
Represents a pointer to an Objective C object.
Definition: Type.h:5849
const StackFrameContext * getStackFrame() const
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
const ProgramStateRef & getState() const
void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const
const RefVal * getRefBinding(ProgramStateRef State, SymbolRef Sym)
bool hasStackStorage() const
Definition: MemRegion.cpp:1140
Stores options for the analyzer from the command line.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:546
QualType getResultType() const
Returns the result type, adjusted for references.
Definition: CallEvent.cpp:69
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:14125
ArgEffect withKind(ArgEffectKind NewK)
All typestate tracking of the object ceases.
static RefVal makeNotOwned(ObjKind o, QualType t)
Create a state for an object whose lifetime is not the responsibility of the current function...
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
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:2449
const RefCountBug & errorKindToBugKind(RefVal::Kind ErrorKind, SymbolRef Sym) const
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:943
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
Definition: CallEvent.cpp:400
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.
An ArgEffect summarizes the retain count behavior on an argument or receiver to a function or method...
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.
AnalysisDeclContext * getAnalysisDeclContext() const
const LocationContext * getLocationContext() const
const LangOptions & getLangOpts() const
Definition: ASTContext.h:707
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.