clang  16.0.0git
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"
17 
18 using namespace clang;
19 using namespace ento;
20 using namespace retaincountchecker;
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 << " | ";
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 
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 
97  Out << "Use-After-Release [ERROR]";
98  break;
99 
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;
117  Out << " [direct ivar access]";
118  break;
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 
154  ProgramStateRef state = C.getState();
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();
168  MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
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 
210  ProgramStateRef state = C.getState();
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 {
231  ProgramStateRef state = C.getState();
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 
291  ProgramStateRef State = C.getState();
292  SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
293  if (!Sym || !isa_and_nonnull<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())
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 ||
317  isSynthesizedAccessor(C.getStackFrame())) {
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.
329  if (isSynthesizedAccessor(C.getStackFrame())) {
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()
345  ->getAnalysisDeclContext()
346  ->getParentMap()
347  .isConsumedExpr(Call.getOriginExpr());
348  }
349  return false;
350 }
351 
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 {
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 
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 std::nullopt;
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.
449  const CallEvent &CallOrMsg,
450  CheckerContext &C) const {
451  ProgramStateRef state = C.getState();
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 
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 
606  const CallEvent &CallOrMsg,
607  CheckerContext &C) const {
608  ProgramStateRef state = C.getState();
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)
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(), &getDeallocSentTag());
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  [[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);
830  V = V.releaseViaIvar() ^ RefVal::Released;
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,
861  RefVal::Kind ErrorKind,
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 = std::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 
890  CheckerContext &C) const {
891  ProgramStateRef state = C.getState();
892  const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
893  if (!FD)
894  return false;
895 
896  const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
897  if (!CE)
898  return false;
899 
901  QualType ResultTy = Call.getResultType();
902 
903  // See if the function has 'rc_ownership_trusted_implementation'
904  // annotate attribute. If it does, we will not inline it.
905  bool hasTrustedImplementationAnnotation = false;
906 
907  const LocationContext *LCtx = C.getLocationContext();
908 
909  using BehaviorSummary = RetainSummaryManager::BehaviorSummary;
911  SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation);
912 
913  // See if it's one of the specific functions we know how to eval.
914  if (!BSmr)
915  return false;
916 
917  // Bind the return value.
918  if (BSmr == BehaviorSummary::Identity ||
919  BSmr == BehaviorSummary::IdentityOrZero ||
920  BSmr == BehaviorSummary::IdentityThis) {
921 
922  const Expr *BindReturnTo =
923  (BSmr == BehaviorSummary::IdentityThis)
924  ? cast<CXXMemberCallExpr>(CE)->getImplicitObjectArgument()
925  : CE->getArg(0);
926  SVal RetVal = state->getSVal(BindReturnTo, LCtx);
927 
928  // If the receiver is unknown or the function has
929  // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
930  // return value.
931  // FIXME: this branch is very strange.
932  if (RetVal.isUnknown() ||
933  (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
934  SValBuilder &SVB = C.getSValBuilder();
935  RetVal =
936  SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
937  }
938 
939  // Bind the value.
940  state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
941 
942  if (BSmr == BehaviorSummary::IdentityOrZero) {
943  // Add a branch where the output is zero.
944  ProgramStateRef NullOutputState = C.getState();
945 
946  // Assume that output is zero on the other branch.
947  NullOutputState = NullOutputState->BindExpr(
948  CE, LCtx, C.getSValBuilder().makeNullWithType(ResultTy),
949  /*Invalidate=*/false);
950  C.addTransition(NullOutputState, &getCastFailTag());
951 
952  // And on the original branch assume that both input and
953  // output are non-zero.
954  if (auto L = RetVal.getAs<DefinedOrUnknownSVal>())
955  state = state->assume(*L, /*assumption=*/true);
956 
957  }
958  }
959 
960  C.addTransition(state);
961  return true;
962 }
963 
964 ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
965  CheckerContext &C) const {
966  ExplodedNode *Pred = C.getPredecessor();
967 
968  // Only adjust the reference count if this is the top-level call frame,
969  // and not the result of inlining. In the future, we should do
970  // better checking even for inlined calls, and see if they match
971  // with their expected semantics (e.g., the method should return a retained
972  // object, etc.).
973  if (!C.inTopFrame())
974  return Pred;
975 
976  if (!S)
977  return Pred;
978 
979  const Expr *RetE = S->getRetValue();
980  if (!RetE)
981  return Pred;
982 
983  ProgramStateRef state = C.getState();
984  // We need to dig down to the symbolic base here because various
985  // custom allocators do sometimes return the symbol with an offset.
986  SymbolRef Sym = state->getSValAsScalarOrLoc(RetE, C.getLocationContext())
987  .getAsLocSymbol(/*IncludeBaseRegions=*/true);
988  if (!Sym)
989  return Pred;
990 
991  // Get the reference count binding (if any).
992  const RefVal *T = getRefBinding(state, Sym);
993  if (!T)
994  return Pred;
995 
996  // Change the reference count.
997  RefVal X = *T;
998 
999  switch (X.getKind()) {
1000  case RefVal::Owned: {
1001  unsigned cnt = X.getCount();
1002  assert(cnt > 0);
1003  X.setCount(cnt - 1);
1005  break;
1006  }
1007 
1008  case RefVal::NotOwned: {
1009  unsigned cnt = X.getCount();
1010  if (cnt) {
1011  X.setCount(cnt - 1);
1013  } else {
1015  }
1016  break;
1017  }
1018 
1019  default:
1020  return Pred;
1021  }
1022 
1023  // Update the binding.
1024  state = setRefBinding(state, Sym, X);
1025  Pred = C.addTransition(state);
1026 
1027  // At this point we have updated the state properly.
1028  // Everything after this is merely checking to see if the return value has
1029  // been over- or under-retained.
1030 
1031  // Did we cache out?
1032  if (!Pred)
1033  return nullptr;
1034 
1035  // Update the autorelease counts.
1036  static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
1037  state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X, S);
1038 
1039  // Have we generated a sink node?
1040  if (!state)
1041  return nullptr;
1042 
1043  // Get the updated binding.
1044  T = getRefBinding(state, Sym);
1045  assert(T);
1046  X = *T;
1047 
1048  // Consult the summary of the enclosing method.
1050  const Decl *CD = &Pred->getCodeDecl();
1052 
1053  // FIXME: What is the convention for blocks? Is there one?
1054  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
1055  const RetainSummary *Summ = Summaries.getSummary(AnyCall(MD));
1056  RE = Summ->getRetEffect();
1057  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
1058  if (!isa<CXXMethodDecl>(FD)) {
1059  const RetainSummary *Summ = Summaries.getSummary(AnyCall(FD));
1060  RE = Summ->getRetEffect();
1061  }
1062  }
1063 
1064  return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
1065 }
1066 
1068  CheckerContext &C,
1069  ExplodedNode *Pred,
1070  RetEffect RE, RefVal X,
1071  SymbolRef Sym,
1072  ProgramStateRef state) const {
1073  // HACK: Ignore retain-count issues on values accessed through ivars,
1074  // because of cases like this:
1075  // [_contentView retain];
1076  // [_contentView removeFromSuperview];
1077  // [self addSubview:_contentView]; // invalidates 'self'
1078  // [_contentView release];
1079  if (X.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1080  return Pred;
1081 
1082  // Any leaks or other errors?
1083  if (X.isReturnedOwned() && X.getCount() == 0) {
1084  if (RE.getKind() != RetEffect::NoRet) {
1085  if (!RE.isOwned()) {
1086 
1087  // The returning type is a CF, we expect the enclosing method should
1088  // return ownership.
1090 
1091  // Generate an error node.
1092  state = setRefBinding(state, Sym, X);
1093 
1094  static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
1095  ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
1096  if (N) {
1097  const LangOptions &LOpts = C.getASTContext().getLangOpts();
1098  auto R =
1099  std::make_unique<RefLeakReport>(*LeakAtReturn, LOpts, N, Sym, C);
1100  C.emitReport(std::move(R));
1101  }
1102  return N;
1103  }
1104  }
1105  } else if (X.isReturnedNotOwned()) {
1106  if (RE.isOwned()) {
1107  if (X.getIvarAccessHistory() ==
1109  // Assume the method was trying to transfer a +1 reference from a
1110  // strong ivar to the caller.
1111  state = setRefBinding(state, Sym,
1112  X.releaseViaIvar() ^ RefVal::ReturnedOwned);
1113  } else {
1114  // Trying to return a not owned object to a caller expecting an
1115  // owned object.
1117 
1118  static CheckerProgramPointTag
1119  ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
1120 
1121  ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
1122  if (N) {
1123  auto R = std::make_unique<RefCountReport>(
1124  *ReturnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
1125  C.emitReport(std::move(R));
1126  }
1127  return N;
1128  }
1129  }
1130  }
1131  return Pred;
1132 }
1133 
1134 //===----------------------------------------------------------------------===//
1135 // Check various ways a symbol can be invalidated.
1136 //===----------------------------------------------------------------------===//
1137 
1139  CheckerContext &C) const {
1140  ProgramStateRef state = C.getState();
1141  const MemRegion *MR = loc.getAsRegion();
1142 
1143  // Find all symbols referenced by 'val' that we are tracking
1144  // and stop tracking them.
1145  if (MR && shouldEscapeRegion(MR)) {
1146  state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1147  C.addTransition(state);
1148  }
1149 }
1150 
1152  SVal Cond,
1153  bool Assumption) const {
1154  // FIXME: We may add to the interface of evalAssume the list of symbols
1155  // whose assumptions have changed. For now we just iterate through the
1156  // bindings and check if any of the tracked symbols are NULL. This isn't
1157  // too bad since the number of symbols we will track in practice are
1158  // probably small and evalAssume is only called at branches and a few
1159  // other places.
1160  RefBindingsTy B = state->get<RefBindings>();
1161 
1162  if (B.isEmpty())
1163  return state;
1164 
1165  bool changed = false;
1166  RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1167  ConstraintManager &CMgr = state->getConstraintManager();
1168 
1169  for (auto &I : B) {
1170  // Check if the symbol is null stop tracking the symbol.
1171  ConditionTruthVal AllocFailed = CMgr.isNull(state, I.first);
1172  if (AllocFailed.isConstrainedTrue()) {
1173  changed = true;
1174  B = RefBFactory.remove(B, I.first);
1175  }
1176  }
1177 
1178  if (changed)
1179  state = state->set<RefBindings>(B);
1180 
1181  return state;
1182 }
1183 
1185  ProgramStateRef state, const InvalidatedSymbols *invalidated,
1186  ArrayRef<const MemRegion *> ExplicitRegions,
1187  ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx,
1188  const CallEvent *Call) const {
1189  if (!invalidated)
1190  return state;
1191 
1192  llvm::SmallPtrSet<SymbolRef, 8> AllowedSymbols;
1193 
1194  for (const MemRegion *I : ExplicitRegions)
1195  if (const SymbolicRegion *SR = I->StripCasts()->getAs<SymbolicRegion>())
1196  AllowedSymbols.insert(SR->getSymbol());
1197 
1198  for (SymbolRef sym : *invalidated) {
1199  if (AllowedSymbols.count(sym))
1200  continue;
1201  // Remove any existing reference-count binding.
1202  state = removeRefBinding(state, sym);
1203  }
1204  return state;
1205 }
1206 
1209  ExplodedNode *Pred,
1210  const ProgramPointTag *Tag,
1211  CheckerContext &Ctx,
1212  SymbolRef Sym,
1213  RefVal V,
1214  const ReturnStmt *S) const {
1215  unsigned ACnt = V.getAutoreleaseCount();
1216 
1217  // No autorelease counts? Nothing to be done.
1218  if (!ACnt)
1219  return state;
1220 
1221  unsigned Cnt = V.getCount();
1222 
1223  // FIXME: Handle sending 'autorelease' to already released object.
1224 
1225  if (V.getKind() == RefVal::ReturnedOwned)
1226  ++Cnt;
1227 
1228  // If we would over-release here, but we know the value came from an ivar,
1229  // assume it was a strong ivar that's just been relinquished.
1230  if (ACnt > Cnt &&
1231  V.getIvarAccessHistory() == RefVal::IvarAccessHistory::AccessedDirectly) {
1232  V = V.releaseViaIvar();
1233  --ACnt;
1234  }
1235 
1236  if (ACnt <= Cnt) {
1237  if (ACnt == Cnt) {
1238  V.clearCounts();
1239  if (V.getKind() == RefVal::ReturnedOwned) {
1241  } else {
1242  V = V ^ RefVal::NotOwned;
1243  }
1244  } else {
1245  V.setCount(V.getCount() - ACnt);
1246  V.setAutoreleaseCount(0);
1247  }
1248  return setRefBinding(state, Sym, V);
1249  }
1250 
1251  // HACK: Ignore retain-count issues on values accessed through ivars,
1252  // because of cases like this:
1253  // [_contentView retain];
1254  // [_contentView removeFromSuperview];
1255  // [self addSubview:_contentView]; // invalidates 'self'
1256  // [_contentView release];
1257  if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1258  return state;
1259 
1260  // Woah! More autorelease counts then retain counts left.
1261  // Emit hard error.
1263  state = setRefBinding(state, Sym, V);
1264 
1265  ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
1266  if (N) {
1267  SmallString<128> sbuf;
1268  llvm::raw_svector_ostream os(sbuf);
1269  os << "Object was autoreleased ";
1270  if (V.getAutoreleaseCount() > 1)
1271  os << V.getAutoreleaseCount() << " times but the object ";
1272  else
1273  os << "but ";
1274  os << "has a +" << V.getCount() << " retain count";
1275 
1276  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1277  auto R = std::make_unique<RefCountReport>(*OverAutorelease, LOpts, N, Sym,
1278  os.str());
1279  Ctx.emitReport(std::move(R));
1280  }
1281 
1282  return nullptr;
1283 }
1284 
1287  SymbolRef sid, RefVal V,
1288  SmallVectorImpl<SymbolRef> &Leaked) const {
1289  bool hasLeak;
1290 
1291  // HACK: Ignore retain-count issues on values accessed through ivars,
1292  // because of cases like this:
1293  // [_contentView retain];
1294  // [_contentView removeFromSuperview];
1295  // [self addSubview:_contentView]; // invalidates 'self'
1296  // [_contentView release];
1297  if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1298  hasLeak = false;
1299  else if (V.isOwned())
1300  hasLeak = true;
1301  else if (V.isNotOwned() || V.isReturnedOwned())
1302  hasLeak = (V.getCount() > 0);
1303  else
1304  hasLeak = false;
1305 
1306  if (!hasLeak)
1307  return removeRefBinding(state, sid);
1308 
1309  Leaked.push_back(sid);
1310  return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
1311 }
1312 
1313 ExplodedNode *
1316  CheckerContext &Ctx,
1317  ExplodedNode *Pred) const {
1318  // Generate an intermediate node representing the leak point.
1319  ExplodedNode *N = Ctx.addTransition(state, Pred);
1320  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1321 
1322  if (N) {
1323  for (SymbolRef L : Leaked) {
1324  const RefCountBug &BT = Pred ? *LeakWithinFunction : *LeakAtReturn;
1325  Ctx.emitReport(std::make_unique<RefLeakReport>(BT, LOpts, N, L, Ctx));
1326  }
1327  }
1328 
1329  return N;
1330 }
1331 
1333  if (!Ctx.inTopFrame())
1334  return;
1335 
1336  RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
1337  const LocationContext *LCtx = Ctx.getLocationContext();
1338  const Decl *D = LCtx->getDecl();
1340 
1341  if (!C || SmrMgr.isTrustedReferenceCountImplementation(D))
1342  return;
1343 
1344  ProgramStateRef state = Ctx.getState();
1345  const RetainSummary *FunctionSummary = SmrMgr.getSummary(*C);
1346  ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
1347 
1348  for (unsigned idx = 0, e = C->param_size(); idx != e; ++idx) {
1349  const ParmVarDecl *Param = C->parameters()[idx];
1350  SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1351 
1352  QualType Ty = Param->getType();
1353  const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
1354  if (AE) {
1355  ObjKind K = AE->getObjKind();
1356  if (K == ObjKind::Generalized || K == ObjKind::OS ||
1357  (TrackNSCFStartParam && (K == ObjKind::ObjC || K == ObjKind::CF))) {
1358  RefVal NewVal = AE->getKind() == DecRef ? RefVal::makeOwned(K, Ty)
1359  : RefVal::makeNotOwned(K, Ty);
1360  state = setRefBinding(state, Sym, NewVal);
1361  }
1362  }
1363  }
1364 
1365  Ctx.addTransition(state);
1366 }
1367 
1369  CheckerContext &Ctx) const {
1370  ExplodedNode *Pred = processReturn(RS, Ctx);
1371 
1372  // Created state cached out.
1373  if (!Pred) {
1374  return;
1375  }
1376 
1377  ProgramStateRef state = Pred->getState();
1378  RefBindingsTy B = state->get<RefBindings>();
1379 
1380  // Don't process anything within synthesized bodies.
1381  const LocationContext *LCtx = Pred->getLocationContext();
1382  if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
1383  assert(!LCtx->inTopFrame());
1384  return;
1385  }
1386 
1387  for (auto &I : B) {
1388  state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
1389  I.first, I.second);
1390  if (!state)
1391  return;
1392  }
1393 
1394  // If the current LocationContext has a parent, don't check for leaks.
1395  // We will do that later.
1396  // FIXME: we should instead check for imbalances of the retain/releases,
1397  // and suggest annotations.
1398  if (LCtx->getParent())
1399  return;
1400 
1401  B = state->get<RefBindings>();
1403 
1404  for (auto &I : B)
1405  state = handleSymbolDeath(state, I.first, I.second, Leaked);
1406 
1407  processLeaks(state, Leaked, Ctx, Pred);
1408 }
1409 
1411  CheckerContext &C) const {
1412  ExplodedNode *Pred = C.getPredecessor();
1413 
1414  ProgramStateRef state = C.getState();
1416 
1417  // Update counts from autorelease pools
1418  for (const auto &I: state->get<RefBindings>()) {
1419  SymbolRef Sym = I.first;
1420  if (SymReaper.isDead(Sym)) {
1421  static CheckerProgramPointTag Tag(this, "DeadSymbolAutorelease");
1422  const RefVal &V = I.second;
1423  state = handleAutoreleaseCounts(state, Pred, &Tag, C, Sym, V);
1424  if (!state)
1425  return;
1426 
1427  // Fetch the new reference count from the state, and use it to handle
1428  // this symbol.
1429  state = handleSymbolDeath(state, Sym, *getRefBinding(state, Sym), Leaked);
1430  }
1431  }
1432 
1433  if (Leaked.empty()) {
1434  C.addTransition(state);
1435  return;
1436  }
1437 
1438  Pred = processLeaks(state, Leaked, C, Pred);
1439 
1440  // Did we cache out?
1441  if (!Pred)
1442  return;
1443 
1444  // Now generate a new node that nukes the old bindings.
1445  // The only bindings left at this point are the leaked symbols.
1446  RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1447  RefBindingsTy B = state->get<RefBindings>();
1448 
1449  for (SymbolRef L : Leaked)
1450  B = F.remove(B, L);
1451 
1452  state = state->set<RefBindings>(B);
1453  C.addTransition(state, Pred);
1454 }
1455 
1457  const char *NL, const char *Sep) const {
1458 
1459  RefBindingsTy B = State->get<RefBindings>();
1460 
1461  if (B.isEmpty())
1462  return;
1463 
1464  Out << Sep << NL;
1465 
1466  for (auto &I : B) {
1467  Out << I.first << " : ";
1468  I.second.print(Out);
1469  Out << NL;
1470  }
1471 }
1472 
1473 //===----------------------------------------------------------------------===//
1474 // Checker registration.
1475 //===----------------------------------------------------------------------===//
1476 
1477 std::unique_ptr<CheckerProgramPointTag> RetainCountChecker::DeallocSentTag;
1478 std::unique_ptr<CheckerProgramPointTag> RetainCountChecker::CastFailTag;
1479 
1480 void ento::registerRetainCountBase(CheckerManager &Mgr) {
1481  auto *Chk = Mgr.registerChecker<RetainCountChecker>();
1482  Chk->DeallocSentTag =
1483  std::make_unique<CheckerProgramPointTag>(Chk, "DeallocSent");
1484  Chk->CastFailTag =
1485  std::make_unique<CheckerProgramPointTag>(Chk, "DynamicCastFail");
1486 }
1487 
1488 bool ento::shouldRegisterRetainCountBase(const CheckerManager &mgr) {
1489  return true;
1490 }
1491 void ento::registerRetainCountChecker(CheckerManager &Mgr) {
1492  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1493  Chk->TrackObjCAndCFObjects = true;
1494  Chk->TrackNSCFStartParam = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
1495  Mgr.getCurrentCheckerName(), "TrackNSCFStartParam");
1496 
1497 #define INIT_BUGTYPE(KIND) \
1498  Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(), \
1499  RefCountBug::KIND);
1500  // TODO: Ideally, we should have a checker for each of these bug types.
1501  INIT_BUGTYPE(UseAfterRelease)
1502  INIT_BUGTYPE(ReleaseNotOwned)
1503  INIT_BUGTYPE(DeallocNotOwned)
1504  INIT_BUGTYPE(FreeNotOwned)
1505  INIT_BUGTYPE(OverAutorelease)
1506  INIT_BUGTYPE(ReturnNotOwnedForOwned)
1507  INIT_BUGTYPE(LeakWithinFunction)
1508  INIT_BUGTYPE(LeakAtReturn)
1509 #undef INIT_BUGTYPE
1510 }
1511 
1512 bool ento::shouldRegisterRetainCountChecker(const CheckerManager &mgr) {
1513  return true;
1514 }
1515 
1516 void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
1517  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1518  Chk->TrackOSObjects = true;
1519 
1520  // FIXME: We want bug reports to always have the same checker name associated
1521  // with them, yet here, if RetainCountChecker is disabled but
1522  // OSObjectRetainCountChecker is enabled, the checker names will be different.
1523  // This hack will make it so that the checker name depends on which checker is
1524  // enabled rather than on the registration order.
1525  // For the most part, we want **non-hidden checkers** to be associated with
1526  // diagnostics, and **hidden checker options** with the fine-tuning of
1527  // modeling. Following this logic, OSObjectRetainCountChecker should be the
1528  // latter, but we can't just remove it for backward compatibility reasons.
1529 #define LAZY_INIT_BUGTYPE(KIND) \
1530  if (!Chk->KIND) \
1531  Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(), \
1532  RefCountBug::KIND);
1533  LAZY_INIT_BUGTYPE(UseAfterRelease)
1534  LAZY_INIT_BUGTYPE(ReleaseNotOwned)
1535  LAZY_INIT_BUGTYPE(DeallocNotOwned)
1536  LAZY_INIT_BUGTYPE(FreeNotOwned)
1537  LAZY_INIT_BUGTYPE(OverAutorelease)
1538  LAZY_INIT_BUGTYPE(ReturnNotOwnedForOwned)
1539  LAZY_INIT_BUGTYPE(LeakWithinFunction)
1540  LAZY_INIT_BUGTYPE(LeakAtReturn)
1541 #undef LAZY_INIT_BUGTYPE
1542 }
1543 
1544 bool ento::shouldRegisterOSObjectRetainCountChecker(const CheckerManager &mgr) {
1545  return true;
1546 }
clang::ento::retaincountchecker::RetainCountChecker::processNonLeakError
void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange, RefVal::Kind ErrorKind, SymbolRef Sym, CheckerContext &C) const
Definition: RetainCountChecker.cpp:859
clang::ObjCInterfaceDecl
Represents an ObjC class declaration.
Definition: DeclObjC.h:1148
clang::ento::RetainSummaryManager::isTrustedReferenceCountImplementation
bool isTrustedReferenceCountImplementation(const Decl *FD)
Definition: RetainSummaryManager.cpp:716
clang::ObjCBoxedExpr
ObjCBoxedExpr - used for generalized expression boxing.
Definition: ExprObjC.h:128
clang::ento::RetainedOutParameter
@ RetainedOutParameter
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
Definition: RetainSummaryManager.h:80
clang::ento::ObjKind::CF
@ CF
Indicates that the tracked object is a CF object.
clang::ento::retaincountchecker::RetainCountChecker::DeallocSentTag
static std::unique_ptr< CheckerProgramPointTag > DeallocSentTag
Definition: RetainCountChecker.h:266
clang::ento::ExplodedNode::getLocationContext
const LocationContext * getLocationContext() const
Definition: ExplodedGraph.h:146
clang::ento::SymbolVisitor
Definition: SymbolManager.h:666
clang::LocationContext
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Definition: AnalysisDeclContext.h:215
clang::Type::isObjCRetainableType
bool isObjCRetainableType() const
Definition: Type.cpp:4385
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:210
clang::Decl::hasAttr
bool hasAttr() const
Definition: DeclBase.h:560
clang::ento::CheckerManager::registerChecker
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
Definition: CheckerManager.h:204
clang::ento::ArgEffects
llvm::ImmutableMap< unsigned, ArgEffect > ArgEffects
ArgEffects summarizes the effects of a function/method call on all of its arguments.
Definition: RetainSummaryManager.h:279
GetReturnType
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...
Definition: RetainCountChecker.cpp:394
clang::ento::retaincountchecker::RetainCountChecker::getDeallocSentTag
static const CheckerProgramPointTag & getDeallocSentTag()
Definition: RetainCountChecker.h:363
clang::ento::SVal::getAsRegion
const MemRegion * getAsRegion() const
Definition: SVals.cpp:120
clang::ento::ObjKind
ObjKind
Determines the object kind of a tracked object.
Definition: RetainSummaryManager.h:35
clang::ento::ConstraintManager
Definition: ConstraintManager.h:69
clang::ento::CheckerManager::getCurrentCheckerName
CheckerNameRef getCurrentCheckerName() const
Definition: CheckerManager.h:163
clang::ProgramPointTag
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
Definition: ProgramPoint.h:38
clang::ento::CallEvent::getOriginExpr
virtual const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Definition: CallEvent.h:240
clang::ento::DefinedOrUnknownSVal
Definition: SVals.h:221
llvm::SmallVector
Definition: LLVM.h:38
clang::ento::MemRegion::StripCasts
const LLVM_ATTRIBUTE_RETURNS_NONNULL MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1342
clang::ento::CheckerContext::getLocationContext
const LocationContext * getLocationContext() const
Definition: CheckerContext.h:93
clang::ento::ArgEffect::getKind
ArgEffectKind getKind() const
Definition: RetainSummaryManager.h:125
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::Type::isScalarType
bool isScalarType() const
Definition: Type.h:7267
clang::ento::retaincountchecker::RetainCountChecker::checkSummary
void checkSummary(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const
Definition: RetainCountChecker.cpp:605
shouldEscapeOSArgumentOnCall
static bool shouldEscapeOSArgumentOnCall(const CallEvent &CE, unsigned ArgIdx, const RefVal *TrackedValue)
Whether the tracked value should be escaped on a given call.
Definition: RetainCountChecker.cpp:436
clang::ObjCBridgedCastExpr
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
Definition: ExprObjC.h:1626
AttributeLangSupport::C
@ C
Definition: SemaDeclAttr.cpp:56
clang::ento::CheckerManager::getAnalyzerOptions
const AnalyzerOptions & getAnalyzerOptions() const
Definition: CheckerManager.h:170
clang::OBC_BridgeRetained
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
Definition: OperationKinds.h:45
clang::OMF_init
@ OMF_init
Definition: IdentifierTable.h:707
clang::ento::ExplodedNode
Definition: ExplodedGraph.h:65
clang::AnyCall::forDecl
static Optional< AnyCall > forDecl(const Decl *D)
If D is a callable (Objective-C method or a function), return a constructed AnyCall object.
Definition: AnyCall.h:133
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1712
clang::ento::retaincountchecker::RefVal::makeNotOwned
static RefVal makeNotOwned(ObjKind o, QualType t)
Create a state for an object whose lifetime is not the responsibility of the current function.
Definition: RetainCountChecker.h:180
llvm::Optional
Definition: LLVM.h:40
llvm::SmallPtrSet
Definition: ASTContext.h:55
clang::ento::retaincountchecker::RetainCountChecker::OverAutorelease
std::unique_ptr< RefCountBug > OverAutorelease
Definition: RetainCountChecker.h:259
clang::ento::retaincountchecker::RefVal::ErrorLeakReturned
@ ErrorLeakReturned
Definition: RetainCountChecker.h:65
clang::ento::RetEffect::MakeNoRet
static RetEffect MakeNoRet()
Definition: RetainSummaryManager.h:198
clang::tooling::X
static ToolExecutorPluginRegistry::Add< AllTUsToolExecutorPlugin > X("all-TUs", "Runs FrontendActions on all TUs in the compilation database. " "Tool results are stored in memory.")
clang::ento::DecRefAndStopTrackingHard
@ DecRefAndStopTrackingHard
Performs the combined functionality of DecRef and StopTrackingHard.
Definition: RetainSummaryManager.h:113
clang::ento::RetEffect::OwnedWhenTrackedReceiver
@ OwnedWhenTrackedReceiver
Indicates that the return value is an owned object when the receiver is also a tracked object.
Definition: RetainSummaryManager.h:156
clang::ento::retaincountchecker::RetainCountChecker::checkPostStmt
void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const
Definition: RetainCountChecker.cpp:146
setRefBinding
static ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym, RefVal Val)
Definition: RetainCountChecker.cpp:36
clang::ento::MemRegionManager::getVarRegion
const VarRegion * getVarRegion(const VarDecl *VD, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
Definition: MemRegion.cpp:964
clang::ento::CheckerContext::getState
const ProgramStateRef & getState() const
Definition: CheckerContext.h:71
clang::ento::retaincountchecker::RetainCountChecker::printState
void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const override
See CheckerManager::runCheckersForPrintState.
Definition: RetainCountChecker.cpp:1456
isReceiverUnconsumedSelf
static bool isReceiverUnconsumedSelf(const CallEvent &Call)
Definition: RetainCountChecker.cpp:338
clang::ento::retaincountchecker::RefVal::ErrorUseAfterRelease
@ ErrorUseAfterRelease
Definition: RetainCountChecker.h:61
clang::ento::retaincountchecker::getRefBinding
const RefVal * getRefBinding(ProgramStateRef State, SymbolRef Sym)
Definition: RetainCountChecker.cpp:28
clang::ento::SVal::getAs
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type.
Definition: SVals.h:104
clang::ento::BlockDataRegion::referenced_vars_iterator::getCapturedRegion
const LLVM_ATTRIBUTE_RETURNS_NONNULL VarRegion * getCapturedRegion() const
Definition: MemRegion.h:718
clang::ento::retaincountchecker::RefVal::ErrorLeak
@ ErrorLeak
Definition: RetainCountChecker.h:64
CallEvent.h
clang::ObjCArrayLiteral
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition: ExprObjC.h:190
clang::ento::Autorelease
@ Autorelease
The argument is treated as if an -autorelease message had been sent to the referenced object.
Definition: RetainSummaryManager.h:59
clang::ento::retaincountchecker::RetainCountChecker::checkEndFunction
void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const
Definition: RetainCountChecker.cpp:1368
clang::ento::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:95
clang::ento::retaincountchecker::RetainCountChecker::processObjCLiterals
void processObjCLiterals(CheckerContext &C, const Expr *Ex) const
Definition: RetainCountChecker.cpp:229
clang::ento::ConditionTruthVal
Definition: ConstraintManager.h:38
REGISTER_MAP_WITH_PROGRAMSTATE
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
Definition: ProgramStateTrait.h:87
clang::ento::SVal::getAsLocSymbol
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
Definition: SVals.cpp:68
clang::ento::SymbolReaper::isDead
bool isDead(SymbolRef sym)
Returns whether or not a symbol has been confirmed dead.
Definition: SymbolManager.h:643
V
#define V(N, I)
Definition: ASTContext.h:3208
clang::ento::CallEvent::getReturnValue
SVal getReturnValue() const
Returns the return value of the call.
Definition: CallEvent.cpp:320
clang::ento::ExplodedNode::getState
const ProgramStateRef & getState() const
Definition: ExplodedGraph.h:168
clang::ento::CallEvent::parameters
virtual ArrayRef< ParmVarDecl * > parameters() const =0
Return call's formal parameters.
clang::ento::retaincountchecker::RetainCountChecker::processSummaryOfInlined
void processSummaryOfInlined(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const
Definition: RetainCountChecker.cpp:448
clang::ento::CallEvent::getArgSourceRange
virtual SourceRange getArgSourceRange(unsigned Index) const
Returns the source range for errors associated with this argument.
Definition: CallEvent.cpp:313
clang::AnyCall
An instance of this class corresponds to a call.
Definition: AnyCall.h:25
clang::ento::RetainSummaryManager::canEval
Optional< BehaviorSummary > canEval(const CallExpr *CE, const FunctionDecl *FD, bool &hasTrustedImplementationAnnotation)
Definition: RetainSummaryManager.cpp:722
clang::ento::retaincountchecker::RetainCountChecker::checkBind
void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const
Definition: RetainCountChecker.cpp:1138
clang::ento::RetEffect::notOwned
bool notOwned() const
Definition: RetainSummaryManager.h:180
clang::ento::RetainSummaryManager::getSummary
const RetainSummary * getSummary(AnyCall C, bool HasNonZeroCallbackArg=false, bool IsReceiverUnconsumedSelf=false, QualType ReceiverType={})
Definition: RetainSummaryManager.cpp:665
clang::ento::SymExpr::getType
virtual QualType getType() const =0
clang::ento::RetEffect::getObjKind
ObjKind getObjKind() const
Definition: RetainSummaryManager.h:174
isSmartPtrField
static bool isSmartPtrField(const MemRegion *MR)
Definition: RetainCountChecker.cpp:488
clang::ento::DoNothing
@ DoNothing
There is no effect.
Definition: RetainSummaryManager.h:55
clang::ento::BlockDataRegion::referenced_vars_iterator
Definition: MemRegion.h:708
clang::ento::MayEscape
@ MayEscape
The argument is treated as potentially escaping, meaning that even when its reference count hits 0 it...
Definition: RetainSummaryManager.h:93
clang::ento::SymExpr::getOriginRegion
virtual const MemRegion * getOriginRegion() const
Find the region from which this symbol originates.
Definition: SymExpr.h:102
isPointerToObject
static bool isPointerToObject(QualType QT)
Definition: RetainCountChecker.cpp:426
clang::ento::retaincountchecker::RefVal::getCount
unsigned getCount() const
Definition: RetainCountChecker.h:127
clang::BlockExpr::getBlockDecl
const BlockDecl * getBlockDecl() const
Definition: Expr.h:5987
clang::ento::retaincountchecker::RetainCountChecker::errorKindToBugKind
const RefCountBug & errorKindToBugKind(RefVal::Kind ErrorKind, SymbolRef Sym) const
Definition: RetainCountChecker.cpp:843
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
clang::ObjCDictionaryLiteral
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:306
clang::ento::SymExpr
Symbolic value.
Definition: SymExpr.h:29
clang::ento::retaincountchecker::RefVal::getIvarAccessHistory
IvarAccessHistory getIvarAccessHistory() const
Returns what the analyzer knows about direct accesses to a particular instance variable.
Definition: RetainCountChecker.h:148
clang::ento::RetEffect::getKind
Kind getKind() const
Definition: RetainSummaryManager.h:172
clang::ento::retaincountchecker::RefVal::Owned
@ Owned
Definition: RetainCountChecker.h:54
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7386
clang::ento::retaincountchecker::RetainCountChecker::getSummaryManager
RetainSummaryManager & getSummaryManager(ASTContext &Ctx) const
Definition: RetainCountChecker.h:280
clang::ento::RetainSummary::getRetEffect
RetEffect getRetEffect() const
getRetEffect - Returns the effect on the return value of the call.
Definition: RetainSummaryManager.h:331
clang::ento::retaincountchecker::RefVal::IvarAccessHistory::AccessedDirectly
@ AccessedDirectly
clang::ento::retaincountchecker::RetainCountChecker::evalAssume
ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, bool Assumption) const
Definition: RetainCountChecker.cpp:1151
clang::ento::retaincountchecker::RefVal::getKind
Kind getKind() const
Definition: RetainCountChecker.h:121
clang::ASTContext::getObjCInterfaceType
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
Definition: ASTContext.cpp:5629
clang::Type::getPointeeCXXRecordDecl
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
Definition: Type.cpp:1745
clang::ento::retaincountchecker::RefVal::ErrorOverAutorelease
@ ErrorOverAutorelease
Definition: RetainCountChecker.h:67
clang::Stmt::children
child_range children()
Definition: Stmt.cpp:285
clang::ento::RetainSummary::getReceiverEffect
ArgEffect getReceiverEffect() const
getReceiverEffect - Returns the effect on the receiver of the call.
Definition: RetainSummaryManager.h:342
clang::ento::CheckerContext::addTransition
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
Definition: CheckerContext.h:168
clang::ento::VarRegion
Definition: MemRegion.h:940
clang::ento::retaincountchecker::RetainCountChecker::evalCall
bool evalCall(const CallEvent &Call, CheckerContext &C) const
Definition: RetainCountChecker.cpp:889
llvm::SmallString< 128 >
LAZY_INIT_BUGTYPE
#define LAZY_INIT_BUGTYPE(KIND)
shouldEscapeRegion
static bool shouldEscapeRegion(const MemRegion *R)
A value escapes in these possible cases:
Definition: RetainCountChecker.cpp:505
bool
#define bool
Definition: stdbool.h:20
clang::ento::RetainSummary::getThisEffect
ArgEffect getThisEffect() const
Definition: RetainSummaryManager.h:346
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:906
clang::ento::CheckerContext::emitReport
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
Definition: CheckerContext.h:244
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:625
clang::ento::retaincountchecker::RetainCountChecker::DeallocNotOwned
std::unique_ptr< RefCountBug > DeallocNotOwned
Definition: RetainCountChecker.h:257
clang::ento::SymbolReaper
A class responsible for cleaning up unused symbols.
Definition: SymbolManager.h:572
llvm::DenseSet< SymbolRef >
clang::Type::getAsCXXRecordDecl
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1760
clang::ento::CheckerContext::inTopFrame
bool inTopFrame() const
Return true if the current LocationContext has no caller context.
Definition: CheckerContext.h:102
clang::ento::retaincountchecker::RefVal::IvarAccessHistory::None
@ None
clang::ento::StopTracking
@ StopTracking
All typestate tracking of the object ceases.
Definition: RetainSummaryManager.h:97
clang::AnyCall::forExpr
static Optional< AnyCall > forExpr(const Expr *E)
If E is a generic call (to ObjC method /function/block/etc), return a constructed AnyCall object.
Definition: AnyCall.h:112
clang::ObjCMessageExpr
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:941
clang::ento::SymbolicRegion
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:770
state
and static some checkers Checker The latter are built on top of the former via the Checker and CheckerVisitor and attempts to isolate them from much of the gore of the internal analysis the analyzer is basically a source code simulator that traces out possible paths of execution The state of the and the combination of state and program point is a node in an exploded which has the entry program point and initial state
Definition: README.txt:30
clang::ento::Loc
Definition: SVals.h:282
removeRefBinding
static ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym)
Definition: RetainCountChecker.cpp:42
clang::ento::retaincountchecker::RefVal::makeOwned
static RefVal makeOwned(ObjKind o, QualType t)
Create a state for an object whose lifetime is the responsibility of the current function,...
Definition: RetainCountChecker.h:172
clang::Type::isObjCObjectPointerType
bool isObjCObjectPointerType() const
Definition: Type.h:7011
clang::ento::ConditionTruthVal::isConstrainedTrue
bool isConstrainedTrue() const
Return true if the constraint is perfectly constrained to 'true'.
Definition: ConstraintManager.h:56
clang::ento::Dealloc
@ Dealloc
The argument is treated as if the referenced object was deallocated.
Definition: RetainSummaryManager.h:62
clang::ento::retaincountchecker::RefVal::Kind
Kind
Definition: RetainCountChecker.h:53
clang::BlockDecl::hasCaptures
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
Definition: Decl.h:4430
clang::ento::SValBuilder
Definition: SValBuilder.h:53
RetainCountChecker.h
clang::ento::retaincountchecker::RetainCountChecker
Definition: RetainCountChecker.h:238
clang::ento::CheckerManager::getChecker
CHECKER * getChecker()
Definition: CheckerManager.h:218
clang::ento::MemRegion::getAs
const RegionTy * getAs() const
Definition: MemRegion.h:1337
clang::ObjCObjectPointerType
Represents a pointer to an Objective C object.
Definition: Type.h:6270
clang::ento::retaincountchecker::RetainCountChecker::UseAfterRelease
std::unique_ptr< RefCountBug > UseAfterRelease
Definition: RetainCountChecker.h:255
clang::ento::retaincountchecker::isSynthesizedAccessor
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...
Definition: RetainCountChecker.h:384
clang::ento::retaincountchecker::RefVal::IvarAccessHistory::ReleasedAfterDirectAccess
@ ReleasedAfterDirectAccess
clang::ento::RetainSummaryManager::isKnownSmartPointer
static bool isKnownSmartPointer(QualType QT)
Definition: RetainSummaryManager.cpp:228
clang::ento::MemRegion::hasStackStorage
bool hasStackStorage() const
Definition: MemRegion.cpp:1289
P
StringRef P
Definition: ASTMatchersInternal.cpp:564
clang::ento::retaincountchecker::RetainCountChecker::LeakWithinFunction
std::unique_ptr< RefCountBug > LeakWithinFunction
Definition: RetainCountChecker.h:261
clang::ento::retaincountchecker::RetainCountChecker::CastFailTag
static std::unique_ptr< CheckerProgramPointTag > CastFailTag
Definition: RetainCountChecker.h:267
clang::ento::DecRef
@ DecRef
The argument has its reference count decreased by 1.
Definition: RetainSummaryManager.h:65
clang::ento::CheckerContext::getASTContext
ASTContext & getASTContext()
Definition: CheckerContext.h:83
clang::ento::RetainSummaryManager::BehaviorSummary
BehaviorSummary
Definition: RetainSummaryManager.h:637
clang::OBC_BridgeTransfer
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
Definition: OperationKinds.h:42
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:802
clang::BlockExpr
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5975
llvm::ArrayRef
Definition: LLVM.h:34
clang::ento::ObjKind::Generalized
@ Generalized
Indicates that the tracked object is a generalized object.
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::ento::coreFoundation::isCFObjectRef
bool isCFObjectRef(QualType T)
Definition: CocoaConventions.cpp:57
clang::ento::ObjKind::ObjC
@ ObjC
Indicates that the tracked object is an Objective-C object.
State
LineState State
Definition: UnwrappedLineFormatter.cpp:1147
clang::ento::retaincountchecker::RefVal
Metadata on reference.
Definition: RetainCountChecker.h:51
clang::ento::RetEffect::isOwned
bool isOwned() const
Definition: RetainSummaryManager.h:176
clang::ento::retaincountchecker::RefVal::ReturnedNotOwned
@ ReturnedNotOwned
Definition: RetainCountChecker.h:58
clang::ento::StopTrackingHard
@ StopTrackingHard
All typestate tracking of the object ceases.
Definition: RetainSummaryManager.h:106
clang::ento::RetainSummary
Summary for a function with respect to ownership changes.
Definition: RetainSummaryManager.h:282
clang::ento::CallEvent::getNumArgs
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
refValFromRetEffect
static Optional< RefVal > refValFromRetEffect(RetEffect RE, QualType ResultTy)
Definition: RetainCountChecker.cpp:415
clang::ento::retaincountchecker::RefVal::NotOwned
@ NotOwned
Definition: RetainCountChecker.h:55
clang::ento::RetainedOutParameterOnNonZero
@ RetainedOutParameterOnNonZero
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
Definition: RetainSummaryManager.h:88
clang::ento::retaincountchecker::RetainCountChecker::checkReturnWithRetEffect
ExplodedNode * checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, ExplodedNode *Pred, RetEffect RE, RefVal X, SymbolRef Sym, ProgramStateRef state) const
Definition: RetainCountChecker.cpp:1067
clang::ento::UnretainedOutParameter
@ UnretainedOutParameter
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +0 v...
Definition: RetainSummaryManager.h:76
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:81
clang::ento::CallEvent::getResultType
QualType getResultType() const
Returns the result type, adjusted for references.
Definition: CallEvent.cpp:72
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::ento::RetainSummary::getArgEffects
ArgEffects getArgEffects() const
Definition: RetainSummaryManager.h:381
clang::AnalyzerOptions::getCheckerBooleanOption
bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName, bool SearchInParents=false) const
Interprets an option's string value as a boolean.
Definition: AnalyzerOptions.cpp:160
clang::ento::MemRegionManager
Definition: MemRegion.h:1353
Checker.h
std
Definition: Format.h:4477
clang::ento::retaincountchecker::RetainCountChecker::ReturnNotOwnedForOwned
std::unique_ptr< RefCountBug > ReturnNotOwnedForOwned
Definition: RetainCountChecker.h:260
clang::ObjCMethodDecl
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
clang::ento::ArgEffect::withKind
ArgEffect withKind(ArgEffectKind NewK)
Definition: RetainSummaryManager.h:128
clang::ento::retaincountchecker::RetainCountChecker::Summaries
std::unique_ptr< RetainSummaryManager > Summaries
Definition: RetainCountChecker.h:264
clang::ento::retaincountchecker::RetainCountChecker::LeakAtReturn
std::unique_ptr< RefCountBug > LeakAtReturn
Definition: RetainCountChecker.h:262
clang::ento::CheckerManager
Definition: CheckerManager.h:126
clang
Definition: CalledOnceCheck.h:17
clang::ento::RetainedOutParameterOnZero
@ RetainedOutParameterOnZero
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
Definition: RetainSummaryManager.h:84
clang::ento::CheckerProgramPointTag
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
Definition: Checker.h:510
clang::ento::RetEffect::NoRet
@ NoRet
Indicates that no retain count information is tracked for the return value.
Definition: RetainSummaryManager.h:144
clang::ento::RetainSummaryManager
Definition: RetainSummaryManager.h:449
clang::ento::ArgEffect::getObjKind
ObjKind getObjKind() const
Definition: RetainSummaryManager.h:126
clang::ento::retaincountchecker::RefVal::ErrorDeallocNotOwned
@ ErrorDeallocNotOwned
Definition: RetainCountChecker.h:60
clang::ento::retaincountchecker::RetainCountChecker::checkBeginFunction
void checkBeginFunction(CheckerContext &C) const
Definition: RetainCountChecker.cpp:1332
clang::ento::ArgEffect
An ArgEffect summarizes the retain count behavior on an argument or receiver to a function or method.
Definition: RetainSummaryManager.h:118
clang::ento::RetainSummaryManager::getObjAllocRetEffect
RetEffect getObjAllocRetEffect() const
Definition: RetainSummaryManager.h:665
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:71
clang::ento::RetEffect::NoRetHard
@ NoRetHard
Definition: RetainSummaryManager.h:162
clang::ento::CheckerContext::generateSink
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a sink node.
Definition: CheckerContext.h:188
clang::ento::retaincountchecker::RefVal::ErrorReleaseNotOwned
@ ErrorReleaseNotOwned
Definition: RetainCountChecker.h:62
clang::ento::CallEvent
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:148
clang::ento::SVal::isUnknown
bool isUnknown() const
Definition: SVals.h:125
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::ento::ExplodedNode::getSVal
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
Definition: ExplodedGraph.h:175
clang::ento::SubRegion::getSuperRegion
const LLVM_ATTRIBUTE_RETURNS_NONNULL MemRegion * getSuperRegion() const
Definition: MemRegion.h:455
clang::ento::retaincountchecker::RefCountBug
Definition: RetainCountDiagnostics.h:27
clang::ento::retaincountchecker::RefVal::print
void print(raw_ostream &Out) const
Definition: RetainCountChecker.cpp:46
clang::ento::CallEvent::getArgSVal
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
Definition: CallEvent.cpp:306
clang::ento::RetEffect
RetEffect summarizes a call's retain/release behavior with respect to its return value.
Definition: RetainSummaryManager.h:139
clang::ento::retaincountchecker::RetainCountChecker::checkDeadSymbols
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const
Definition: RetainCountChecker.cpp:1410
clang::ento::CheckerContext
Definition: CheckerContext.h:23
clang::ento::SVal
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:73
clang::ento::RetainSummary::getArg
ArgEffect getArg(unsigned idx) const
getArg - Return the argument effect on the argument specified by idx (starting from 0).
Definition: RetainSummaryManager.h:314
clang::ento::retaincountchecker::RefVal::ErrorReturnedNotOwned
@ ErrorReturnedNotOwned
Definition: RetainCountChecker.h:68
clang::ento::IncRef
@ IncRef
The argument has its reference count increased by 1.
Definition: RetainSummaryManager.h:72
clang::ento::DecRefBridgedTransferred
@ DecRefBridgedTransferred
The argument has its reference count decreased by 1 to model a transferred bridge cast under ARC.
Definition: RetainSummaryManager.h:69
clang::ento::retaincountchecker::RefVal::ReturnedOwned
@ ReturnedOwned
Definition: RetainCountChecker.h:57
clang::ento::retaincountchecker::RefVal::withIvarAccess
RefVal withIvarAccess() const
Definition: RetainCountChecker.h:204
clang::ento::retaincountchecker::RetainCountChecker::handleSymbolDeath
ProgramStateRef handleSymbolDeath(ProgramStateRef state, SymbolRef sid, RefVal V, SmallVectorImpl< SymbolRef > &Leaked) const
Definition: RetainCountChecker.cpp:1286
llvm::SmallVectorImpl
Definition: Randstruct.h:18
clang::ObjCBridgedCastExpr::getBridgeKind
ObjCBridgeCastKind getBridgeKind() const
Determine which kind of bridge is being performed via this cast.
Definition: ExprObjC.h:1653
clang::ento::ExplodedNode::getCodeDecl
const Decl & getCodeDecl() const
Definition: ExplodedGraph.h:154
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:712
clang::ento::retaincountchecker::RetainCountChecker::updateSymbol
ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym, RefVal V, ArgEffect E, RefVal::Kind &hasErr, CheckerContext &C) const
Definition: RetainCountChecker.cpp:711
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::ento::retaincountchecker::RetainCountChecker::checkRegionChanges
ProgramStateRef checkRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call) const
Definition: RetainCountChecker.cpp:1184
clang::ento::SVal::getAsSymbol
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
Definition: SVals.cpp:104
clang::ento::SValBuilder::conjureSymbolVal
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
clang::ento::retaincountchecker::RetainCountChecker::processLeaks
ExplodedNode * processLeaks(ProgramStateRef state, SmallVectorImpl< SymbolRef > &Leaked, CheckerContext &Ctx, ExplodedNode *Pred=nullptr) const
Definition: RetainCountChecker.cpp:1314
updateOutParameters
static SmallVector< ProgramStateRef, 2 > updateOutParameters(ProgramStateRef State, const RetainSummary &Summ, const CallEvent &CE)
Definition: RetainCountChecker.cpp:521
clang::ASTContext::getObjCObjectPointerType
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
Definition: ASTContext.cpp:5599
clang::ento::retaincountchecker::RetainCountChecker::TrackNSCFStartParam
bool TrackNSCFStartParam
Track initial parameters (for the entry point) for NS/CF objects.
Definition: RetainCountChecker.h:276
clang::CastExpr
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3480
clang::ento::retaincountchecker::RetainCountChecker::handleAutoreleaseCounts
ProgramStateRef handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred, const ProgramPointTag *Tag, CheckerContext &Ctx, SymbolRef Sym, RefVal V, const ReturnStmt *S=nullptr) const
Definition: RetainCountChecker.cpp:1208
clang::ento::retaincountchecker::RetainCountChecker::checkPostCall
void checkPostCall(const CallEvent &Call, CheckerContext &C) const
Definition: RetainCountChecker.cpp:363
clang::LocationContext::getDecl
const Decl * getDecl() const
Definition: AnalysisDeclContext.h:251
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1904
clang::OBC_Bridge
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
Definition: OperationKinds.h:39
clang::ento::ConstraintManager::isNull
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...
Definition: ConstraintManager.h:127
clang::ento::retaincountchecker::RetainCountChecker::ReleaseNotOwned
std::unique_ptr< RefCountBug > ReleaseNotOwned
Definition: RetainCountChecker.h:256
clang::ento::VarRegion::getDecl
const VarDecl * getDecl() const override=0
clang::ento::retaincountchecker::RetainCountChecker::getCastFailTag
static const CheckerProgramPointTag & getCastFailTag()
Definition: RetainCountChecker.h:367
clang::ObjCIvarRefExpr
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:549
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:764
llvm::IntrusiveRefCntPtr
Definition: LLVM.h:47
clang::ento::retaincountchecker::RetainCountChecker::FreeNotOwned
std::unique_ptr< RefCountBug > FreeNotOwned
Definition: RetainCountChecker.h:258
INIT_BUGTYPE
#define INIT_BUGTYPE(KIND)
clang::ento::ObjKind::OS
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
clang::ReturnStmt
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:2796
clang::ento::retaincountchecker::RefVal::Released
@ Released
Definition: RetainCountChecker.h:56
getSummary
const static RetainSummary * getSummary(RetainSummaryManager &Summaries, const CallEvent &Call, QualType ReceiverType)
Definition: RetainCountChecker.cpp:352