Clang Project

clang_source_code/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
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/PathSensitive/CallEvent.h"
16
17using namespace clang;
18using namespace ento;
19using namespace retaincountchecker;
20using llvm::StrInStrNoCase;
21
22REGISTER_MAP_WITH_PROGRAMSTATE(RefBindings, SymbolRef, RefVal)
23
24namespace clang {
25namespace ento {
26namespace retaincountchecker {
27
28const RefVal *getRefBinding(ProgramStateRef StateSymbolRef Sym) {
29  return State->get<RefBindings>(Sym);
30}
31
32// end namespace retaincountchecker
33// end namespace ento
34// end namespace clang
35
36static ProgramStateRef setRefBinding(ProgramStateRef StateSymbolRef Sym,
37                                     RefVal Val) {
38  assert(Sym != nullptr);
39  return State->set<RefBindings>(Sym, Val);
40}
41
42static ProgramStateRef removeRefBinding(ProgramStateRef StateSymbolRef Sym) {
43  return State->remove<RefBindings>(Sym);
44}
45
46void RefVal::print(raw_ostream &Outconst {
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 (cntOut << " (+ " << cnt << ")";
56      break;
57    }
58
59    case NotOwned: {
60      Out << "NotOwned";
61      unsigned cnt = getCount();
62      if (cntOut << " (+ " << cnt << ")";
63      break;
64    }
65
66    case ReturnedOwned: {
67      Out << "ReturnedOwned";
68      unsigned cnt = getCount();
69      if (cntOut << " (+ " << cnt << ")";
70      break;
71    }
72
73    case ReturnedNotOwned: {
74      Out << "ReturnedNotOwned";
75      unsigned cnt = getCount();
76      if (cntOut << " (+ " << cnt << ")";
77      break;
78    }
79
80    case Released:
81      Out << "Released";
82      break;
83
84    case ErrorDeallocNotOwned:
85      Out << "-dealloc (not-owned)";
86      break;
87
88    case ErrorLeak:
89      Out << "Leaked";
90      break;
91
92    case ErrorLeakReturned:
93      Out << "Leaked (Bad naming)";
94      break;
95
96    case ErrorUseAfterRelease:
97      Out << "Use-After-Release [ERROR]";
98      break;
99
100    case ErrorReleaseNotOwned:
101      Out << "Release of Not-Owned [ERROR]";
102      break;
103
104    case RefVal::ErrorOverAutorelease:
105      Out << "Over-autoreleased";
106      break;
107
108    case RefVal::ErrorReturnedNotOwned:
109      Out << "Non-owned object returned instead of owned";
110      break;
111  }
112
113  switch (getIvarAccessHistory()) {
114  case IvarAccessHistory::None:
115    break;
116  case IvarAccessHistory::AccessedDirectly:
117    Out << " [direct ivar access]";
118    break;
119  case IvarAccessHistory::ReleasedAfterDirectAccess:
120    Out << " [released after direct ivar access]";
121  }
122
123  if (ACnt) {
124    Out << " [autorelease -" << ACnt << ']';
125  }
126}
127
128namespace {
129class StopTrackingCallback final : public SymbolVisitor {
130  ProgramStateRef state;
131public:
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
146void RetainCountChecker::checkPostStmt(const BlockExpr *BE,
147                                       CheckerContext &Cconst {
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.
166  SmallVector<const MemRegion*, 10Regions;
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
182void RetainCountChecker::checkPostStmt(const CastExpr *CE,
183                                       CheckerContext &Cconst {
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(IncRefK);
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:
206      AE = AE.withKind(DecRefBridgedTransferred);
207      break;
208  }
209
210  ProgramStateRef state = C.getState();
211  SymbolRef Sym = C.getSVal(CE).getAsLocSymbol();
212  if (!Sym)
213    return;
214  const RefValT = getRefBinding(state, Sym);
215  if (!T)
216    return;
217
218  RefVal::Kind hasErr = (RefVal::Kind0;
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
229void RetainCountChecker::processObjCLiterals(CheckerContext &C,
230                                             const Expr *Exconst {
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,
253                          RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
254  }
255
256  C.addTransition(state);
257}
258
259void RetainCountChecker::checkPostStmt(const ObjCArrayLiteral *AL,
260                                       CheckerContext &Cconst {
261  // Apply the 'MayEscape' to all values.
262  processObjCLiterals(CAL);
263}
264
265void RetainCountChecker::checkPostStmt(const ObjCDictionaryLiteral *DL,
266                                       CheckerContext &Cconst {
267  // Apply the 'MayEscape' to all keys and values.
268  processObjCLiterals(CDL);
269}
270
271void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
272                                       CheckerContext &Cconst {
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,
279                          RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
280  }
281
282  C.addTransition(State);
283}
284
285void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
286                                       CheckerContext &Cconst {
287  Optional<LocIVarLoc = 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())
302    Kind = ObjKind::ObjC;
303  else if (coreFoundation::isCFObjectRef(Ty))
304    Kind = ObjKind::CF;
305  else
306    return;
307
308  // If the value is already known to be nil, don't bother tracking it.
309  ConstraintManager &CMgr = State->getConstraintManager();
310  if (CMgr.isNull(State, Sym).isConstrainedTrue())
311    return;
312
313  if (const RefVal *RV = getRefBinding(State, Sym)) {
314    // If we've seen this symbol before, or we're only seeing it now because
315    // of something the analyzer has synthesized, don't do anything.
316    if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None ||
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(KindTy);
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
338static 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
352const static RetainSummary *getSummary(RetainSummaryManager &Summaries,
353                                       const CallEvent &Call,
354                                       QualType ReceiverType) {
355  const Expr *CE = Call.getOriginExpr();
356  AnyCall C =
357      CE ? *AnyCall::forExpr(CE)
358         : AnyCall(cast<CXXDestructorDecl>(Call.getDecl()));
359  return Summaries.getSummary(CCall.hasNonZeroCallbackArg(),
360                              isReceiverUnconsumedSelf(Call), ReceiverType);
361}
362
363void RetainCountChecker::checkPostCall(const CallEvent &Call,
364                                       CheckerContext &Cconst {
365  RetainSummaryManager &Summaries = getSummaryManager(C);
366
367  // Leave null if no receiver.
368  QualType ReceiverType;
369  if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
370    if (MC->isInstanceMessage()) {
371      SVal ReceiverV = MC->getReceiverSVal();
372      if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
373        if (const RefVal *T = getRefBinding(C.getState(), Sym))
374          ReceiverType = T->getType();
375    }
376  }
377
378  const RetainSummary *Summ = getSummary(SummariesCallReceiverType);
379
380  if (C.wasInlined) {
381    processSummaryOfInlined(*SummCallC);
382    return;
383  }
384  checkSummary(*SummCallC);
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.
394static QualType GetReturnType(const Expr *RetEASTContext &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 :
409                    Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D));
410      }
411
412  return RetTy;
413}
414
415static Optional<RefValrefValFromRetEffect(RetEffect RE,
416                                            QualType ResultTy) {
417  if (RE.isOwned()) {
418    return RefVal::makeOwned(RE.getObjKind(), ResultTy);
419  } else if (RE.notOwned()) {
420    return RefVal::makeNotOwned(RE.getObjKind(), ResultTy);
421  }
422
423  return None;
424}
425
426static 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.
436static bool shouldEscapeOSArgumentOnCall(const CallEvent &CEunsigned 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.
448void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
449                                                 const CallEvent &CallOrMsg,
450                                                 CheckerContext &Cconst {
451  ProgramStateRef state = C.getState();
452
453  // Evaluate the effect of the arguments.
454  for (unsigned idx = 0e = 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(CallOrMsgidxT))
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
488static 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.
505static 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
520static SmallVector<ProgramStateRef2>
521updateOutParameters(ProgramStateRef Stateconst RetainSummary &Summ,
522                    const CallEvent &CE) {
523
524  SVal L = CE.getReturnValue();
525
526  // Splitting is required to support out parameters,
527  // as out parameters might be created only on the "success" branch.
528  // We want to avoid eagerly splitting unless out parameters are actually
529  // needed.
530  bool SplitNecessary = false;
531  for (auto &P : Summ.getArgEffects())
532    if (P.second.getKind() == RetainedOutParameterOnNonZero ||
533        P.second.getKind() == RetainedOutParameterOnZero)
534      SplitNecessary = true;
535
536  ProgramStateRef AssumeNonZeroReturn = State;
537  ProgramStateRef AssumeZeroReturn = State;
538
539  if (SplitNecessary) {
540    if (auto DL = L.getAs<DefinedOrUnknownSVal>()) {
541      AssumeNonZeroReturn = AssumeNonZeroReturn->assume(*DL, true);
542      AssumeZeroReturn = AssumeZeroReturn->assume(*DL, false);
543    }
544  }
545
546  for (unsigned idx = 0e = CE.getNumArgs(); idx != e; ++idx) {
547    SVal ArgVal = CE.getArgSVal(idx);
548    ArgEffect AE = Summ.getArg(idx);
549
550    auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.getAsRegion());
551    if (!ArgRegion)
552      continue;
553
554    QualType PointeeTy = ArgRegion->getValueType();
555    SVal PointeeVal = State->getSVal(ArgRegion);
556    SymbolRef Pointee = PointeeVal.getAsLocSymbol();
557    if (!Pointee)
558      continue;
559
560    if (shouldEscapeRegion(ArgRegion))
561      continue;
562
563    auto makeNotOwnedParameter = [&](ProgramStateRef St) {
564      return setRefBinding(St, Pointee,
565                           RefVal::makeNotOwned(AE.getObjKind(), PointeeTy));
566    };
567    auto makeOwnedParameter = [&](ProgramStateRef St) {
568      return setRefBinding(St, Pointee,
569                           RefVal::makeOwned(ObjKind::OS, PointeeTy));
570    };
571
572    switch (AE.getKind()) {
573    case UnretainedOutParameter:
574      AssumeNonZeroReturn = makeNotOwnedParameter(AssumeNonZeroReturn);
575      AssumeZeroReturn = makeNotOwnedParameter(AssumeZeroReturn);
576      break;
577    case RetainedOutParameter:
578      AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
579      AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
580      break;
581    case RetainedOutParameterOnNonZero:
582      AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
583      break;
584    case RetainedOutParameterOnZero:
585      AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
586      break;
587    default:
588      break;
589    }
590  }
591
592  if (SplitNecessary) {
593    return {AssumeNonZeroReturn, AssumeZeroReturn};
594  } else {
595    assert(AssumeZeroReturn == AssumeNonZeroReturn);
596    return {AssumeZeroReturn};
597  }
598}
599
600void RetainCountChecker::checkSummary(const RetainSummary &Summ,
601                                      const CallEvent &CallOrMsg,
602                                      CheckerContext &Cconst {
603  ProgramStateRef state = C.getState();
604
605  // Evaluate the effect of the arguments.
606  RefVal::Kind hasErr = (RefVal::Kind0;
607  SourceRange ErrorRange;
608  SymbolRef ErrorSym = nullptr;
609
610  // Helper tag for providing diagnostics: indicate whether dealloc was sent
611  // at this location.
612  bool DeallocSent = false;
613
614  for (unsigned idx = 0e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
615    SVal V = CallOrMsg.getArgSVal(idx);
616
617    ArgEffect Effect = Summ.getArg(idx);
618    if (SymbolRef Sym = V.getAsLocSymbol()) {
619      if (const RefVal *T = getRefBinding(state, Sym)) {
620
621        if (shouldEscapeOSArgumentOnCall(CallOrMsgidxT))
622          Effect = ArgEffect(StopTrackingHardObjKind::OS);
623
624        state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
625        if (hasErr) {
626          ErrorRange = CallOrMsg.getArgSourceRange(idx);
627          ErrorSym = Sym;
628          break;
629        } else if (Effect.getKind() == Dealloc) {
630          DeallocSent = true;
631        }
632      }
633    }
634  }
635
636  // Evaluate the effect on the message receiver / `this` argument.
637  bool ReceiverIsTracked = false;
638  if (!hasErr) {
639    if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
640      if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
641        if (const RefVal *T = getRefBinding(state, Sym)) {
642          ReceiverIsTracked = true;
643          state = updateSymbol(state, Sym, *T,
644                               Summ.getReceiverEffect(), hasErr, C);
645          if (hasErr) {
646            ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
647            ErrorSym = Sym;
648          } else if (Summ.getReceiverEffect().getKind() == Dealloc) {
649            DeallocSent = true;
650          }
651        }
652      }
653    } else if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
654      if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
655        if (const RefVal *T = getRefBinding(state, Sym)) {
656          state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
657                               hasErr, C);
658          if (hasErr) {
659            ErrorRange = MCall->getOriginExpr()->getSourceRange();
660            ErrorSym = Sym;
661          }
662        }
663      }
664    }
665  }
666
667  // Process any errors.
668  if (hasErr) {
669    processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C);
670    return;
671  }
672
673  // Consult the summary for the return value.
674  RetEffect RE = Summ.getRetEffect();
675
676  if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
677    if (ReceiverIsTracked)
678      RE = getSummaryManager(C).getObjAllocRetEffect();
679    else
680      RE = RetEffect::MakeNoRet();
681  }
682
683  if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
684    QualType ResultTy = CallOrMsg.getResultType();
685    if (RE.notOwned()) {
686      const Expr *Ex = CallOrMsg.getOriginExpr();
687      assert(Ex);
688      ResultTy = GetReturnType(ExC.getASTContext());
689    }
690    if (Optional<RefVal> updatedRefVal = refValFromRetEffect(RE, ResultTy))
691      state = setRefBinding(state, Sym, *updatedRefVal);
692  }
693
694  SmallVector<ProgramStateRef2Out =
695      updateOutParameters(state, Summ, CallOrMsg);
696
697  for (ProgramStateRef St : Out) {
698    if (DeallocSent) {
699      C.addTransition(St, C.getPredecessor(), &DeallocSentTag);
700    } else {
701      C.addTransition(St);
702    }
703  }
704}
705
706ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
707                                                 SymbolRef symRefVal V,
708                                                 ArgEffect AE,
709                                                 RefVal::Kind &hasErr,
710                                                 CheckerContext &Cconst {
711  bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
712  if (AE.getObjKind() == ObjKind::ObjC && IgnoreRetainMsg) {
713    switch (AE.getKind()) {
714    default:
715      break;
716    case IncRef:
717      AE = AE.withKind(DoNothing);
718      break;
719    case DecRef:
720      AE = AE.withKind(DoNothing);
721      break;
722    case DecRefAndStopTrackingHard:
723      AE = AE.withKind(StopTracking);
724      break;
725    }
726  }
727
728  // Handle all use-after-releases.
729  if (V.getKind() == RefVal::Released) {
730    V = V ^ RefVal::ErrorUseAfterRelease;
731    hasErr = V.getKind();
732    return setRefBinding(state, sym, V);
733  }
734
735  switch (AE.getKind()) {
736    case UnretainedOutParameter:
737    case RetainedOutParameter:
738    case RetainedOutParameterOnZero:
739    case RetainedOutParameterOnNonZero:
740      llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
741                       "not have ref state.");
742
743    case Dealloc// NB. we only need to add a note in a non-error case.
744      switch (V.getKind()) {
745        default:
746          llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
747        case RefVal::Owned:
748          // The object immediately transitions to the released state.
749          V = V ^ RefVal::Released;
750          V.clearCounts();
751          return setRefBinding(state, sym, V);
752        case RefVal::NotOwned:
753          V = V ^ RefVal::ErrorDeallocNotOwned;
754          hasErr = V.getKind();
755          break;
756      }
757      break;
758
759    case MayEscape:
760      if (V.getKind() == RefVal::Owned) {
761        V = V ^ RefVal::NotOwned;
762        break;
763      }
764
765      LLVM_FALLTHROUGH;
766
767    case DoNothing:
768      return state;
769
770    case Autorelease:
771      // Update the autorelease counts.
772      V = V.autorelease();
773      break;
774
775    case StopTracking:
776    case StopTrackingHard:
777      return removeRefBinding(state, sym);
778
779    case IncRef:
780      switch (V.getKind()) {
781        default:
782          llvm_unreachable("Invalid RefVal state for a retain.");
783        case RefVal::Owned:
784        case RefVal::NotOwned:
785          V = V + 1;
786          break;
787      }
788      break;
789
790    case DecRef:
791    case DecRefBridgedTransferred:
792    case DecRefAndStopTrackingHard:
793      switch (V.getKind()) {
794        default:
795          // case 'RefVal::Released' handled above.
796          llvm_unreachable("Invalid RefVal state for a release.");
797
798        case RefVal::Owned:
799           0", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp", 799, __PRETTY_FUNCTION__))" file_link="../../../../../include/assert.h.html#88" macro="true">assert(V.getCount() > 0);
800          if (V.getCount() == 1) {
801            if (AE.getKind() == DecRefBridgedTransferred ||
802                V.getIvarAccessHistory() ==
803                  RefVal::IvarAccessHistory::AccessedDirectly)
804              V = V ^ RefVal::NotOwned;
805            else
806              V = V ^ RefVal::Released;
807          } else if (AE.getKind() == DecRefAndStopTrackingHard) {
808            return removeRefBinding(state, sym);
809          }
810
811          V = V - 1;
812          break;
813
814        case RefVal::NotOwned:
815          if (V.getCount() > 0) {
816            if (AE.getKind() == DecRefAndStopTrackingHard)
817              return removeRefBinding(state, sym);
818            V = V - 1;
819          } else if (V.getIvarAccessHistory() ==
820                       RefVal::IvarAccessHistory::AccessedDirectly) {
821            // Assume that the instance variable was holding on the object at
822            // +1, and we just didn't know.
823            if (AE.getKind() == DecRefAndStopTrackingHard)
824              return removeRefBinding(state, sym);
825            V = V.releaseViaIvar() ^ RefVal::Released;
826          } else {
827            V = V ^ RefVal::ErrorReleaseNotOwned;
828            hasErr = V.getKind();
829          }
830          break;
831      }
832      break;
833  }
834  return setRefBinding(state, sym, V);
835}
836
837const RefCountBug &
838RetainCountChecker::errorKindToBugKind(RefVal::Kind ErrorKind,
839                                       SymbolRef Symconst {
840  switch (ErrorKind) {
841    case RefVal::ErrorUseAfterRelease:
842      return useAfterRelease;
843    case RefVal::ErrorReleaseNotOwned:
844      return releaseNotOwned;
845    case RefVal::ErrorDeallocNotOwned:
846      if (Sym->getType()->getPointeeCXXRecordDecl())
847        return freeNotOwned;
848      return deallocNotOwned;
849    default:
850      llvm_unreachable("Unhandled error.");
851  }
852}
853
854void RetainCountChecker::processNonLeakError(ProgramStateRef St,
855                                             SourceRange ErrorRange,
856                                             RefVal::Kind ErrorKind,
857                                             SymbolRef Sym,
858                                             CheckerContext &Cconst {
859  // HACK: Ignore retain-count issues on values accessed through ivars,
860  // because of cases like this:
861  //   [_contentView retain];
862  //   [_contentView removeFromSuperview];
863  //   [self addSubview:_contentView]; // invalidates 'self'
864  //   [_contentView release];
865  if (const RefVal *RV = getRefBinding(St, Sym))
866    if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
867      return;
868
869  ExplodedNode *N = C.generateErrorNode(St);
870  if (!N)
871    return;
872
873  auto report = llvm::make_unique<RefCountReport>(
874      errorKindToBugKind(ErrorKind, Sym),
875      C.getASTContext().getLangOpts(), N, Sym);
876  report->addRange(ErrorRange);
877  C.emitReport(std::move(report));
878}
879
880//===----------------------------------------------------------------------===//
881// Handle the return values of retain-count-related functions.
882//===----------------------------------------------------------------------===//
883
884bool RetainCountChecker::evalCall(const CallExpr *CECheckerContext &Cconst {
885  ProgramStateRef state = C.getState();
886  const FunctionDecl *FD = C.getCalleeDecl(CE);
887  if (!FD)
888    return false;
889
890  RetainSummaryManager &SmrMgr = getSummaryManager(C);
891  QualType ResultTy = CE->getCallReturnType(C.getASTContext());
892
893  // See if the function has 'rc_ownership_trusted_implementation'
894  // annotate attribute. If it does, we will not inline it.
895  bool hasTrustedImplementationAnnotation = false;
896
897  const LocationContext *LCtx = C.getLocationContext();
898
899  using BehaviorSummary = RetainSummaryManager::BehaviorSummary;
900  Optional<BehaviorSummaryBSmr =
901      SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation);
902
903  // See if it's one of the specific functions we know how to eval.
904  if (!BSmr)
905    return false;
906
907  // Bind the return value.
908  if (BSmr == BehaviorSummary::Identity ||
909      BSmr == BehaviorSummary::IdentityOrZero ||
910      BSmr == BehaviorSummary::IdentityThis) {
911
912    const Expr *BindReturnTo =
913        (BSmr == BehaviorSummary::IdentityThis)
914            ? cast<CXXMemberCallExpr>(CE)->getImplicitObjectArgument()
915            : CE->getArg(0);
916    SVal RetVal = state->getSVal(BindReturnTo, LCtx);
917
918    // If the receiver is unknown or the function has
919    // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
920    // return value.
921    // FIXME: this branch is very strange.
922    if (RetVal.isUnknown() ||
923        (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
924      SValBuilder &SVB = C.getSValBuilder();
925      RetVal =
926          SVB.conjureSymbolVal(nullptrCELCtxResultTyC.blockCount());
927    }
928
929    // Bind the value.
930    state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
931
932    if (BSmr == BehaviorSummary::IdentityOrZero) {
933      // Add a branch where the output is zero.
934      ProgramStateRef NullOutputState = C.getState();
935
936      // Assume that output is zero on the other branch.
937      NullOutputState = NullOutputState->BindExpr(
938          CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false);
939      C.addTransition(NullOutputState, &CastFailTag);
940
941      // And on the original branch assume that both input and
942      // output are non-zero.
943      if (auto L = RetVal.getAs<DefinedOrUnknownSVal>())
944        state = state->assume(*L, /*Assumption=*/true);
945
946    }
947  }
948
949  C.addTransition(state);
950  return true;
951}
952
953ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
954                                                 CheckerContext &Cconst {
955  ExplodedNode *Pred = C.getPredecessor();
956
957  // Only adjust the reference count if this is the top-level call frame,
958  // and not the result of inlining.  In the future, we should do
959  // better checking even for inlined calls, and see if they match
960  // with their expected semantics (e.g., the method should return a retained
961  // object, etc.).
962  if (!C.inTopFrame())
963    return Pred;
964
965  if (!S)
966    return Pred;
967
968  const Expr *RetE = S->getRetValue();
969  if (!RetE)
970    return Pred;
971
972  ProgramStateRef state = C.getState();
973  SymbolRef Sym =
974    state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
975  if (!Sym)
976    return Pred;
977
978  // Get the reference count binding (if any).
979  const RefVal *T = getRefBinding(state, Sym);
980  if (!T)
981    return Pred;
982
983  // Change the reference count.
984  RefVal X = *T;
985
986  switch (X.getKind()) {
987    case RefVal::Owned: {
988      unsigned cnt = X.getCount();
989       0", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp", 989, __PRETTY_FUNCTION__))" file_link="../../../../../include/assert.h.html#88" macro="true">assert(cnt > 0);
990      X.setCount(cnt - 1);
991      X = X ^ RefVal::ReturnedOwned;
992      break;
993    }
994
995    case RefVal::NotOwned: {
996      unsigned cnt = X.getCount();
997      if (cnt) {
998        X.setCount(cnt - 1);
999        X = X ^ RefVal::ReturnedOwned;
1000      } else {
1001        X = X ^ RefVal::ReturnedNotOwned;
1002      }
1003      break;
1004    }
1005
1006    default:
1007      return Pred;
1008  }
1009
1010  // Update the binding.
1011  state = setRefBinding(state, Sym, X);
1012  Pred = C.addTransition(state);
1013
1014  // At this point we have updated the state properly.
1015  // Everything after this is merely checking to see if the return value has
1016  // been over- or under-retained.
1017
1018  // Did we cache out?
1019  if (!Pred)
1020    return nullptr;
1021
1022  // Update the autorelease counts.
1023  static CheckerProgramPointTag AutoreleaseTag(this"Autorelease");
1024  state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X, S);
1025
1026  // Have we generated a sink node?
1027  if (!state)
1028    return nullptr;
1029
1030  // Get the updated binding.
1031  T = getRefBinding(state, Sym);
1032  assert(T);
1033  X = *T;
1034
1035  // Consult the summary of the enclosing method.
1036  RetainSummaryManager &Summaries = getSummaryManager(C);
1037  const Decl *CD = &Pred->getCodeDecl();
1038  RetEffect RE = RetEffect::MakeNoRet();
1039
1040  // FIXME: What is the convention for blocks? Is there one?
1041  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
1042    const RetainSummary *Summ = Summaries.getSummary(AnyCall(MD));
1043    RE = Summ->getRetEffect();
1044  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
1045    if (!isa<CXXMethodDecl>(FD)) {
1046      const RetainSummary *Summ = Summaries.getSummary(AnyCall(FD));
1047      RE = Summ->getRetEffect();
1048    }
1049  }
1050
1051  return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
1052}
1053
1054ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
1055                                                  CheckerContext &C,
1056                                                  ExplodedNode *Pred,
1057                                                  RetEffect RERefVal X,
1058                                                  SymbolRef Sym,
1059                                                  ProgramStateRef stateconst {
1060  // HACK: Ignore retain-count issues on values accessed through ivars,
1061  // because of cases like this:
1062  //   [_contentView retain];
1063  //   [_contentView removeFromSuperview];
1064  //   [self addSubview:_contentView]; // invalidates 'self'
1065  //   [_contentView release];
1066  if (X.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1067    return Pred;
1068
1069  // Any leaks or other errors?
1070  if (X.isReturnedOwned() && X.getCount() == 0) {
1071    if (RE.getKind() != RetEffect::NoRet) {
1072      if (!RE.isOwned()) {
1073
1074        // The returning type is a CF, we expect the enclosing method should
1075        // return ownership.
1076        X = X ^ RefVal::ErrorLeakReturned;
1077
1078        // Generate an error node.
1079        state = setRefBinding(state, Sym, X);
1080
1081        static CheckerProgramPointTag ReturnOwnLeakTag(this"ReturnsOwnLeak");
1082        ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
1083        if (N) {
1084          const LangOptions &LOpts = C.getASTContext().getLangOpts();
1085          auto R =
1086              llvm::make_unique<RefLeakReport>(leakAtReturn, LOpts, N, Sym, C);
1087          C.emitReport(std::move(R));
1088        }
1089        return N;
1090      }
1091    }
1092  } else if (X.isReturnedNotOwned()) {
1093    if (RE.isOwned()) {
1094      if (X.getIvarAccessHistory() ==
1095            RefVal::IvarAccessHistory::AccessedDirectly) {
1096        // Assume the method was trying to transfer a +1 reference from a
1097        // strong ivar to the caller.
1098        state = setRefBinding(state, Sym,
1099                              X.releaseViaIvar() ^ RefVal::ReturnedOwned);
1100      } else {
1101        // Trying to return a not owned object to a caller expecting an
1102        // owned object.
1103        state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
1104
1105        static CheckerProgramPointTag
1106            ReturnNotOwnedTag(this"ReturnNotOwnedForOwned");
1107
1108        ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
1109        if (N) {
1110          auto R = llvm::make_unique<RefCountReport>(
1111              returnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
1112          C.emitReport(std::move(R));
1113        }
1114        return N;
1115      }
1116    }
1117  }
1118  return Pred;
1119}
1120
1121//===----------------------------------------------------------------------===//
1122// Check various ways a symbol can be invalidated.
1123//===----------------------------------------------------------------------===//
1124
1125void RetainCountChecker::checkBind(SVal locSVal valconst Stmt *S,
1126                                   CheckerContext &Cconst {
1127  ProgramStateRef state = C.getState();
1128  const MemRegion *MR = loc.getAsRegion();
1129
1130  // Find all symbols referenced by 'val' that we are tracking
1131  // and stop tracking them.
1132  if (MR && shouldEscapeRegion(MR)) {
1133    state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1134    C.addTransition(state);
1135  }
1136}
1137
1138ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
1139                                               SVal Cond,
1140                                               bool Assumptionconst {
1141  // FIXME: We may add to the interface of evalAssume the list of symbols
1142  //  whose assumptions have changed.  For now we just iterate through the
1143  //  bindings and check if any of the tracked symbols are NULL.  This isn't
1144  //  too bad since the number of symbols we will track in practice are
1145  //  probably small and evalAssume is only called at branches and a few
1146  //  other places.
1147  RefBindingsTy B = state->get<RefBindings>();
1148
1149  if (B.isEmpty())
1150    return state;
1151
1152  bool changed = false;
1153  RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1154  ConstraintManager &CMgr = state->getConstraintManager();
1155
1156  for (auto &I : B) {
1157    // Check if the symbol is null stop tracking the symbol.
1158    ConditionTruthVal AllocFailed = CMgr.isNull(state, I.first);
1159    if (AllocFailed.isConstrainedTrue()) {
1160      changed = true;
1161      B = RefBFactory.remove(B, I.first);
1162    }
1163  }
1164
1165  if (changed)
1166    state = state->set<RefBindings>(B);
1167
1168  return state;
1169}
1170
1171ProgramStateRef RetainCountChecker::checkRegionChanges(
1172    ProgramStateRef stateconst InvalidatedSymbols *invalidated,
1173    ArrayRef<const MemRegion *> ExplicitRegions,
1174    ArrayRef<const MemRegion *> Regionsconst LocationContext *LCtx,
1175    const CallEvent *Callconst {
1176  if (!invalidated)
1177    return state;
1178
1179  llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
1180
1181  for (const MemRegion *I : ExplicitRegions)
1182    if (const SymbolicRegion *SR = I->StripCasts()->getAs<SymbolicRegion>())
1183      WhitelistedSymbols.insert(SR->getSymbol());
1184
1185  for (SymbolRef sym : *invalidated) {
1186    if (WhitelistedSymbols.count(sym))
1187      continue;
1188    // Remove any existing reference-count binding.
1189    state = removeRefBinding(state, sym);
1190  }
1191  return state;
1192}
1193
1194ProgramStateRef
1195RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
1196                                            ExplodedNode *Pred,
1197                                            const ProgramPointTag *Tag,
1198                                            CheckerContext &Ctx,
1199                                            SymbolRef Sym,
1200                                            RefVal V,
1201                                            const ReturnStmt *Sconst {
1202  unsigned ACnt = V.getAutoreleaseCount();
1203
1204  // No autorelease counts?  Nothing to be done.
1205  if (!ACnt)
1206    return state;
1207
1208  unsigned Cnt = V.getCount();
1209
1210  // FIXME: Handle sending 'autorelease' to already released object.
1211
1212  if (V.getKind() == RefVal::ReturnedOwned)
1213    ++Cnt;
1214
1215  // If we would over-release here, but we know the value came from an ivar,
1216  // assume it was a strong ivar that's just been relinquished.
1217  if (ACnt > Cnt &&
1218      V.getIvarAccessHistory() == RefVal::IvarAccessHistory::AccessedDirectly) {
1219    V = V.releaseViaIvar();
1220    --ACnt;
1221  }
1222
1223  if (ACnt <= Cnt) {
1224    if (ACnt == Cnt) {
1225      V.clearCounts();
1226      if (V.getKind() == RefVal::ReturnedOwned) {
1227        V = V ^ RefVal::ReturnedNotOwned;
1228      } else {
1229        V = V ^ RefVal::NotOwned;
1230      }
1231    } else {
1232      V.setCount(V.getCount() - ACnt);
1233      V.setAutoreleaseCount(0);
1234    }
1235    return setRefBinding(state, Sym, V);
1236  }
1237
1238  // HACK: Ignore retain-count issues on values accessed through ivars,
1239  // because of cases like this:
1240  //   [_contentView retain];
1241  //   [_contentView removeFromSuperview];
1242  //   [self addSubview:_contentView]; // invalidates 'self'
1243  //   [_contentView release];
1244  if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1245    return state;
1246
1247  // Woah!  More autorelease counts then retain counts left.
1248  // Emit hard error.
1249  V = V ^ RefVal::ErrorOverAutorelease;
1250  state = setRefBinding(state, Sym, V);
1251
1252  ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
1253  if (N) {
1254    SmallString<128sbuf;
1255    llvm::raw_svector_ostream os(sbuf);
1256    os << "Object was autoreleased ";
1257    if (V.getAutoreleaseCount() > 1)
1258      os << V.getAutoreleaseCount() << " times but the object ";
1259    else
1260      os << "but ";
1261    os << "has a +" << V.getCount() << " retain count";
1262
1263    const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1264    auto R = llvm::make_unique<RefCountReport>(overAutorelease, LOpts, N, Sym,
1265                                               os.str());
1266    Ctx.emitReport(std::move(R));
1267  }
1268
1269  return nullptr;
1270}
1271
1272ProgramStateRef
1273RetainCountChecker::handleSymbolDeath(ProgramStateRef state,
1274                                      SymbolRef sidRefVal V,
1275                                    SmallVectorImpl<SymbolRef> &Leakedconst {
1276  bool hasLeak;
1277
1278  // HACK: Ignore retain-count issues on values accessed through ivars,
1279  // because of cases like this:
1280  //   [_contentView retain];
1281  //   [_contentView removeFromSuperview];
1282  //   [self addSubview:_contentView]; // invalidates 'self'
1283  //   [_contentView release];
1284  if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1285    hasLeak = false;
1286  else if (V.isOwned())
1287    hasLeak = true;
1288  else if (V.isNotOwned() || V.isReturnedOwned())
1289    hasLeak = (V.getCount() > 0);
1290  else
1291    hasLeak = false;
1292
1293  if (!hasLeak)
1294    return removeRefBinding(state, sid);
1295
1296  Leaked.push_back(sid);
1297  return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
1298}
1299
1300ExplodedNode *
1301RetainCountChecker::processLeaks(ProgramStateRef state,
1302                                 SmallVectorImpl<SymbolRef> &Leaked,
1303                                 CheckerContext &Ctx,
1304                                 ExplodedNode *Predconst {
1305  // Generate an intermediate node representing the leak point.
1306  ExplodedNode *N = Ctx.addTransition(state, Pred);
1307  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1308
1309  if (N) {
1310    for (SymbolRef L : Leaked) {
1311      const RefCountBug &BT = Pred ? leakWithinFunction : leakAtReturn;
1312      Ctx.emitReport(llvm::make_unique<RefLeakReport>(BT, LOpts, N, L, Ctx));
1313    }
1314  }
1315
1316  return N;
1317}
1318
1319void RetainCountChecker::checkBeginFunction(CheckerContext &Ctxconst {
1320  if (!Ctx.inTopFrame())
1321    return;
1322
1323  RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
1324  const LocationContext *LCtx = Ctx.getLocationContext();
1325  const Decl *D = LCtx->getDecl();
1326  Optional<AnyCallC = AnyCall::forDecl(D);
1327
1328  if (!C || SmrMgr.isTrustedReferenceCountImplementation(D))
1329    return;
1330
1331  ProgramStateRef state = Ctx.getState();
1332  const RetainSummary *FunctionSummary = SmrMgr.getSummary(*C);
1333  ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
1334
1335  for (unsigned idx = 0e = C->param_size(); idx != e; ++idx) {
1336    const ParmVarDecl *Param = C->parameters()[idx];
1337    SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1338
1339    QualType Ty = Param->getType();
1340    const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
1341    if (AE) {
1342      ObjKind K = AE->getObjKind();
1343      if (K == ObjKind::Generalized || K == ObjKind::OS ||
1344          (TrackNSCFStartParam && (K == ObjKind::ObjC || K == ObjKind::CF))) {
1345        RefVal NewVal = AE->getKind() == DecRef ? RefVal::makeOwned(KTy)
1346                                                : RefVal::makeNotOwned(KTy);
1347        state = setRefBinding(state, Sym, NewVal);
1348      }
1349    }
1350  }
1351
1352  Ctx.addTransition(state);
1353}
1354
1355void RetainCountChecker::checkEndFunction(const ReturnStmt *RS,
1356                                          CheckerContext &Ctxconst {
1357  ExplodedNode *Pred = processReturn(RSCtx);
1358
1359  // Created state cached out.
1360  if (!Pred) {
1361    return;
1362  }
1363
1364  ProgramStateRef state = Pred->getState();
1365  RefBindingsTy B = state->get<RefBindings>();
1366
1367  // Don't process anything within synthesized bodies.
1368  const LocationContext *LCtx = Pred->getLocationContext();
1369  if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
1370    inTopFrame()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp", 1370, __PRETTY_FUNCTION__))" file_link="../../../../../include/assert.h.html#88" macro="true">assert(!LCtx->inTopFrame());
1371    return;
1372  }
1373
1374  for (auto &I : B) {
1375    state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
1376                                    I.first, I.second);
1377    if (!state)
1378      return;
1379  }
1380
1381  // If the current LocationContext has a parent, don't check for leaks.
1382  // We will do that later.
1383  // FIXME: we should instead check for imbalances of the retain/releases,
1384  // and suggest annotations.
1385  if (LCtx->getParent())
1386    return;
1387
1388  B = state->get<RefBindings>();
1389  SmallVector<SymbolRef10Leaked;
1390
1391  for (auto &I : B)
1392    state = handleSymbolDeath(state, I.first, I.second, Leaked);
1393
1394  processLeaks(state, Leaked, Ctx, Pred);
1395}
1396
1397void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
1398                                          CheckerContext &Cconst {
1399  ExplodedNode *Pred = C.getPredecessor();
1400
1401  ProgramStateRef state = C.getState();
1402  SmallVector<SymbolRef10Leaked;
1403
1404  // Update counts from autorelease pools
1405  for (const auto &I: state->get<RefBindings>()) {
1406    SymbolRef Sym = I.first;
1407    if (SymReaper.isDead(Sym)) {
1408      static CheckerProgramPointTag Tag(this"DeadSymbolAutorelease");
1409      const RefVal &V = I.second;
1410      state = handleAutoreleaseCounts(state, Pred, &Tag, C, Sym, V);
1411      if (!state)
1412        return;
1413
1414      // Fetch the new reference count from the state, and use it to handle
1415      // this symbol.
1416      state = handleSymbolDeath(state, Sym, *getRefBinding(state, Sym), Leaked);
1417    }
1418  }
1419
1420  if (Leaked.empty()) {
1421    C.addTransition(state);
1422    return;
1423  }
1424
1425  Pred = processLeaks(state, Leaked, C, Pred);
1426
1427  // Did we cache out?
1428  if (!Pred)
1429    return;
1430
1431  // Now generate a new node that nukes the old bindings.
1432  // The only bindings left at this point are the leaked symbols.
1433  RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1434  RefBindingsTy B = state->get<RefBindings>();
1435
1436  for (SymbolRef L : Leaked)
1437    B = F.remove(B, L);
1438
1439  state = state->set<RefBindings>(B);
1440  C.addTransition(state, Pred);
1441}
1442
1443void RetainCountChecker::printState(raw_ostream &OutProgramStateRef State,
1444                                    const char *NLconst char *Sepconst {
1445
1446  RefBindingsTy B = State->get<RefBindings>();
1447
1448  if (B.isEmpty())
1449    return;
1450
1451  Out << Sep << NL;
1452
1453  for (auto &I : B) {
1454    Out << I.first << " : ";
1455    I.second.print(Out);
1456    Out << NL;
1457  }
1458}
1459
1460//===----------------------------------------------------------------------===//
1461// Checker registration.
1462//===----------------------------------------------------------------------===//
1463
1464void ento::registerRetainCountBase(CheckerManager &Mgr) {
1465  Mgr.registerChecker<RetainCountChecker>();
1466}
1467
1468bool ento::shouldRegisterRetainCountBase(const LangOptions &LO) {
1469  return true;
1470}
1471
1472// FIXME: remove this, hack for backwards compatibility:
1473// it should be possible to enable the NS/CF retain count checker as
1474// osx.cocoa.RetainCount, and it should be possible to disable
1475// osx.OSObjectRetainCount using osx.cocoa.RetainCount:CheckOSObject=false.
1476static bool getOption(AnalyzerOptions &Options,
1477                      StringRef Postfix,
1478                      StringRef Value) {
1479  auto I = Options.Config.find(
1480    (StringRef("osx.cocoa.RetainCount:") + Postfix).str());
1481  if (I != Options.Config.end())
1482    return I->getValue() == Value;
1483  return false;
1484}
1485
1486void ento::registerRetainCountChecker(CheckerManager &Mgr) {
1487  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1488  Chk->TrackObjCAndCFObjects = true;
1489  Chk->TrackNSCFStartParam = getOption(Mgr.getAnalyzerOptions(),
1490                                       "TrackNSCFStartParam",
1491                                       "true");
1492}
1493
1494bool ento::shouldRegisterRetainCountChecker(const LangOptions &LO) {
1495  return true;
1496}
1497
1498void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
1499  auto *Chk = Mgr.getChecker<RetainCountChecker>();
1500  if (!getOption(Mgr.getAnalyzerOptions(),
1501                 "CheckOSObject",
1502                 "false"))
1503    Chk->TrackOSObjects = true;
1504}
1505
1506bool ento::shouldRegisterOSObjectRetainCountChecker(const LangOptions &LO) {
1507  return true;
1508}
1509
clang::ento::retaincountchecker::RefVal::print
clang::ento::retaincountchecker::RetainCountChecker::checkPostStmt
clang::ento::retaincountchecker::RetainCountChecker::checkPostStmt
clang::ento::retaincountchecker::RetainCountChecker::processObjCLiterals
clang::ento::retaincountchecker::RetainCountChecker::checkPostStmt
clang::ento::retaincountchecker::RetainCountChecker::checkPostStmt
clang::ento::retaincountchecker::RetainCountChecker::checkPostStmt
clang::ento::retaincountchecker::RetainCountChecker::checkPostStmt
clang::ento::retaincountchecker::RetainCountChecker::checkPostCall
clang::ento::retaincountchecker::RetainCountChecker::processSummaryOfInlined
clang::ento::retaincountchecker::RetainCountChecker::checkSummary
clang::ento::retaincountchecker::RetainCountChecker::updateSymbol
clang::ento::retaincountchecker::RetainCountChecker::errorKindToBugKind
clang::ento::retaincountchecker::RetainCountChecker::processNonLeakError
clang::ento::retaincountchecker::RetainCountChecker::evalCall
clang::ento::retaincountchecker::RetainCountChecker::processReturn
clang::ento::retaincountchecker::RetainCountChecker::checkReturnWithRetEffect
clang::ento::retaincountchecker::RetainCountChecker::checkBind
clang::ento::retaincountchecker::RetainCountChecker::evalAssume
clang::ento::retaincountchecker::RetainCountChecker::checkRegionChanges
clang::ento::retaincountchecker::RetainCountChecker::handleAutoreleaseCounts
clang::ento::retaincountchecker::RetainCountChecker::handleSymbolDeath
clang::ento::retaincountchecker::RetainCountChecker::processLeaks
clang::ento::retaincountchecker::RetainCountChecker::checkBeginFunction
clang::ento::retaincountchecker::RetainCountChecker::checkEndFunction
clang::ento::retaincountchecker::RetainCountChecker::checkDeadSymbols
clang::ento::retaincountchecker::RetainCountChecker::printState