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"
15#include "clang/StaticAnalyzer/Core/Checker.h"
16#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
17#include <optional>
18
19using namespace clang;
20using namespace ento;
21using namespace retaincountchecker;
22
23REGISTER_MAP_WITH_PROGRAMSTATE(RefBindings, SymbolRef, RefVal)
24
25namespace clang {
26namespace ento {
27namespace retaincountchecker {
28
29const RefVal *getRefBinding(ProgramStateRef State, SymbolRef Sym) {
30  return State->get<RefBindings>(Sym);
31}
32
33} // end namespace retaincountchecker
34} // end namespace ento
35} // end namespace clang
36
37static ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
38                                     RefVal Val) {
39  assert(Sym != nullptr);
40  return State->set<RefBindings>(Sym, Val);
41}
42
43static ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
44  return State->remove<RefBindings>(Sym);
45}
46
47void RefVal::print(raw_ostream &Out) const {
48  if (!T.isNull())
49    Out << "Tracked " << T << " | ";
50
51  switch (getKind()) {
52    default: llvm_unreachable("Invalid RefVal kind");
53    case Owned: {
54      Out << "Owned";
55      unsigned cnt = getCount();
56      if (cnt) Out << " (+ " << cnt << ")";
57      break;
58    }
59
60    case NotOwned: {
61      Out << "NotOwned";
62      unsigned cnt = getCount();
63      if (cnt) Out << " (+ " << cnt << ")";
64      break;
65    }
66
67    case ReturnedOwned: {
68      Out << "ReturnedOwned";
69      unsigned cnt = getCount();
70      if (cnt) Out << " (+ " << cnt << ")";
71      break;
72    }
73
74    case ReturnedNotOwned: {
75      Out << "ReturnedNotOwned";
76      unsigned cnt = getCount();
77      if (cnt) Out << " (+ " << cnt << ")";
78      break;
79    }
80
81    case Released:
82      Out << "Released";
83      break;
84
85    case ErrorDeallocNotOwned:
86      Out << "-dealloc (not-owned)";
87      break;
88
89    case ErrorLeak:
90      Out << "Leaked";
91      break;
92
93    case ErrorLeakReturned:
94      Out << "Leaked (Bad naming)";
95      break;
96
97    case ErrorUseAfterRelease:
98      Out << "Use-After-Release [ERROR]";
99      break;
100
101    case ErrorReleaseNotOwned:
102      Out << "Release of Not-Owned [ERROR]";
103      break;
104
105    case RefVal::ErrorOverAutorelease:
106      Out << "Over-autoreleased";
107      break;
108
109    case RefVal::ErrorReturnedNotOwned:
110      Out << "Non-owned object returned instead of owned";
111      break;
112  }
113
114  switch (getIvarAccessHistory()) {
115  case IvarAccessHistory::None:
116    break;
117  case IvarAccessHistory::AccessedDirectly:
118    Out << " [direct ivar access]";
119    break;
120  case IvarAccessHistory::ReleasedAfterDirectAccess:
121    Out << " [released after direct ivar access]";
122  }
123
124  if (ACnt) {
125    Out << " [autorelease -" << ACnt << ']';
126  }
127}
128
129namespace {
130class StopTrackingCallback final : public SymbolVisitor {
131  ProgramStateRef state;
132public:
133  StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
134  ProgramStateRef getState() const { return state; }
135
136  bool VisitSymbol(SymbolRef sym) override {
137    state = removeRefBinding(state, sym);
138    return true;
139  }
140};
141} // end anonymous namespace
142
143//===----------------------------------------------------------------------===//
144// Handle statements that may have an effect on refcounts.
145//===----------------------------------------------------------------------===//
146
147void RetainCountChecker::checkPostStmt(const BlockExpr *BE,
148                                       CheckerContext &C) const {
149
150  // Scan the BlockDecRefExprs for any object the retain count checker
151  // may be tracking.
152  if (!BE->getBlockDecl()->hasCaptures())
153    return;
154
155  ProgramStateRef state = C.getState();
156  auto *R = cast<BlockDataRegion>(C.getSVal(BE).getAsRegion());
157
158  BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
159                                            E = R->referenced_vars_end();
160
161  if (I == E)
162    return;
163
164  // FIXME: For now we invalidate the tracking of all symbols passed to blocks
165  // via captured variables, even though captured variables result in a copy
166  // and in implicit increment/decrement of a retain count.
167  SmallVector<const MemRegion*, 10> Regions;
168  const LocationContext *LC = C.getLocationContext();
169  MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
170
171  for ( ; I != E; ++I) {
172    const VarRegion *VR = I.getCapturedRegion();
173    if (VR->getSuperRegion() == R) {
174      VR = MemMgr.getVarRegion(VR->getDecl(), LC);
175    }
176    Regions.push_back(VR);
177  }
178
179  state = state->scanReachableSymbols<StopTrackingCallback>(Regions).getState();
180  C.addTransition(state);
181}
182
183void RetainCountChecker::checkPostStmt(const CastExpr *CE,
184                                       CheckerContext &C) const {
185  const ObjCBridgedCastExpr *BE = dyn_cast<ObjCBridgedCastExpr>(CE);
186  if (!BE)
187    return;
188
189  QualType QT = CE->getType();
190  ObjKind K;
191  if (QT->isObjCObjectPointerType()) {
192    K = ObjKind::ObjC;
193  } else {
194    K = ObjKind::CF;
195  }
196
197  ArgEffect AE = ArgEffect(IncRef, K);
198
199  switch (BE->getBridgeKind()) {
200    case OBC_Bridge:
201      // Do nothing.
202      return;
203    case OBC_BridgeRetained:
204      AE = AE.withKind(IncRef);
205      break;
206    case OBC_BridgeTransfer:
207      AE = AE.withKind(DecRefBridgedTransferred);
208      break;
209  }
210
211  ProgramStateRef state = C.getState();
212  SymbolRef Sym = C.getSVal(CE).getAsLocSymbol();
213  if (!Sym)
214    return;
215  const RefVal* T = getRefBinding(state, Sym);
216  if (!T)
217    return;
218
219  RefVal::Kind hasErr = (RefVal::Kind) 0;
220  state = updateSymbol(state, Sym, *T, AE, hasErr, C);
221
222  if (hasErr) {
223    // FIXME: If we get an error during a bridge cast, should we report it?
224    return;
225  }
226
227  C.addTransition(state);
228}
229
230void RetainCountChecker::processObjCLiterals(CheckerContext &C,
231                                             const Expr *Ex) const {
232  ProgramStateRef state = C.getState();
233  const ExplodedNode *pred = C.getPredecessor();
234  for (const Stmt *Child : Ex->children()) {
235    SVal V = pred->getSVal(Child);
236    if (SymbolRef sym = V.getAsSymbol())
237      if (const RefVal* T = getRefBinding(state, sym)) {
238        RefVal::Kind hasErr = (RefVal::Kind) 0;
239        state = updateSymbol(state, sym, *T,
240                             ArgEffect(MayEscape, ObjKind::ObjC), hasErr, C);
241        if (hasErr) {
242          processNonLeakError(state, Child->getSourceRange(), hasErr, sym, C);
243          return;
244        }
245      }
246  }
247
248  // Return the object as autoreleased.
249  //  RetEffect RE = RetEffect::MakeNotOwned(ObjKind::ObjC);
250  if (SymbolRef sym =
251        state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
252    QualType ResultTy = Ex->getType();
253    state = setRefBinding(state, sym,
254                          RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
255  }
256
257  C.addTransition(state);
258}
259
260void RetainCountChecker::checkPostStmt(const ObjCArrayLiteral *AL,
261                                       CheckerContext &C) const {
262  // Apply the 'MayEscape' to all values.
263  processObjCLiterals(C, AL);
264}
265
266void RetainCountChecker::checkPostStmt(const ObjCDictionaryLiteral *DL,
267                                       CheckerContext &C) const {
268  // Apply the 'MayEscape' to all keys and values.
269  processObjCLiterals(C, DL);
270}
271
272void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
273                                       CheckerContext &C) const {
274  const ExplodedNode *Pred = C.getPredecessor();
275  ProgramStateRef State = Pred->getState();
276
277  if (SymbolRef Sym = Pred->getSVal(Ex).getAsSymbol()) {
278    QualType ResultTy = Ex->getType();
279    State = setRefBinding(State, Sym,
280                          RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
281  }
282
283  C.addTransition(State);
284}
285
286void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
287                                       CheckerContext &C) const {
288  std::optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>();
289  if (!IVarLoc)
290    return;
291
292  ProgramStateRef State = C.getState();
293  SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
294  if (!Sym || !isa_and_nonnull<ObjCIvarRegion>(Sym->getOriginRegion()))
295    return;
296
297  // Accessing an ivar directly is unusual. If we've done that, be more
298  // forgiving about what the surrounding code is allowed to do.
299
300  QualType Ty = Sym->getType();
301  ObjKind Kind;
302  if (Ty->isObjCRetainableType())
303    Kind = ObjKind::ObjC;
304  else if (coreFoundation::isCFObjectRef(Ty))
305    Kind = ObjKind::CF;
306  else
307    return;
308
309  // If the value is already known to be nil, don't bother tracking it.
310  ConstraintManager &CMgr = State->getConstraintManager();
311  if (CMgr.isNull(State, Sym).isConstrainedTrue())
312    return;
313
314  if (const RefVal *RV = getRefBinding(State, Sym)) {
315    // If we've seen this symbol before, or we're only seeing it now because
316    // of something the analyzer has synthesized, don't do anything.
317    if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None ||
318        isSynthesizedAccessor(C.getStackFrame())) {
319      return;
320    }
321
322    // Note that this value has been loaded from an ivar.
323    C.addTransition(setRefBinding(State, Sym, RV->withIvarAccess()));
324    return;
325  }
326
327  RefVal PlusZero = RefVal::makeNotOwned(Kind, Ty);
328
329  // In a synthesized accessor, the effective retain count is +0.
330  if (isSynthesizedAccessor(C.getStackFrame())) {
331    C.addTransition(setRefBinding(State, Sym, PlusZero));
332    return;
333  }
334
335  State = setRefBinding(State, Sym, PlusZero.withIvarAccess());
336  C.addTransition(State);
337}
338
339static bool isReceiverUnconsumedSelf(const CallEvent &Call) {
340  if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
341
342    // Check if the message is not consumed, we know it will not be used in
343    // an assignment, ex: "self = [super init]".
344    return MC->getMethodFamily() == OMF_init && MC->isReceiverSelfOrSuper() &&
345           !Call.getLocationContext()
346                ->getAnalysisDeclContext()
347                ->getParentMap()
348                .isConsumedExpr(Call.getOriginExpr());
349  }
350  return false;
351}
352
353const static RetainSummary *getSummary(RetainSummaryManager &Summaries,
354                                       const CallEvent &Call,
355                                       QualType ReceiverType) {
356  const Expr *CE = Call.getOriginExpr();
357  AnyCall C =
358      CE ? *AnyCall::forExpr(CE)
359         : AnyCall(cast<CXXDestructorDecl>(Call.getDecl()));
360  return Summaries.getSummary(C, Call.hasNonZeroCallbackArg(),
361                              isReceiverUnconsumedSelf(Call), ReceiverType);
362}
363
364void RetainCountChecker::checkPostCall(const CallEvent &Call,
365                                       CheckerContext &C) const {
366  RetainSummaryManager &Summaries = getSummaryManager(C);
367
368  // Leave null if no receiver.
369  QualType ReceiverType;
370  if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
371    if (MC->isInstanceMessage()) {
372      SVal ReceiverV = MC->getReceiverSVal();
373      if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
374        if (const RefVal *T = getRefBinding(C.getState(), Sym))
375          ReceiverType = T->getType();
376    }
377  }
378
379  const RetainSummary *Summ = getSummary(Summaries, Call, ReceiverType);
380
381  if (C.wasInlined) {
382    processSummaryOfInlined(*Summ, Call, C);
383    return;
384  }
385  checkSummary(*Summ, Call, C);
386}
387
388/// GetReturnType - Used to get the return type of a message expression or
389///  function call with the intention of affixing that type to a tracked symbol.
390///  While the return type can be queried directly from RetEx, when
391///  invoking class methods we augment to the return type to be that of
392///  a pointer to the class (as opposed it just being id).
393// FIXME: We may be able to do this with related result types instead.
394// This function is probably overestimating.
395static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) {
396  QualType RetTy = RetE->getType();
397  // If RetE is not a message expression just return its type.
398  // If RetE is a message expression, return its types if it is something
399  /// more specific than id.
400  if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
401    if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>())
402      if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
403          PT->isObjCClassType()) {
404        // At this point we know the return type of the message expression is
405        // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
406        // is a call to a class method whose type we can resolve.  In such
407        // cases, promote the return type to XXX* (where XXX is the class).
408        const ObjCInterfaceDecl *D = ME->getReceiverInterface();
409        return !D ? RetTy :
410                    Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D));
411      }
412
413  return RetTy;
414}
415
416static std::optional<RefVal> refValFromRetEffect(RetEffect RE,
417                                                 QualType ResultTy) {
418  if (RE.isOwned()) {
419    return RefVal::makeOwned(RE.getObjKind(), ResultTy);
420  } else if (RE.notOwned()) {
421    return RefVal::makeNotOwned(RE.getObjKind(), ResultTy);
422  }
423
424  return std::nullopt;
425}
426
427static bool isPointerToObject(QualType QT) {
428  QualType PT = QT->getPointeeType();
429  if (!PT.isNull())
430    if (PT->getAsCXXRecordDecl())
431      return true;
432  return false;
433}
434
435/// Whether the tracked value should be escaped on a given call.
436/// OSObjects are escaped when passed to void * / etc.
437static bool shouldEscapeOSArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
438                                       const RefVal *TrackedValue) {
439  if (TrackedValue->getObjKind() != ObjKind::OS)
440    return false;
441  if (ArgIdx >= CE.parameters().size())
442    return false;
443  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
444}
445
446// We don't always get the exact modeling of the function with regards to the
447// retain count checker even when the function is inlined. For example, we need
448// to stop tracking the symbols which were marked with StopTrackingHard.
449void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
450                                                 const CallEvent &CallOrMsg,
451                                                 CheckerContext &C) const {
452  ProgramStateRef state = C.getState();
453
454  // Evaluate the effect of the arguments.
455  for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
456    SVal V = CallOrMsg.getArgSVal(idx);
457
458    if (SymbolRef Sym = V.getAsLocSymbol()) {
459      bool ShouldRemoveBinding = Summ.getArg(idx).getKind() == StopTrackingHard;
460      if (const RefVal *T = getRefBinding(state, Sym))
461        if (shouldEscapeOSArgumentOnCall(CallOrMsg, idx, T))
462          ShouldRemoveBinding = true;
463
464      if (ShouldRemoveBinding)
465        state = removeRefBinding(state, Sym);
466    }
467  }
468
469  // Evaluate the effect on the message receiver.
470  if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
471    if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
472      if (Summ.getReceiverEffect().getKind() == StopTrackingHard) {
473        state = removeRefBinding(state, Sym);
474      }
475    }
476  }
477
478  // Consult the summary for the return value.
479  RetEffect RE = Summ.getRetEffect();
480
481  if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
482    if (RE.getKind() == RetEffect::NoRetHard)
483      state = removeRefBinding(state, Sym);
484  }
485
486  C.addTransition(state);
487}
488
489static bool isSmartPtrField(const MemRegion *MR) {
490  const auto *TR = dyn_cast<TypedValueRegion>(
491    cast<SubRegion>(MR)->getSuperRegion());
492  return TR && RetainSummaryManager::isKnownSmartPointer(TR->getValueType());
493}
494
495
496/// A value escapes in these possible cases:
497///
498/// - binding to something that is not a memory region.
499/// - binding to a memregion that does not have stack storage
500/// - binding to a variable that has a destructor attached using CleanupAttr
501///
502/// We do not currently model what happens when a symbol is
503/// assigned to a struct field, unless it is a known smart pointer
504/// implementation, about which we know that it is inlined.
505/// FIXME: This could definitely be improved upon.
506static bool shouldEscapeRegion(const MemRegion *R) {
507  if (isSmartPtrField(R))
508    return false;
509
510  const auto *VR = dyn_cast<VarRegion>(R);
511
512  if (!R->hasStackStorage() || !VR)
513    return true;
514
515  const VarDecl *VD = VR->getDecl();
516  if (!VD->hasAttr<CleanupAttr>())
517    return false; // CleanupAttr attaches destructors, which cause escaping.
518  return true;
519}
520
521static SmallVector<ProgramStateRef, 2>
522updateOutParameters(ProgramStateRef State, const RetainSummary &Summ,
523                    const CallEvent &CE) {
524
525  SVal L = CE.getReturnValue();
526
527  // Splitting is required to support out parameters,
528  // as out parameters might be created only on the "success" branch.
529  // We want to avoid eagerly splitting unless out parameters are actually
530  // needed.
531  bool SplitNecessary = false;
532  for (auto &P : Summ.getArgEffects())
533    if (P.second.getKind() == RetainedOutParameterOnNonZero ||
534        P.second.getKind() == RetainedOutParameterOnZero)
535      SplitNecessary = true;
536
537  ProgramStateRef AssumeNonZeroReturn = State;
538  ProgramStateRef AssumeZeroReturn = State;
539
540  if (SplitNecessary) {
541    if (!CE.getResultType()->isScalarType()) {
542      // Structures cannot be assumed. This probably deserves
543      // a compiler warning for invalid annotations.
544      return {State};
545    }
546    if (auto DL = L.getAs<DefinedOrUnknownSVal>()) {
547      AssumeNonZeroReturn = AssumeNonZeroReturn->assume(*DL, true);
548      AssumeZeroReturn = AssumeZeroReturn->assume(*DL, false);
549    }
550  }
551
552  for (unsigned idx = 0, e = CE.getNumArgs(); idx != e; ++idx) {
553    SVal ArgVal = CE.getArgSVal(idx);
554    ArgEffect AE = Summ.getArg(idx);
555
556    auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.getAsRegion());
557    if (!ArgRegion)
558      continue;
559
560    QualType PointeeTy = ArgRegion->getValueType();
561    SVal PointeeVal = State->getSVal(ArgRegion);
562    SymbolRef Pointee = PointeeVal.getAsLocSymbol();
563    if (!Pointee)
564      continue;
565
566    if (shouldEscapeRegion(ArgRegion))
567      continue;
568
569    auto makeNotOwnedParameter = [&](ProgramStateRef St) {
570      return setRefBinding(St, Pointee,
571                           RefVal::makeNotOwned(AE.getObjKind(), PointeeTy));
572    };
573    auto makeOwnedParameter = [&](ProgramStateRef St) {
574      return setRefBinding(St, Pointee,
575                           RefVal::makeOwned(ObjKind::OS, PointeeTy));
576    };
577
578    switch (AE.getKind()) {
579    case UnretainedOutParameter:
580      AssumeNonZeroReturn = makeNotOwnedParameter(AssumeNonZeroReturn);
581      AssumeZeroReturn = makeNotOwnedParameter(AssumeZeroReturn);
582      break;
583    case RetainedOutParameter:
584      AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
585      AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
586      break;
587    case RetainedOutParameterOnNonZero:
588      AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
589      break;
590    case RetainedOutParameterOnZero:
591      AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
592      break;
593    default:
594      break;
595    }
596  }
597
598  if (SplitNecessary) {
599    return {AssumeNonZeroReturn, AssumeZeroReturn};
600  } else {
601    assert(AssumeZeroReturn == AssumeNonZeroReturn);
602    return {AssumeZeroReturn};
603  }
604}
605
606void RetainCountChecker::checkSummary(const RetainSummary &Summ,
607                                      const CallEvent &CallOrMsg,
608                                      CheckerContext &C) const {
609  ProgramStateRef state = C.getState();
610
611  // Evaluate the effect of the arguments.
612  RefVal::Kind hasErr = (RefVal::Kind) 0;
613  SourceRange ErrorRange;
614  SymbolRef ErrorSym = nullptr;
615
616  // Helper tag for providing diagnostics: indicate whether dealloc was sent
617  // at this location.
618  bool DeallocSent = false;
619
620  for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
621    SVal V = CallOrMsg.getArgSVal(idx);
622
623    ArgEffect Effect = Summ.getArg(idx);
624    if (SymbolRef Sym = V.getAsLocSymbol()) {
625      if (const RefVal *T = getRefBinding(state, Sym)) {
626
627        if (shouldEscapeOSArgumentOnCall(CallOrMsg, idx, T))
628          Effect = ArgEffect(StopTrackingHard, ObjKind::OS);
629
630        state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
631        if (hasErr) {
632          ErrorRange = CallOrMsg.getArgSourceRange(idx);
633          ErrorSym = Sym;
634          break;
635        } else if (Effect.getKind() == Dealloc) {
636          DeallocSent = true;
637        }
638      }
639    }
640  }
641
642  // Evaluate the effect on the message receiver / `this` argument.
643  bool ReceiverIsTracked = false;
644  if (!hasErr) {
645    if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
646      if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
647        if (const RefVal *T = getRefBinding(state, Sym)) {
648          ReceiverIsTracked = true;
649          state = updateSymbol(state, Sym, *T,
650                               Summ.getReceiverEffect(), hasErr, C);
651          if (hasErr) {
652            ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
653            ErrorSym = Sym;
654          } else if (Summ.getReceiverEffect().getKind() == Dealloc) {
655            DeallocSent = true;
656          }
657        }
658      }
659    } else if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
660      if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
661        if (const RefVal *T = getRefBinding(state, Sym)) {
662          state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
663                               hasErr, C);
664          if (hasErr) {
665            ErrorRange = MCall->getOriginExpr()->getSourceRange();
666            ErrorSym = Sym;
667          }
668        }
669      }
670    }
671  }
672
673  // Process any errors.
674  if (hasErr) {
675    processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C);
676    return;
677  }
678
679  // Consult the summary for the return value.
680  RetEffect RE = Summ.getRetEffect();
681
682  if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
683    if (ReceiverIsTracked)
684      RE = getSummaryManager(C).getObjAllocRetEffect();
685    else
686      RE = RetEffect::MakeNoRet();
687  }
688
689  if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
690    QualType ResultTy = CallOrMsg.getResultType();
691    if (RE.notOwned()) {
692      const Expr *Ex = CallOrMsg.getOriginExpr();
693      assert(Ex);
694      ResultTy = GetReturnType(Ex, C.getASTContext());
695    }
696    if (std::optional<RefVal> updatedRefVal = refValFromRetEffect(RE, ResultTy))
697      state = setRefBinding(state, Sym, *updatedRefVal);
698  }
699
700  SmallVector<ProgramStateRef, 2> Out =
701      updateOutParameters(state, Summ, CallOrMsg);
702
703  for (ProgramStateRef St : Out) {
704    if (DeallocSent) {
705      C.addTransition(St, C.getPredecessor(), &getDeallocSentTag());
706    } else {
707      C.addTransition(St);
708    }
709  }
710}
711
712ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
713                                                 SymbolRef sym, RefVal V,
714                                                 ArgEffect AE,
715                                                 RefVal::Kind &hasErr,
716                                                 CheckerContext &C) const {
717  bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
718  if (AE.getObjKind() == ObjKind::ObjC && IgnoreRetainMsg) {
719    switch (AE.getKind()) {
720    default:
721      break;
722    case IncRef:
723      AE = AE.withKind(DoNothing);
724      break;
725    case DecRef:
726      AE = AE.withKind(DoNothing);
727      break;
728    case DecRefAndStopTrackingHard:
729      AE = AE.withKind(StopTracking);
730      break;
731    }
732  }
733
734  // Handle all use-after-releases.
735  if (V.getKind() == RefVal::Released) {
736    V = V ^ RefVal::ErrorUseAfterRelease;
737    hasErr = V.getKind();
738    return setRefBinding(state, sym, V);
739  }
740
741  switch (AE.getKind()) {
742    case UnretainedOutParameter:
743    case RetainedOutParameter:
744    case RetainedOutParameterOnZero:
745    case RetainedOutParameterOnNonZero:
746      llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
747                       "not have ref state.");
748
749    case Dealloc: // NB. we only need to add a note in a non-error case.
750      switch (V.getKind()) {
751        default:
752          llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
753        case RefVal::Owned:
754          // The object immediately transitions to the released state.
755          V = V ^ RefVal::Released;
756          V.clearCounts();
757          return setRefBinding(state, sym, V);
758        case RefVal::NotOwned:
759          V = V ^ RefVal::ErrorDeallocNotOwned;
760          hasErr = V.getKind();
761          break;
762      }
763      break;
764
765    case MayEscape:
766      if (V.getKind() == RefVal::Owned) {
767        V = V ^ RefVal::NotOwned;
768        break;
769      }
770
771      [[fallthrough]];
772
773    case DoNothing:
774      return state;
775
776    case Autorelease:
777      // Update the autorelease counts.
778      V = V.autorelease();
779      break;
780
781    case StopTracking:
782    case StopTrackingHard:
783      return removeRefBinding(state, sym);
784
785    case IncRef:
786      switch (V.getKind()) {
787        default:
788          llvm_unreachable("Invalid RefVal state for a retain.");
789        case RefVal::Owned:
790        case RefVal::NotOwned:
791          V = V + 1;
792          break;
793      }
794      break;
795
796    case DecRef:
797    case DecRefBridgedTransferred:
798    case DecRefAndStopTrackingHard:
799      switch (V.getKind()) {
800        default:
801          // case 'RefVal::Released' handled above.
802          llvm_unreachable("Invalid RefVal state for a release.");
803
804        case RefVal::Owned:
805          assert(V.getCount() > 0);
806          if (V.getCount() == 1) {
807            if (AE.getKind() == DecRefBridgedTransferred ||
808                V.getIvarAccessHistory() ==
809                  RefVal::IvarAccessHistory::AccessedDirectly)
810              V = V ^ RefVal::NotOwned;
811            else
812              V = V ^ RefVal::Released;
813          } else if (AE.getKind() == DecRefAndStopTrackingHard) {
814            return removeRefBinding(state, sym);
815          }
816
817          V = V - 1;
818          break;
819
820        case RefVal::NotOwned:
821          if (V.getCount() > 0) {
822            if (AE.getKind() == DecRefAndStopTrackingHard)
823              return removeRefBinding(state, sym);
824            V = V - 1;
825          } else if (V.getIvarAccessHistory() ==
826                       RefVal::IvarAccessHistory::AccessedDirectly) {
827            // Assume that the instance variable was holding on the object at
828            // +1, and we just didn't know.
829            if (AE.getKind() == DecRefAndStopTrackingHard)
830              return removeRefBinding(state, sym);
831            V = V.releaseViaIvar() ^ RefVal::Released;
832          } else {
833            V = V ^ RefVal::ErrorReleaseNotOwned;
834            hasErr = V.getKind();
835          }
836          break;
837      }
838      break;
839  }
840  return setRefBinding(state, sym, V);
841}
842
843const RefCountBug &
844RetainCountChecker::errorKindToBugKind(RefVal::Kind ErrorKind,
845                                       SymbolRef Sym) const {
846  switch (ErrorKind) {
847    case RefVal::ErrorUseAfterRelease:
848      return *UseAfterRelease;
849    case RefVal::ErrorReleaseNotOwned:
850      return *ReleaseNotOwned;
851    case RefVal::ErrorDeallocNotOwned:
852      if (Sym->getType()->getPointeeCXXRecordDecl())
853        return *FreeNotOwned;
854      return *DeallocNotOwned;
855    default:
856      llvm_unreachable("Unhandled error.");
857  }
858}
859
860void RetainCountChecker::processNonLeakError(ProgramStateRef St,
861                                             SourceRange ErrorRange,
862                                             RefVal::Kind ErrorKind,
863                                             SymbolRef Sym,
864                                             CheckerContext &C) const {
865  // HACK: Ignore retain-count issues on values accessed through ivars,
866  // because of cases like this:
867  //   [_contentView retain];
868  //   [_contentView removeFromSuperview];
869  //   [self addSubview:_contentView]; // invalidates 'self'
870  //   [_contentView release];
871  if (const RefVal *RV = getRefBinding(St, Sym))
872    if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
873      return;
874
875  ExplodedNode *N = C.generateErrorNode(St);
876  if (!N)
877    return;
878
879  auto report = std::make_unique<RefCountReport>(
880      errorKindToBugKind(ErrorKind, Sym),
881      C.getASTContext().getLangOpts(), N, Sym);
882  report->addRange(ErrorRange);
883  C.emitReport(std::move(report));
884}
885
886//===----------------------------------------------------------------------===//
887// Handle the return values of retain-count-related functions.
888//===----------------------------------------------------------------------===//
889
890bool RetainCountChecker::evalCall(const CallEvent &Call,
891                                  CheckerContext &C) const {
892  ProgramStateRef state = C.getState();
893  const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
894  if (!FD)
895    return false;
896
897  const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
898  if (!CE)
899    return false;
900
901  RetainSummaryManager &SmrMgr = getSummaryManager(C);
902  QualType ResultTy = Call.getResultType();
903
904  // See if the function has 'rc_ownership_trusted_implementation'
905  // annotate attribute. If it does, we will not inline it.
906  bool hasTrustedImplementationAnnotation = false;
907
908  const LocationContext *LCtx = C.getLocationContext();
909
910  using BehaviorSummary = RetainSummaryManager::BehaviorSummary;
911  std::optional<BehaviorSummary> BSmr =
912      SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation);
913
914  // See if it's one of the specific functions we know how to eval.
915  if (!BSmr)
916    return false;
917
918  // Bind the return value.
919  if (BSmr == BehaviorSummary::Identity ||
920      BSmr == BehaviorSummary::IdentityOrZero ||
921      BSmr == BehaviorSummary::IdentityThis) {
922
923    const Expr *BindReturnTo =
924        (BSmr == BehaviorSummary::IdentityThis)
925            ? cast<CXXMemberCallExpr>(CE)->getImplicitObjectArgument()
926            : CE->getArg(0);
927    SVal RetVal = state->getSVal(BindReturnTo, LCtx);
928
929    // If the receiver is unknown or the function has
930    // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
931    // return value.
932    // FIXME: this branch is very strange.
933    if (RetVal.isUnknown() ||
934        (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
935      SValBuilder &SVB = C.getSValBuilder();
936      RetVal =
937          SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
938    }
939
940    // Bind the value.
941    state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
942
943    if (BSmr == BehaviorSummary::IdentityOrZero) {
944      // Add a branch where the output is zero.
945      ProgramStateRef NullOutputState = C.getState();
946
947      // Assume that output is zero on the other branch.
948      NullOutputState = NullOutputState->BindExpr(
949          CE, LCtx, C.getSValBuilder().makeNullWithType(ResultTy),
950          /*Invalidate=*/false);
951      C.addTransition(NullOutputState, &getCastFailTag());
952
953      // And on the original branch assume that both input and
954      // output are non-zero.
955      if (auto L = RetVal.getAs<DefinedOrUnknownSVal>())
956        state = state->assume(*L, /*assumption=*/true);
957
958    }
959  }
960
961  C.addTransition(state);
962  return true;
963}
964
965ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
966                                                 CheckerContext &C) const {
967  ExplodedNode *Pred = C.getPredecessor();
968
969  // Only adjust the reference count if this is the top-level call frame,
970  // and not the result of inlining.  In the future, we should do
971  // better checking even for inlined calls, and see if they match
972  // with their expected semantics (e.g., the method should return a retained
973  // object, etc.).
974  if (!C.inTopFrame())
975    return Pred;
976
977  if (!S)
978    return Pred;
979
980  const Expr *RetE = S->getRetValue();
981  if (!RetE)
982    return Pred;
983
984  ProgramStateRef state = C.getState();
985  // We need to dig down to the symbolic base here because various
986  // custom allocators do sometimes return the symbol with an offset.
987  SymbolRef Sym = state->getSValAsScalarOrLoc(RetE, C.getLocationContext())
988                      .getAsLocSymbol(/*IncludeBaseRegions=*/true);
989  if (!Sym)
990    return Pred;
991
992  // Get the reference count binding (if any).
993  const RefVal *T = getRefBinding(state, Sym);
994  if (!T)
995    return Pred;
996
997  // Change the reference count.
998  RefVal X = *T;
999
1000  switch (X.getKind()) {
1001    case RefVal::Owned: {
1002      unsigned cnt = X.getCount();
1003      assert(cnt > 0);
1004      X.setCount(cnt - 1);
1005      X = X ^ RefVal::ReturnedOwned;
1006      break;
1007    }
1008
1009    case RefVal::NotOwned: {
1010      unsigned cnt = X.getCount();
1011      if (cnt) {
1012        X.setCount(cnt - 1);
1013        X = X ^ RefVal::ReturnedOwned;
1014      } else {
1015        X = X ^ RefVal::ReturnedNotOwned;
1016      }
1017      break;
1018    }
1019
1020    default:
1021      return Pred;
1022  }
1023
1024  // Update the binding.
1025  state = setRefBinding(state, Sym, X);
1026  Pred = C.addTransition(state);
1027
1028  // At this point we have updated the state properly.
1029  // Everything after this is merely checking to see if the return value has
1030  // been over- or under-retained.
1031
1032  // Did we cache out?
1033  if (!Pred)
1034    return nullptr;
1035
1036  // Update the autorelease counts.
1037  static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
1038  state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X, S);
1039
1040  // Have we generated a sink node?
1041  if (!state)
1042    return nullptr;
1043
1044  // Get the updated binding.
1045  T = getRefBinding(state, Sym);
1046  assert(T);
1047  X = *T;
1048
1049  // Consult the summary of the enclosing method.
1050  RetainSummaryManager &Summaries = getSummaryManager(C);
1051  const Decl *CD = &Pred->getCodeDecl();
1052  RetEffect RE = RetEffect::MakeNoRet();
1053
1054  // FIXME: What is the convention for blocks? Is there one?
1055  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
1056    const RetainSummary *Summ = Summaries.getSummary(AnyCall(MD));
1057    RE = Summ->getRetEffect();
1058  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
1059    if (!isa<CXXMethodDecl>(FD)) {
1060      const RetainSummary *Summ = Summaries.getSummary(AnyCall(FD));
1061      RE = Summ->getRetEffect();
1062    }
1063  }
1064
1065  return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
1066}
1067
1068ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
1069                                                  CheckerContext &C,
1070                                                  ExplodedNode *Pred,
1071                                                  RetEffect RE, RefVal X,
1072                                                  SymbolRef Sym,
1073                                                  ProgramStateRef state) const {
1074  // HACK: Ignore retain-count issues on values accessed through ivars,
1075  // because of cases like this:
1076  //   [_contentView retain];
1077  //   [_contentView removeFromSuperview];
1078  //   [self addSubview:_contentView]; // invalidates 'self'
1079  //   [_contentView release];
1080  if (X.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1081    return Pred;
1082
1083  // Any leaks or other errors?
1084  if (X.isReturnedOwned() && X.getCount() == 0) {
1085    if (RE.getKind() != RetEffect::NoRet) {
1086      if (!RE.isOwned()) {
1087
1088        // The returning type is a CF, we expect the enclosing method should
1089        // return ownership.
1090        X = X ^ RefVal::ErrorLeakReturned;
1091
1092        // Generate an error node.
1093        state = setRefBinding(state, Sym, X);
1094
1095        static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
1096        ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
1097        if (N) {
1098          const LangOptions &LOpts = C.getASTContext().getLangOpts();
1099          auto R =
1100              std::make_unique<RefLeakReport>(*LeakAtReturn, LOpts, N, Sym, C);
1101          C.emitReport(std::move(R));
1102        }
1103        return N;
1104      }
1105    }
1106  } else if (X.isReturnedNotOwned()) {
1107    if (RE.isOwned()) {
1108      if (X.getIvarAccessHistory() ==
1109            RefVal::IvarAccessHistory::AccessedDirectly) {
1110        // Assume the method was trying to transfer a +1 reference from a
1111        // strong ivar to the caller.
1112        state = setRefBinding(state, Sym,
1113                              X.releaseViaIvar() ^ RefVal::ReturnedOwned);
1114      } else {
1115        // Trying to return a not owned object to a caller expecting an
1116        // owned object.
1117        state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
1118
1119        static CheckerProgramPointTag
1120            ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
1121
1122        ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
1123        if (N) {
1124          auto R = std::make_unique<RefCountReport>(
1125              *ReturnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
1126          C.emitReport(std::move(R));
1127        }
1128        return N;
1129      }
1130    }
1131  }
1132  return Pred;
1133}
1134
1135//===----------------------------------------------------------------------===//
1136// Check various ways a symbol can be invalidated.
1137//===----------------------------------------------------------------------===//
1138
1139void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
1140                                   CheckerContext &C) const {
1141  ProgramStateRef state = C.getState();
1142  const MemRegion *MR = loc.getAsRegion();
1143
1144  // Find all symbols referenced by 'val' that we are tracking
1145  // and stop tracking them.
1146  if (MR && shouldEscapeRegion(MR)) {
1147    state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1148    C.addTransition(state);
1149  }
1150}
1151
1152ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
1153                                               SVal Cond,
1154                                               bool Assumption) const {
1155  // FIXME: We may add to the interface of evalAssume the list of symbols
1156  //  whose assumptions have changed.  For now we just iterate through the
1157  //  bindings and check if any of the tracked symbols are NULL.  This isn't
1158  //  too bad since the number of symbols we will track in practice are
1159  //  probably small and evalAssume is only called at branches and a few
1160  //  other places.
1161  RefBindingsTy B = state->get<RefBindings>();
1162
1163  if (B.isEmpty())
1164    return state;
1165
1166  bool changed = false;
1167  RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1168  ConstraintManager &CMgr = state->getConstraintManager();
1169
1170  for (auto &I : B) {
1171    // Check if the symbol is null stop tracking the symbol.
1172    ConditionTruthVal AllocFailed = CMgr.isNull(state, I.first);
1173    if (AllocFailed.isConstrainedTrue()) {
1174      changed = true;
1175      B = RefBFactory.remove(B, I.first);
1176    }
1177  }
1178
1179  if (changed)
1180    state = state->set<RefBindings>(B);
1181
1182  return state;
1183}
1184
1185ProgramStateRef RetainCountChecker::checkRegionChanges(
1186    ProgramStateRef state, const InvalidatedSymbols *invalidated,
1187    ArrayRef<const MemRegion *> ExplicitRegions,
1188    ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx,
1189    const CallEvent *Call) const {
1190  if (!invalidated)
1191    return state;
1192
1193  llvm::SmallPtrSet<SymbolRef, 8> AllowedSymbols;
1194
1195  for (const MemRegion *I : ExplicitRegions)
1196    if (const SymbolicRegion *SR = I->StripCasts()->getAs<SymbolicRegion>())
1197      AllowedSymbols.insert(SR->getSymbol());
1198
1199  for (SymbolRef sym : *invalidated) {
1200    if (AllowedSymbols.count(sym))
1201      continue;
1202    // Remove any existing reference-count binding.
1203    state = removeRefBinding(state, sym);
1204  }
1205  return state;
1206}
1207
1208ProgramStateRef
1209RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
1210                                            ExplodedNode *Pred,
1211                                            const ProgramPointTag *Tag,
1212                                            CheckerContext &Ctx,
1213                                            SymbolRef Sym,
1214                                            RefVal V,
1215                                            const ReturnStmt *S) const {
1216  unsigned ACnt = V.getAutoreleaseCount();
1217
1218  // No autorelease counts?  Nothing to be done.
1219  if (!ACnt)
1220    return state;
1221
1222  unsigned Cnt = V.getCount();
1223
1224  // FIXME: Handle sending 'autorelease' to already released object.
1225
1226  if (V.getKind() == RefVal::ReturnedOwned)
1227    ++Cnt;
1228
1229  // If we would over-release here, but we know the value came from an ivar,
1230  // assume it was a strong ivar that's just been relinquished.
1231  if (ACnt > Cnt &&
1232      V.getIvarAccessHistory() == RefVal::IvarAccessHistory::AccessedDirectly) {
1233    V = V.releaseViaIvar();
1234    --ACnt;
1235  }
1236
1237  if (ACnt <= Cnt) {
1238    if (ACnt == Cnt) {
1239      V.clearCounts();
1240      if (V.getKind() == RefVal::ReturnedOwned) {
1241        V = V ^ RefVal::ReturnedNotOwned;
1242      } else {
1243        V = V ^ RefVal::NotOwned;
1244      }
1245    } else {
1246      V.setCount(V.getCount() - ACnt);
1247      V.setAutoreleaseCount(0);
1248    }
1249    return setRefBinding(state, Sym, V);
1250  }
1251
1252  // HACK: Ignore retain-count issues on values accessed through ivars,
1253  // because of cases like this:
1254  //   [_contentView retain];
1255  //   [_contentView removeFromSuperview];
1256  //   [self addSubview:_contentView]; // invalidates 'self'
1257  //   [_contentView release];
1258  if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1259    return state;
1260
1261  // Woah!  More autorelease counts then retain counts left.
1262  // Emit hard error.
1263  V = V ^ RefVal::ErrorOverAutorelease;
1264  state = setRefBinding(state, Sym, V);
1265
1266  ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
1267  if (N) {
1268    SmallString<128> sbuf;
1269    llvm::raw_svector_ostream os(sbuf);
1270    os << "Object was autoreleased ";
1271    if (V.getAutoreleaseCount() > 1)
1272      os << V.getAutoreleaseCount() << " times but the object ";
1273    else
1274      os << "but ";
1275    os << "has a +" << V.getCount() << " retain count";
1276
1277    const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1278    auto R = std::make_unique<RefCountReport>(*OverAutorelease, LOpts, N, Sym,
1279                                              os.str());
1280    Ctx.emitReport(std::move(R));
1281  }
1282
1283  return nullptr;
1284}
1285
1286ProgramStateRef
1287RetainCountChecker::handleSymbolDeath(ProgramStateRef state,
1288                                      SymbolRef sid, RefVal V,
1289                                    SmallVectorImpl<SymbolRef> &Leaked) const {
1290  bool hasLeak;
1291
1292  // HACK: Ignore retain-count issues on values accessed through ivars,
1293  // because of cases like this:
1294  //   [_contentView retain];
1295  //   [_contentView removeFromSuperview];
1296  //   [self addSubview:_contentView]; // invalidates 'self'
1297  //   [_contentView release];
1298  if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1299    hasLeak = false;
1300  else if (V.isOwned())
1301    hasLeak = true;
1302  else if (V.isNotOwned() || V.isReturnedOwned())
1303    hasLeak = (V.getCount() > 0);
1304  else
1305    hasLeak = false;
1306
1307  if (!hasLeak)
1308    return removeRefBinding(state, sid);
1309
1310  Leaked.push_back(sid);
1311  return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
1312}
1313
1314ExplodedNode *
1315RetainCountChecker::processLeaks(ProgramStateRef state,
1316                                 SmallVectorImpl<SymbolRef> &Leaked,
1317                                 CheckerContext &Ctx,
1318                                 ExplodedNode *Pred) const {
1319  // Generate an intermediate node representing the leak point.
1320  ExplodedNode *N = Ctx.addTransition(state, Pred);
1321  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1322
1323  if (N) {
1324    for (SymbolRef L : Leaked) {
1325      const RefCountBug &BT = Pred ? *LeakWithinFunction : *LeakAtReturn;
1326      Ctx.emitReport(std::make_unique<RefLeakReport>(BT, LOpts, N, L, Ctx));
1327    }
1328  }
1329
1330  return N;
1331}
1332
1333void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
1334  if (!Ctx.inTopFrame())
1335    return;
1336
1337  RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
1338  const LocationContext *LCtx = Ctx.getLocationContext();
1339  const Decl *D = LCtx->getDecl();
1340  std::optional<AnyCall> C = AnyCall::forDecl(D);
1341
1342  if (!C || SmrMgr.isTrustedReferenceCountImplementation(D))
1343    return;
1344
1345  ProgramStateRef state = Ctx.getState();
1346  const RetainSummary *FunctionSummary = SmrMgr.getSummary(*C);
1347  ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
1348
1349  for (unsigned idx = 0, e = C->param_size(); idx != e; ++idx) {
1350    const ParmVarDecl *Param = C->parameters()[idx];
1351    SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1352
1353    QualType Ty = Param->getType();
1354    const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
1355    if (AE) {
1356      ObjKind K = AE->getObjKind();
1357      if (K == ObjKind::Generalized || K == ObjKind::OS ||
1358          (TrackNSCFStartParam && (K == ObjKind::ObjC || K == ObjKind::CF))) {
1359        RefVal NewVal = AE->getKind() == DecRef ? RefVal::makeOwned(K, Ty)
1360                                                : RefVal::makeNotOwned(K, Ty);
1361        state = setRefBinding(state, Sym, NewVal);
1362      }
1363    }
1364  }
1365
1366  Ctx.addTransition(state);
1367}
1368
1369void RetainCountChecker::checkEndFunction(const ReturnStmt *RS,
1370                                          CheckerContext &Ctx) const {
1371  ExplodedNode *Pred = processReturn(RS, Ctx);
1372
1373  // Created state cached out.
1374  if (!Pred) {
1375    return;
1376  }
1377
1378  ProgramStateRef state = Pred->getState();
1379  RefBindingsTy B = state->get<RefBindings>();
1380
1381  // Don't process anything within synthesized bodies.
1382  const LocationContext *LCtx = Pred->getLocationContext();
1383  if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
1384    assert(!LCtx->inTopFrame());
1385    return;
1386  }
1387
1388  for (auto &I : B) {
1389    state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
1390                                    I.first, I.second);
1391    if (!state)
1392      return;
1393  }
1394
1395  // If the current LocationContext has a parent, don't check for leaks.
1396  // We will do that later.
1397  // FIXME: we should instead check for imbalances of the retain/releases,
1398  // and suggest annotations.
1399  if (LCtx->getParent())
1400    return;
1401
1402  B = state->get<RefBindings>();
1403  SmallVector<SymbolRef, 10> Leaked;
1404
1405  for (auto &I : B)
1406    state = handleSymbolDeath(state, I.first, I.second, Leaked);
1407
1408  processLeaks(state, Leaked, Ctx, Pred);
1409}
1410
1411void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
1412                                          CheckerContext &C) const {
1413  ExplodedNode *Pred = C.getPredecessor();
1414
1415  ProgramStateRef state = C.getState();
1416  SmallVector<SymbolRef, 10> Leaked;
1417
1418  // Update counts from autorelease pools
1419  for (const auto &I: state->get<RefBindings>()) {
1420    SymbolRef Sym = I.first;
1421    if (SymReaper.isDead(Sym)) {
1422      static CheckerProgramPointTag Tag(this, "DeadSymbolAutorelease");
1423      const RefVal &V = I.second;
1424      state = handleAutoreleaseCounts(state, Pred, &Tag, C, Sym, V);
1425      if (!state)
1426        return;
1427
1428      // Fetch the new reference count from the state, and use it to handle
1429      // this symbol.
1430      state = handleSymbolDeath(state, Sym, *getRefBinding(state, Sym), Leaked);
1431    }
1432  }
1433
1434  if (Leaked.empty()) {
1435    C.addTransition(state);
1436    return;
1437  }
1438
1439  Pred = processLeaks(state, Leaked, C, Pred);
1440
1441  // Did we cache out?
1442  if (!Pred)
1443    return;
1444
1445  // Now generate a new node that nukes the old bindings.
1446  // The only bindings left at this point are the leaked symbols.
1447  RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1448  RefBindingsTy B = state->get<RefBindings>();
1449
1450  for (SymbolRef L : Leaked)
1451    B = F.remove(B, L);
1452
1453  state = state->set<RefBindings>(B);
1454  C.addTransition(state, Pred);
1455}
1456
1457void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
1458                                    const char *NL, const char *Sep) const {
1459
1460  RefBindingsTy B = State->get<RefBindings>();
1461
1462  if (B.isEmpty())
1463    return;
1464
1465  Out << Sep << NL;
1466
1467  for (auto &I : B) {
1468    Out << I.first << " : ";
1469    I.second.print(Out);
1470    Out << NL;
1471  }
1472}
1473
1474//===----------------------------------------------------------------------===//
1475// Checker registration.
1476//===----------------------------------------------------------------------===//
1477
1478std::unique_ptr<CheckerProgramPointTag> RetainCountChecker::DeallocSentTag;
1479std::unique_ptr<CheckerProgramPointTag> RetainCountChecker::CastFailTag;
1480
1481void ento::registerRetainCountBase(CheckerManager &Mgr) {
1482  auto *Chk = Mgr.registerChecker<RetainCountChecker>();
1483  Chk->DeallocSentTag =
1484      std::make_unique<CheckerProgramPointTag>(Chk, "DeallocSent");
1485  Chk->CastFailTag =
1486      std::make_unique<CheckerProgramPointTag>(Chk, "DynamicCastFail");
1487}
1488
1489bool ento::shouldRegisterRetainCountBase(const CheckerManager &mgr) {
1490  return true;
1491}
1492void ento::registerRetainCountChecker(CheckerManager &Mgr) {
1493  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1494  Chk->TrackObjCAndCFObjects = true;
1495  Chk->TrackNSCFStartParam = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
1496      Mgr.getCurrentCheckerName(), "TrackNSCFStartParam");
1497
1498#define INIT_BUGTYPE(KIND)                                                     \
1499  Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(),       \
1500                                            RefCountBug::KIND);
1501  // TODO: Ideally, we should have a checker for each of these bug types.
1502  INIT_BUGTYPE(UseAfterRelease)
1503  INIT_BUGTYPE(ReleaseNotOwned)
1504  INIT_BUGTYPE(DeallocNotOwned)
1505  INIT_BUGTYPE(FreeNotOwned)
1506  INIT_BUGTYPE(OverAutorelease)
1507  INIT_BUGTYPE(ReturnNotOwnedForOwned)
1508  INIT_BUGTYPE(LeakWithinFunction)
1509  INIT_BUGTYPE(LeakAtReturn)
1510#undef INIT_BUGTYPE
1511}
1512
1513bool ento::shouldRegisterRetainCountChecker(const CheckerManager &mgr) {
1514  return true;
1515}
1516
1517void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
1518  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1519  Chk->TrackOSObjects = true;
1520
1521  // FIXME: We want bug reports to always have the same checker name associated
1522  // with them, yet here, if RetainCountChecker is disabled but
1523  // OSObjectRetainCountChecker is enabled, the checker names will be different.
1524  // This hack will make it so that the checker name depends on which checker is
1525  // enabled rather than on the registration order.
1526  // For the most part, we want **non-hidden checkers** to be associated with
1527  // diagnostics, and **hidden checker options** with the fine-tuning of
1528  // modeling. Following this logic, OSObjectRetainCountChecker should be the
1529  // latter, but we can't just remove it for backward compatibility reasons.
1530#define LAZY_INIT_BUGTYPE(KIND)                                                \
1531  if (!Chk->KIND)                                                              \
1532    Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(),     \
1533                                              RefCountBug::KIND);
1534  LAZY_INIT_BUGTYPE(UseAfterRelease)
1535  LAZY_INIT_BUGTYPE(ReleaseNotOwned)
1536  LAZY_INIT_BUGTYPE(DeallocNotOwned)
1537  LAZY_INIT_BUGTYPE(FreeNotOwned)
1538  LAZY_INIT_BUGTYPE(OverAutorelease)
1539  LAZY_INIT_BUGTYPE(ReturnNotOwnedForOwned)
1540  LAZY_INIT_BUGTYPE(LeakWithinFunction)
1541  LAZY_INIT_BUGTYPE(LeakAtReturn)
1542#undef LAZY_INIT_BUGTYPE
1543}
1544
1545bool ento::shouldRegisterOSObjectRetainCountChecker(const CheckerManager &mgr) {
1546  return true;
1547}
1548