clang  14.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.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 
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 || !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())
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 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.
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  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);
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().makeNull(), /*Invalidate=*/false);
949  C.addTransition(NullOutputState, &getCastFailTag());
950 
951  // And on the original branch assume that both input and
952  // output are non-zero.
953  if (auto L = RetVal.getAs<DefinedOrUnknownSVal>())
954  state = state->assume(*L, /*assumption=*/true);
955 
956  }
957  }
958 
959  C.addTransition(state);
960  return true;
961 }
962 
963 ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
964  CheckerContext &C) const {
965  ExplodedNode *Pred = C.getPredecessor();
966 
967  // Only adjust the reference count if this is the top-level call frame,
968  // and not the result of inlining. In the future, we should do
969  // better checking even for inlined calls, and see if they match
970  // with their expected semantics (e.g., the method should return a retained
971  // object, etc.).
972  if (!C.inTopFrame())
973  return Pred;
974 
975  if (!S)
976  return Pred;
977 
978  const Expr *RetE = S->getRetValue();
979  if (!RetE)
980  return Pred;
981 
982  ProgramStateRef state = C.getState();
983  // We need to dig down to the symbolic base here because various
984  // custom allocators do sometimes return the symbol with an offset.
985  SymbolRef Sym = state->getSValAsScalarOrLoc(RetE, C.getLocationContext())
986  .getAsLocSymbol(/*IncludeBaseRegions=*/true);
987  if (!Sym)
988  return Pred;
989 
990  // Get the reference count binding (if any).
991  const RefVal *T = getRefBinding(state, Sym);
992  if (!T)
993  return Pred;
994 
995  // Change the reference count.
996  RefVal X = *T;
997 
998  switch (X.getKind()) {
999  case RefVal::Owned: {
1000  unsigned cnt = X.getCount();
1001  assert(cnt > 0);
1002  X.setCount(cnt - 1);
1004  break;
1005  }
1006 
1007  case RefVal::NotOwned: {
1008  unsigned cnt = X.getCount();
1009  if (cnt) {
1010  X.setCount(cnt - 1);
1012  } else {
1014  }
1015  break;
1016  }
1017 
1018  default:
1019  return Pred;
1020  }
1021 
1022  // Update the binding.
1023  state = setRefBinding(state, Sym, X);
1024  Pred = C.addTransition(state);
1025 
1026  // At this point we have updated the state properly.
1027  // Everything after this is merely checking to see if the return value has
1028  // been over- or under-retained.
1029 
1030  // Did we cache out?
1031  if (!Pred)
1032  return nullptr;
1033 
1034  // Update the autorelease counts.
1035  static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
1036  state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X, S);
1037 
1038  // Have we generated a sink node?
1039  if (!state)
1040  return nullptr;
1041 
1042  // Get the updated binding.
1043  T = getRefBinding(state, Sym);
1044  assert(T);
1045  X = *T;
1046 
1047  // Consult the summary of the enclosing method.
1049  const Decl *CD = &Pred->getCodeDecl();
1051 
1052  // FIXME: What is the convention for blocks? Is there one?
1053  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
1054  const RetainSummary *Summ = Summaries.getSummary(AnyCall(MD));
1055  RE = Summ->getRetEffect();
1056  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
1057  if (!isa<CXXMethodDecl>(FD)) {
1058  const RetainSummary *Summ = Summaries.getSummary(AnyCall(FD));
1059  RE = Summ->getRetEffect();
1060  }
1061  }
1062 
1063  return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
1064 }
1065 
1067  CheckerContext &C,
1068  ExplodedNode *Pred,
1069  RetEffect RE, RefVal X,
1070  SymbolRef Sym,
1071  ProgramStateRef state) const {
1072  // HACK: Ignore retain-count issues on values accessed through ivars,
1073  // because of cases like this:
1074  // [_contentView retain];
1075  // [_contentView removeFromSuperview];
1076  // [self addSubview:_contentView]; // invalidates 'self'
1077  // [_contentView release];
1078  if (X.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1079  return Pred;
1080 
1081  // Any leaks or other errors?
1082  if (X.isReturnedOwned() && X.getCount() == 0) {
1083  if (RE.getKind() != RetEffect::NoRet) {
1084  if (!RE.isOwned()) {
1085 
1086  // The returning type is a CF, we expect the enclosing method should
1087  // return ownership.
1089 
1090  // Generate an error node.
1091  state = setRefBinding(state, Sym, X);
1092 
1093  static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
1094  ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
1095  if (N) {
1096  const LangOptions &LOpts = C.getASTContext().getLangOpts();
1097  auto R =
1098  std::make_unique<RefLeakReport>(*LeakAtReturn, LOpts, N, Sym, C);
1099  C.emitReport(std::move(R));
1100  }
1101  return N;
1102  }
1103  }
1104  } else if (X.isReturnedNotOwned()) {
1105  if (RE.isOwned()) {
1106  if (X.getIvarAccessHistory() ==
1108  // Assume the method was trying to transfer a +1 reference from a
1109  // strong ivar to the caller.
1110  state = setRefBinding(state, Sym,
1111  X.releaseViaIvar() ^ RefVal::ReturnedOwned);
1112  } else {
1113  // Trying to return a not owned object to a caller expecting an
1114  // owned object.
1116 
1117  static CheckerProgramPointTag
1118  ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
1119 
1120  ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
1121  if (N) {
1122  auto R = std::make_unique<RefCountReport>(
1123  *ReturnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
1124  C.emitReport(std::move(R));
1125  }
1126  return N;
1127  }
1128  }
1129  }
1130  return Pred;
1131 }
1132 
1133 //===----------------------------------------------------------------------===//
1134 // Check various ways a symbol can be invalidated.
1135 //===----------------------------------------------------------------------===//
1136 
1138  CheckerContext &C) const {
1139  ProgramStateRef state = C.getState();
1140  const MemRegion *MR = loc.getAsRegion();
1141 
1142  // Find all symbols referenced by 'val' that we are tracking
1143  // and stop tracking them.
1144  if (MR && shouldEscapeRegion(MR)) {
1145  state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1146  C.addTransition(state);
1147  }
1148 }
1149 
1151  SVal Cond,
1152  bool Assumption) const {
1153  // FIXME: We may add to the interface of evalAssume the list of symbols
1154  // whose assumptions have changed. For now we just iterate through the
1155  // bindings and check if any of the tracked symbols are NULL. This isn't
1156  // too bad since the number of symbols we will track in practice are
1157  // probably small and evalAssume is only called at branches and a few
1158  // other places.
1159  RefBindingsTy B = state->get<RefBindings>();
1160 
1161  if (B.isEmpty())
1162  return state;
1163 
1164  bool changed = false;
1165  RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1166  ConstraintManager &CMgr = state->getConstraintManager();
1167 
1168  for (auto &I : B) {
1169  // Check if the symbol is null stop tracking the symbol.
1170  ConditionTruthVal AllocFailed = CMgr.isNull(state, I.first);
1171  if (AllocFailed.isConstrainedTrue()) {
1172  changed = true;
1173  B = RefBFactory.remove(B, I.first);
1174  }
1175  }
1176 
1177  if (changed)
1178  state = state->set<RefBindings>(B);
1179 
1180  return state;
1181 }
1182 
1184  ProgramStateRef state, const InvalidatedSymbols *invalidated,
1185  ArrayRef<const MemRegion *> ExplicitRegions,
1186  ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx,
1187  const CallEvent *Call) const {
1188  if (!invalidated)
1189  return state;
1190 
1191  llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
1192 
1193  for (const MemRegion *I : ExplicitRegions)
1194  if (const SymbolicRegion *SR = I->StripCasts()->getAs<SymbolicRegion>())
1195  WhitelistedSymbols.insert(SR->getSymbol());
1196 
1197  for (SymbolRef sym : *invalidated) {
1198  if (WhitelistedSymbols.count(sym))
1199  continue;
1200  // Remove any existing reference-count binding.
1201  state = removeRefBinding(state, sym);
1202  }
1203  return state;
1204 }
1205 
1208  ExplodedNode *Pred,
1209  const ProgramPointTag *Tag,
1210  CheckerContext &Ctx,
1211  SymbolRef Sym,
1212  RefVal V,
1213  const ReturnStmt *S) const {
1214  unsigned ACnt = V.getAutoreleaseCount();
1215 
1216  // No autorelease counts? Nothing to be done.
1217  if (!ACnt)
1218  return state;
1219 
1220  unsigned Cnt = V.getCount();
1221 
1222  // FIXME: Handle sending 'autorelease' to already released object.
1223 
1224  if (V.getKind() == RefVal::ReturnedOwned)
1225  ++Cnt;
1226 
1227  // If we would over-release here, but we know the value came from an ivar,
1228  // assume it was a strong ivar that's just been relinquished.
1229  if (ACnt > Cnt &&
1230  V.getIvarAccessHistory() == RefVal::IvarAccessHistory::AccessedDirectly) {
1231  V = V.releaseViaIvar();
1232  --ACnt;
1233  }
1234 
1235  if (ACnt <= Cnt) {
1236  if (ACnt == Cnt) {
1237  V.clearCounts();
1238  if (V.getKind() == RefVal::ReturnedOwned) {
1240  } else {
1241  V = V ^ RefVal::NotOwned;
1242  }
1243  } else {
1244  V.setCount(V.getCount() - ACnt);
1245  V.setAutoreleaseCount(0);
1246  }
1247  return setRefBinding(state, Sym, V);
1248  }
1249 
1250  // HACK: Ignore retain-count issues on values accessed through ivars,
1251  // because of cases like this:
1252  // [_contentView retain];
1253  // [_contentView removeFromSuperview];
1254  // [self addSubview:_contentView]; // invalidates 'self'
1255  // [_contentView release];
1256  if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1257  return state;
1258 
1259  // Woah! More autorelease counts then retain counts left.
1260  // Emit hard error.
1262  state = setRefBinding(state, Sym, V);
1263 
1264  ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
1265  if (N) {
1266  SmallString<128> sbuf;
1267  llvm::raw_svector_ostream os(sbuf);
1268  os << "Object was autoreleased ";
1269  if (V.getAutoreleaseCount() > 1)
1270  os << V.getAutoreleaseCount() << " times but the object ";
1271  else
1272  os << "but ";
1273  os << "has a +" << V.getCount() << " retain count";
1274 
1275  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1276  auto R = std::make_unique<RefCountReport>(*OverAutorelease, LOpts, N, Sym,
1277  os.str());
1278  Ctx.emitReport(std::move(R));
1279  }
1280 
1281  return nullptr;
1282 }
1283 
1286  SymbolRef sid, RefVal V,
1287  SmallVectorImpl<SymbolRef> &Leaked) const {
1288  bool hasLeak;
1289 
1290  // HACK: Ignore retain-count issues on values accessed through ivars,
1291  // because of cases like this:
1292  // [_contentView retain];
1293  // [_contentView removeFromSuperview];
1294  // [self addSubview:_contentView]; // invalidates 'self'
1295  // [_contentView release];
1296  if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1297  hasLeak = false;
1298  else if (V.isOwned())
1299  hasLeak = true;
1300  else if (V.isNotOwned() || V.isReturnedOwned())
1301  hasLeak = (V.getCount() > 0);
1302  else
1303  hasLeak = false;
1304 
1305  if (!hasLeak)
1306  return removeRefBinding(state, sid);
1307 
1308  Leaked.push_back(sid);
1309  return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
1310 }
1311 
1312 ExplodedNode *
1315  CheckerContext &Ctx,
1316  ExplodedNode *Pred) const {
1317  // Generate an intermediate node representing the leak point.
1318  ExplodedNode *N = Ctx.addTransition(state, Pred);
1319  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1320 
1321  if (N) {
1322  for (SymbolRef L : Leaked) {
1323  const RefCountBug &BT = Pred ? *LeakWithinFunction : *LeakAtReturn;
1324  Ctx.emitReport(std::make_unique<RefLeakReport>(BT, LOpts, N, L, Ctx));
1325  }
1326  }
1327 
1328  return N;
1329 }
1330 
1332  if (!Ctx.inTopFrame())
1333  return;
1334 
1335  RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
1336  const LocationContext *LCtx = Ctx.getLocationContext();
1337  const Decl *D = LCtx->getDecl();
1339 
1340  if (!C || SmrMgr.isTrustedReferenceCountImplementation(D))
1341  return;
1342 
1343  ProgramStateRef state = Ctx.getState();
1344  const RetainSummary *FunctionSummary = SmrMgr.getSummary(*C);
1345  ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
1346 
1347  for (unsigned idx = 0, e = C->param_size(); idx != e; ++idx) {
1348  const ParmVarDecl *Param = C->parameters()[idx];
1349  SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1350 
1351  QualType Ty = Param->getType();
1352  const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
1353  if (AE) {
1354  ObjKind K = AE->getObjKind();
1355  if (K == ObjKind::Generalized || K == ObjKind::OS ||
1356  (TrackNSCFStartParam && (K == ObjKind::ObjC || K == ObjKind::CF))) {
1357  RefVal NewVal = AE->getKind() == DecRef ? RefVal::makeOwned(K, Ty)
1358  : RefVal::makeNotOwned(K, Ty);
1359  state = setRefBinding(state, Sym, NewVal);
1360  }
1361  }
1362  }
1363 
1364  Ctx.addTransition(state);
1365 }
1366 
1368  CheckerContext &Ctx) const {
1369  ExplodedNode *Pred = processReturn(RS, Ctx);
1370 
1371  // Created state cached out.
1372  if (!Pred) {
1373  return;
1374  }
1375 
1376  ProgramStateRef state = Pred->getState();
1377  RefBindingsTy B = state->get<RefBindings>();
1378 
1379  // Don't process anything within synthesized bodies.
1380  const LocationContext *LCtx = Pred->getLocationContext();
1381  if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
1382  assert(!LCtx->inTopFrame());
1383  return;
1384  }
1385 
1386  for (auto &I : B) {
1387  state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
1388  I.first, I.second);
1389  if (!state)
1390  return;
1391  }
1392 
1393  // If the current LocationContext has a parent, don't check for leaks.
1394  // We will do that later.
1395  // FIXME: we should instead check for imbalances of the retain/releases,
1396  // and suggest annotations.
1397  if (LCtx->getParent())
1398  return;
1399 
1400  B = state->get<RefBindings>();
1402 
1403  for (auto &I : B)
1404  state = handleSymbolDeath(state, I.first, I.second, Leaked);
1405 
1406  processLeaks(state, Leaked, Ctx, Pred);
1407 }
1408 
1410  CheckerContext &C) const {
1411  ExplodedNode *Pred = C.getPredecessor();
1412 
1413  ProgramStateRef state = C.getState();
1415 
1416  // Update counts from autorelease pools
1417  for (const auto &I: state->get<RefBindings>()) {
1418  SymbolRef Sym = I.first;
1419  if (SymReaper.isDead(Sym)) {
1420  static CheckerProgramPointTag Tag(this, "DeadSymbolAutorelease");
1421  const RefVal &V = I.second;
1422  state = handleAutoreleaseCounts(state, Pred, &Tag, C, Sym, V);
1423  if (!state)
1424  return;
1425 
1426  // Fetch the new reference count from the state, and use it to handle
1427  // this symbol.
1428  state = handleSymbolDeath(state, Sym, *getRefBinding(state, Sym), Leaked);
1429  }
1430  }
1431 
1432  if (Leaked.empty()) {
1433  C.addTransition(state);
1434  return;
1435  }
1436 
1437  Pred = processLeaks(state, Leaked, C, Pred);
1438 
1439  // Did we cache out?
1440  if (!Pred)
1441  return;
1442 
1443  // Now generate a new node that nukes the old bindings.
1444  // The only bindings left at this point are the leaked symbols.
1445  RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1446  RefBindingsTy B = state->get<RefBindings>();
1447 
1448  for (SymbolRef L : Leaked)
1449  B = F.remove(B, L);
1450 
1451  state = state->set<RefBindings>(B);
1452  C.addTransition(state, Pred);
1453 }
1454 
1456  const char *NL, const char *Sep) const {
1457 
1458  RefBindingsTy B = State->get<RefBindings>();
1459 
1460  if (B.isEmpty())
1461  return;
1462 
1463  Out << Sep << NL;
1464 
1465  for (auto &I : B) {
1466  Out << I.first << " : ";
1467  I.second.print(Out);
1468  Out << NL;
1469  }
1470 }
1471 
1472 //===----------------------------------------------------------------------===//
1473 // Checker registration.
1474 //===----------------------------------------------------------------------===//
1475 
1476 std::unique_ptr<CheckerProgramPointTag> RetainCountChecker::DeallocSentTag;
1477 std::unique_ptr<CheckerProgramPointTag> RetainCountChecker::CastFailTag;
1478 
1479 void ento::registerRetainCountBase(CheckerManager &Mgr) {
1480  auto *Chk = Mgr.registerChecker<RetainCountChecker>();
1481  Chk->DeallocSentTag =
1482  std::make_unique<CheckerProgramPointTag>(Chk, "DeallocSent");
1483  Chk->CastFailTag =
1484  std::make_unique<CheckerProgramPointTag>(Chk, "DynamicCastFail");
1485 }
1486 
1487 bool ento::shouldRegisterRetainCountBase(const CheckerManager &mgr) {
1488  return true;
1489 }
1490 void ento::registerRetainCountChecker(CheckerManager &Mgr) {
1491  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1492  Chk->TrackObjCAndCFObjects = true;
1493  Chk->TrackNSCFStartParam = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
1494  Mgr.getCurrentCheckerName(), "TrackNSCFStartParam");
1495 
1496 #define INIT_BUGTYPE(KIND) \
1497  Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(), \
1498  RefCountBug::KIND);
1499  // TODO: Ideally, we should have a checker for each of these bug types.
1500  INIT_BUGTYPE(UseAfterRelease)
1501  INIT_BUGTYPE(ReleaseNotOwned)
1502  INIT_BUGTYPE(DeallocNotOwned)
1503  INIT_BUGTYPE(FreeNotOwned)
1504  INIT_BUGTYPE(OverAutorelease)
1505  INIT_BUGTYPE(ReturnNotOwnedForOwned)
1506  INIT_BUGTYPE(LeakWithinFunction)
1507  INIT_BUGTYPE(LeakAtReturn)
1508 #undef INIT_BUGTYPE
1509 }
1510 
1511 bool ento::shouldRegisterRetainCountChecker(const CheckerManager &mgr) {
1512  return true;
1513 }
1514 
1515 void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
1516  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1517  Chk->TrackOSObjects = true;
1518 
1519  // FIXME: We want bug reports to always have the same checker name associated
1520  // with them, yet here, if RetainCountChecker is disabled but
1521  // OSObjectRetainCountChecker is enabled, the checker names will be different.
1522  // This hack will make it so that the checker name depends on which checker is
1523  // enabled rather than on the registration order.
1524  // For the most part, we want **non-hidden checkers** to be associated with
1525  // diagnostics, and **hidden checker options** with the fine-tuning of
1526  // modeling. Following this logic, OSObjectRetainCountChecker should be the
1527  // latter, but we can't just remove it for backward compatibility reasons.
1528 #define LAZY_INIT_BUGTYPE(KIND) \
1529  if (!Chk->KIND) \
1530  Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(), \
1531  RefCountBug::KIND);
1532  LAZY_INIT_BUGTYPE(UseAfterRelease)
1533  LAZY_INIT_BUGTYPE(ReleaseNotOwned)
1534  LAZY_INIT_BUGTYPE(DeallocNotOwned)
1535  LAZY_INIT_BUGTYPE(FreeNotOwned)
1536  LAZY_INIT_BUGTYPE(OverAutorelease)
1537  LAZY_INIT_BUGTYPE(ReturnNotOwnedForOwned)
1538  LAZY_INIT_BUGTYPE(LeakWithinFunction)
1539  LAZY_INIT_BUGTYPE(LeakAtReturn)
1540 #undef LAZY_INIT_BUGTYPE
1541 }
1542 
1543 bool ento::shouldRegisterOSObjectRetainCountChecker(const CheckerManager &mgr) {
1544  return true;
1545 }
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:1151
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:586
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:4284
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:212
clang::Decl::hasAttr
bool hasAttr() const
Definition: DeclBase.h:547
clang::ento::CheckerManager::registerChecker
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
Definition: CheckerManager.h:205
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:131
clang::ento::ObjKind
ObjKind
Determines the object kind of a tracked object.
Definition: RetainSummaryManager.h:35
clang::ento::ConstraintManager
Definition: ConstraintManager.h:77
clang::ento::CheckerManager::getCurrentCheckerName
CheckerNameRef getCurrentCheckerName() const
Definition: CheckerManager.h:164
clang::ProgramPointTag
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
Definition: ProgramPoint.h:39
clang::ento::CallEvent::getOriginExpr
virtual const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Definition: CallEvent.h:228
clang::ento::DefinedOrUnknownSVal
Definition: SVals.h:236
llvm::SmallVector
Definition: LLVM.h:38
clang::ento::MemRegion::StripCasts
const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1328
clang::ento::CheckerContext::getLocationContext
const LocationContext * getLocationContext() const
Definition: CheckerContext.h:91
clang::ento::ArgEffect::getKind
ArgEffectKind getKind() const
Definition: RetainSummaryManager.h:125
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:673
clang::Type::isScalarType
bool isScalarType() const
Definition: Type.h:7042
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:1625
AttributeLangSupport::C
@ C
Definition: SemaDeclAttr.cpp:54
clang::ento::CheckerManager::getAnalyzerOptions
const AnalyzerOptions & getAnalyzerOptions() const
Definition: CheckerManager.h:171
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:696
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:1665
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:82
clang::QualType::getAsString
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1015
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:946
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:1455
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:111
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:1367
clang::ento::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
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:84
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:87
clang::ento::SymbolReaper::isDead
bool isDead(SymbolRef sym)
Returns whether or not a symbol has been confirmed dead.
Definition: SymbolManager.h:570
V
#define V(N, I)
Definition: ASTContext.h:3121
clang::ento::CallEvent::getReturnValue
SVal getReturnValue() const
Returns the return value of the call.
Definition: CallEvent.cpp:401
clang::ento::ExplodedNode::getState
const ProgramStateRef & getState() const
Definition: ExplodedGraph.h:169
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:394
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:1137
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:694
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:101
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:5977
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:212
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:7161
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:1150
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:5434
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:166
clang::ento::VarRegion
Definition: MemRegion.h:906
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:15
clang::ento::RetainSummary::getThisEffect
ArgEffect getThisEffect() const
Definition: RetainSummaryManager.h:346
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:876
clang::ento::CheckerContext::emitReport
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
Definition: CheckerContext.h:242
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:505
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:100
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:940
clang::ento::SymbolicRegion
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:754
clang::ento::SubRegion::getSuperRegion
const MemRegion * getSuperRegion() const
Definition: MemRegion.h:447
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:327
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:6794
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:4272
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:219
clang::ento::MemRegion::getAs
const RegionTy * getAs() const
Definition: MemRegion.h:1286
clang::ObjCObjectPointerType
Represents a pointer to an Objective C object.
Definition: Type.h:6072
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:1274
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
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:738
clang::BlockExpr
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5965
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:89
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:986
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:1066
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:58
clang::ento::CallEvent::getResultType
QualType getResultType() const
Returns the result type, adjusted for references.
Definition: CallEvent.cpp:71
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:151
clang::ento::MemRegionManager
Definition: MemRegion.h:1302
Checker.h
std
Definition: Format.h:4034
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:127
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:1331
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:69
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:186
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:143
clang::ento::SVal::isUnknown
bool isUnknown() const
Definition: SVals.h:136
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:177
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:387
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:1409
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:75
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:1285
llvm::SmallVectorImpl
Definition: LLVM.h:39
clang::ObjCBridgedCastExpr::getBridgeKind
ObjCBridgeCastKind getBridgeKind() const
Determine which kind of bridge is being performed via this cast.
Definition: ExprObjC.h:1652
clang::ento::ExplodedNode::getCodeDecl
const Decl & getCodeDecl() const
Definition: ExplodedGraph.h:154
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:687
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:1183
clang::ento::SVal::getAsSymbol
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
Definition: SVals.cpp:123
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:1313
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:5404
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:3473
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:1207
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:247
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1856
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:167
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:548
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:765
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:2760
clang::ento::BlockDataRegion::referenced_vars_iterator::getCapturedRegion
const VarRegion * getCapturedRegion() const
Definition: MemRegion.h:703
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