clang  8.0.0svn
RetainCountChecker.cpp
Go to the documentation of this file.
1 //==-- RetainCountChecker.cpp - Checks for leaks and other issues -*- C++ -*--//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the methods for RetainCountChecker, which implements
11 // a reference count checker for Core Foundation and Cocoa on (Mac OS X).
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "RetainCountChecker.h"
16 
17 using namespace clang;
18 using namespace ento;
19 using namespace retaincountchecker;
20 using llvm::StrInStrNoCase;
21 
22 REGISTER_MAP_WITH_PROGRAMSTATE(RefBindings, SymbolRef, RefVal)
23 
24 namespace clang {
25 namespace ento {
26 namespace retaincountchecker {
27 
29  return State->get<RefBindings>(Sym);
30 }
31 
33  RefVal Val) {
34  assert(Sym != nullptr);
35  return State->set<RefBindings>(Sym, Val);
36 }
37 
39  return State->remove<RefBindings>(Sym);
40 }
41 
42 } // end namespace retaincountchecker
43 } // end namespace ento
44 } // end namespace clang
45 
46 void RefVal::print(raw_ostream &Out) const {
47  if (!T.isNull())
48  Out << "Tracked " << T.getAsString() << '/';
49 
50  switch (getKind()) {
51  default: llvm_unreachable("Invalid RefVal kind");
52  case Owned: {
53  Out << "Owned";
54  unsigned cnt = getCount();
55  if (cnt) Out << " (+ " << cnt << ")";
56  break;
57  }
58 
59  case NotOwned: {
60  Out << "NotOwned";
61  unsigned cnt = getCount();
62  if (cnt) Out << " (+ " << cnt << ")";
63  break;
64  }
65 
66  case ReturnedOwned: {
67  Out << "ReturnedOwned";
68  unsigned cnt = getCount();
69  if (cnt) Out << " (+ " << cnt << ")";
70  break;
71  }
72 
73  case ReturnedNotOwned: {
74  Out << "ReturnedNotOwned";
75  unsigned cnt = getCount();
76  if (cnt) Out << " (+ " << cnt << ")";
77  break;
78  }
79 
80  case Released:
81  Out << "Released";
82  break;
83 
84  case ErrorDeallocNotOwned:
85  Out << "-dealloc (not-owned)";
86  break;
87 
88  case ErrorLeak:
89  Out << "Leaked";
90  break;
91 
92  case ErrorLeakReturned:
93  Out << "Leaked (Bad naming)";
94  break;
95 
96  case ErrorUseAfterRelease:
97  Out << "Use-After-Release [ERROR]";
98  break;
99 
100  case ErrorReleaseNotOwned:
101  Out << "Release of Not-Owned [ERROR]";
102  break;
103 
105  Out << "Over-autoreleased";
106  break;
107 
109  Out << "Non-owned object returned instead of owned";
110  break;
111  }
112 
113  switch (getIvarAccessHistory()) {
115  break;
116  case IvarAccessHistory::AccessedDirectly:
117  Out << " [direct ivar access]";
118  break;
119  case IvarAccessHistory::ReleasedAfterDirectAccess:
120  Out << " [released after direct ivar access]";
121  }
122 
123  if (ACnt) {
124  Out << " [autorelease -" << ACnt << ']';
125  }
126 }
127 
128 namespace {
129 class StopTrackingCallback final : public SymbolVisitor {
131 public:
132  StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
133  ProgramStateRef getState() const { return state; }
134 
135  bool VisitSymbol(SymbolRef sym) override {
136  state = state->remove<RefBindings>(sym);
137  return true;
138  }
139 };
140 } // end anonymous namespace
141 
142 //===----------------------------------------------------------------------===//
143 // Handle statements that may have an effect on refcounts.
144 //===----------------------------------------------------------------------===//
145 
147  CheckerContext &C) const {
148 
149  // Scan the BlockDecRefExprs for any object the retain count checker
150  // may be tracking.
151  if (!BE->getBlockDecl()->hasCaptures())
152  return;
153 
155  auto *R = cast<BlockDataRegion>(C.getSVal(BE).getAsRegion());
156 
157  BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
158  E = R->referenced_vars_end();
159 
160  if (I == E)
161  return;
162 
163  // FIXME: For now we invalidate the tracking of all symbols passed to blocks
164  // via captured variables, even though captured variables result in a copy
165  // and in implicit increment/decrement of a retain count.
167  const LocationContext *LC = C.getLocationContext();
169 
170  for ( ; I != E; ++I) {
171  const VarRegion *VR = I.getCapturedRegion();
172  if (VR->getSuperRegion() == R) {
173  VR = MemMgr.getVarRegion(VR->getDecl(), LC);
174  }
175  Regions.push_back(VR);
176  }
177 
178  state =
179  state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
180  Regions.data() + Regions.size()).getState();
181  C.addTransition(state);
182 }
183 
185  CheckerContext &C) const {
186  const ObjCBridgedCastExpr *BE = dyn_cast<ObjCBridgedCastExpr>(CE);
187  if (!BE)
188  return;
189 
190  ArgEffect AE = IncRef;
191 
192  switch (BE->getBridgeKind()) {
193  case OBC_Bridge:
194  // Do nothing.
195  return;
196  case OBC_BridgeRetained:
197  AE = IncRef;
198  break;
199  case OBC_BridgeTransfer:
201  break;
202  }
203 
205  SymbolRef Sym = C.getSVal(CE).getAsLocSymbol();
206  if (!Sym)
207  return;
208  const RefVal* T = getRefBinding(state, Sym);
209  if (!T)
210  return;
211 
212  RefVal::Kind hasErr = (RefVal::Kind) 0;
213  state = updateSymbol(state, Sym, *T, AE, hasErr, C);
214 
215  if (hasErr) {
216  // FIXME: If we get an error during a bridge cast, should we report it?
217  return;
218  }
219 
220  C.addTransition(state);
221 }
222 
224  const Expr *Ex) const {
226  const ExplodedNode *pred = C.getPredecessor();
227  for (const Stmt *Child : Ex->children()) {
228  SVal V = pred->getSVal(Child);
229  if (SymbolRef sym = V.getAsSymbol())
230  if (const RefVal* T = getRefBinding(state, sym)) {
231  RefVal::Kind hasErr = (RefVal::Kind) 0;
232  state = updateSymbol(state, sym, *T, MayEscape, hasErr, C);
233  if (hasErr) {
234  processNonLeakError(state, Child->getSourceRange(), hasErr, sym, C);
235  return;
236  }
237  }
238  }
239 
240  // Return the object as autoreleased.
241  // RetEffect RE = RetEffect::MakeNotOwned(RetEffect::ObjC);
242  if (SymbolRef sym =
243  state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
244  QualType ResultTy = Ex->getType();
245  state = setRefBinding(state, sym,
247  }
248 
249  C.addTransition(state);
250 }
251 
253  CheckerContext &C) const {
254  // Apply the 'MayEscape' to all values.
255  processObjCLiterals(C, AL);
256 }
257 
259  CheckerContext &C) const {
260  // Apply the 'MayEscape' to all keys and values.
261  processObjCLiterals(C, DL);
262 }
263 
265  CheckerContext &C) const {
266  const ExplodedNode *Pred = C.getPredecessor();
267  ProgramStateRef State = Pred->getState();
268 
269  if (SymbolRef Sym = Pred->getSVal(Ex).getAsSymbol()) {
270  QualType ResultTy = Ex->getType();
271  State = setRefBinding(State, Sym,
273  }
274 
275  C.addTransition(State);
276 }
277 
279  CheckerContext &C) const {
280  Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>();
281  if (!IVarLoc)
282  return;
283 
285  SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
286  if (!Sym || !dyn_cast_or_null<ObjCIvarRegion>(Sym->getOriginRegion()))
287  return;
288 
289  // Accessing an ivar directly is unusual. If we've done that, be more
290  // forgiving about what the surrounding code is allowed to do.
291 
292  QualType Ty = Sym->getType();
294  if (Ty->isObjCRetainableType())
295  Kind = RetEffect::ObjC;
296  else if (coreFoundation::isCFObjectRef(Ty))
297  Kind = RetEffect::CF;
298  else
299  return;
300 
301  // If the value is already known to be nil, don't bother tracking it.
302  ConstraintManager &CMgr = State->getConstraintManager();
303  if (CMgr.isNull(State, Sym).isConstrainedTrue())
304  return;
305 
306  if (const RefVal *RV = getRefBinding(State, Sym)) {
307  // If we've seen this symbol before, or we're only seeing it now because
308  // of something the analyzer has synthesized, don't do anything.
309  if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None ||
311  return;
312  }
313 
314  // Note that this value has been loaded from an ivar.
315  C.addTransition(setRefBinding(State, Sym, RV->withIvarAccess()));
316  return;
317  }
318 
319  RefVal PlusZero = RefVal::makeNotOwned(Kind, Ty);
320 
321  // In a synthesized accessor, the effective retain count is +0.
323  C.addTransition(setRefBinding(State, Sym, PlusZero));
324  return;
325  }
326 
327  State = setRefBinding(State, Sym, PlusZero.withIvarAccess());
328  C.addTransition(State);
329 }
330 
332  CheckerContext &C) const {
333  RetainSummaryManager &Summaries = getSummaryManager(C);
334 
335  // Leave null if no receiver.
336  QualType ReceiverType;
337  if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
338  if (MC->isInstanceMessage()) {
339  SVal ReceiverV = MC->getReceiverSVal();
340  if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
341  if (const RefVal *T = getRefBinding(C.getState(), Sym))
342  ReceiverType = T->getType();
343  }
344  }
345 
346  const RetainSummary *Summ = Summaries.getSummary(Call, ReceiverType);
347 
348  if (C.wasInlined) {
349  processSummaryOfInlined(*Summ, Call, C);
350  return;
351  }
352  checkSummary(*Summ, Call, C);
353 }
354 
355 /// GetReturnType - Used to get the return type of a message expression or
356 /// function call with the intention of affixing that type to a tracked symbol.
357 /// While the return type can be queried directly from RetEx, when
358 /// invoking class methods we augment to the return type to be that of
359 /// a pointer to the class (as opposed it just being id).
360 // FIXME: We may be able to do this with related result types instead.
361 // This function is probably overestimating.
362 static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) {
363  QualType RetTy = RetE->getType();
364  // If RetE is not a message expression just return its type.
365  // If RetE is a message expression, return its types if it is something
366  /// more specific than id.
367  if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
368  if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>())
369  if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
370  PT->isObjCClassType()) {
371  // At this point we know the return type of the message expression is
372  // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
373  // is a call to a class method whose type we can resolve. In such
374  // cases, promote the return type to XXX* (where XXX is the class).
375  const ObjCInterfaceDecl *D = ME->getReceiverInterface();
376  return !D ? RetTy :
378  }
379 
380  return RetTy;
381 }
382 
384  QualType ResultTy) {
385  if (RE.isOwned()) {
386  return RefVal::makeOwned(RE.getObjKind(), ResultTy);
387  } else if (RE.notOwned()) {
388  return RefVal::makeNotOwned(RE.getObjKind(), ResultTy);
389  }
390 
391  return None;
392 }
393 
394 // We don't always get the exact modeling of the function with regards to the
395 // retain count checker even when the function is inlined. For example, we need
396 // to stop tracking the symbols which were marked with StopTrackingHard.
398  const CallEvent &CallOrMsg,
399  CheckerContext &C) const {
401 
402  // Evaluate the effect of the arguments.
403  for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
404  if (Summ.getArg(idx) == StopTrackingHard) {
405  SVal V = CallOrMsg.getArgSVal(idx);
406  if (SymbolRef Sym = V.getAsLocSymbol()) {
407  state = removeRefBinding(state, Sym);
408  }
409  }
410  }
411 
412  // Evaluate the effect on the message receiver.
413  if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
414  if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
415  if (Summ.getReceiverEffect() == StopTrackingHard) {
416  state = removeRefBinding(state, Sym);
417  }
418  }
419  }
420 
421  // Consult the summary for the return value.
422  RetEffect RE = Summ.getRetEffect();
423 
424  if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
425  if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
426  if (Optional<RefVal> updatedRefVal =
427  refValFromRetEffect(RE, MCall->getResultType())) {
428  state = setRefBinding(state, Sym, *updatedRefVal);
429  }
430  }
431 
432  if (RE.getKind() == RetEffect::NoRetHard)
433  state = removeRefBinding(state, Sym);
434  }
435 
436  C.addTransition(state);
437 }
438 
440  SVal ArgVal,
441  ArgEffect Effect) {
442  auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.getAsRegion());
443  if (!ArgRegion)
444  return State;
445 
446  QualType PointeeTy = ArgRegion->getValueType();
447  if (!coreFoundation::isCFObjectRef(PointeeTy))
448  return State;
449 
450  SVal PointeeVal = State->getSVal(ArgRegion);
451  SymbolRef Pointee = PointeeVal.getAsLocSymbol();
452  if (!Pointee)
453  return State;
454 
455  switch (Effect) {
457  State = setRefBinding(State, Pointee,
458  RefVal::makeNotOwned(RetEffect::CF, PointeeTy));
459  break;
461  // Do nothing. Retained out parameters will either point to a +1 reference
462  // or NULL, but the way you check for failure differs depending on the API.
463  // Consequently, we don't have a good way to track them yet.
464  break;
465 
466  default:
467  llvm_unreachable("only for out parameters");
468  }
469 
470  return State;
471 }
472 
474  const CallEvent &CallOrMsg,
475  CheckerContext &C) const {
477 
478  // Evaluate the effect of the arguments.
479  RefVal::Kind hasErr = (RefVal::Kind) 0;
480  SourceRange ErrorRange;
481  SymbolRef ErrorSym = nullptr;
482 
483  for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
484  SVal V = CallOrMsg.getArgSVal(idx);
485 
486  ArgEffect Effect = Summ.getArg(idx);
487  if (Effect == RetainedOutParameter || Effect == UnretainedOutParameter) {
488  state = updateOutParameter(state, V, Effect);
489  } else if (SymbolRef Sym = V.getAsLocSymbol()) {
490  if (const RefVal *T = getRefBinding(state, Sym)) {
491  state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
492  if (hasErr) {
493  ErrorRange = CallOrMsg.getArgSourceRange(idx);
494  ErrorSym = Sym;
495  break;
496  }
497  }
498  }
499  }
500 
501  // Evaluate the effect on the message receiver / `this` argument.
502  bool ReceiverIsTracked = false;
503  if (!hasErr) {
504  if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
505  if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
506  if (const RefVal *T = getRefBinding(state, Sym)) {
507  ReceiverIsTracked = true;
508  state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
509  hasErr, C);
510  if (hasErr) {
511  ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
512  ErrorSym = Sym;
513  }
514  }
515  }
516  } else if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
517  if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
518  if (const RefVal *T = getRefBinding(state, Sym)) {
519  state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
520  hasErr, C);
521  if (hasErr) {
522  ErrorRange = MCall->getOriginExpr()->getSourceRange();
523  ErrorSym = Sym;
524  }
525  }
526  }
527  }
528  }
529 
530  // Process any errors.
531  if (hasErr) {
532  processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C);
533  return;
534  }
535 
536  // Consult the summary for the return value.
537  RetEffect RE = Summ.getRetEffect();
538 
540  if (ReceiverIsTracked)
541  RE = getSummaryManager(C).getObjAllocRetEffect();
542  else
543  RE = RetEffect::MakeNoRet();
544  }
545 
546  if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
547  QualType ResultTy = CallOrMsg.getResultType();
548  if (RE.notOwned()) {
549  const Expr *Ex = CallOrMsg.getOriginExpr();
550  assert(Ex);
551  ResultTy = GetReturnType(Ex, C.getASTContext());
552  }
553  if (Optional<RefVal> updatedRefVal = refValFromRetEffect(RE, ResultTy))
554  state = setRefBinding(state, Sym, *updatedRefVal);
555  }
556 
557  // This check is actually necessary; otherwise the statement builder thinks
558  // we've hit a previously-found path.
559  // Normally addTransition takes care of this, but we want the node pointer.
560  ExplodedNode *NewNode;
561  if (state == C.getState()) {
562  NewNode = C.getPredecessor();
563  } else {
564  NewNode = C.addTransition(state);
565  }
566 
567  // Annotate the node with summary we used.
568  if (NewNode) {
569  // FIXME: This is ugly. See checkEndAnalysis for why it's necessary.
570  if (ShouldResetSummaryLog) {
571  SummaryLog.clear();
572  ShouldResetSummaryLog = false;
573  }
574  SummaryLog[NewNode] = &Summ;
575  }
576 }
577 
580  RefVal V, ArgEffect E, RefVal::Kind &hasErr,
581  CheckerContext &C) const {
582  bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
583  switch (E) {
584  default:
585  break;
586  case IncRefMsg:
587  E = IgnoreRetainMsg ? DoNothing : IncRef;
588  break;
589  case DecRefMsg:
590  E = IgnoreRetainMsg ? DoNothing: DecRef;
591  break;
593  E = IgnoreRetainMsg ? StopTracking : DecRefAndStopTrackingHard;
594  break;
595  case MakeCollectable:
596  E = DoNothing;
597  }
598 
599  // Handle all use-after-releases.
600  if (V.getKind() == RefVal::Released) {
602  hasErr = V.getKind();
603  return setRefBinding(state, sym, V);
604  }
605 
606  switch (E) {
607  case DecRefMsg:
608  case IncRefMsg:
609  case MakeCollectable:
611  llvm_unreachable("DecRefMsg/IncRefMsg/MakeCollectable already converted");
612 
615  llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
616  "not have ref state.");
617 
618  case Dealloc:
619  switch (V.getKind()) {
620  default:
621  llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
622  case RefVal::Owned:
623  // The object immediately transitions to the released state.
624  V = V ^ RefVal::Released;
625  V.clearCounts();
626  return setRefBinding(state, sym, V);
627  case RefVal::NotOwned:
629  hasErr = V.getKind();
630  break;
631  }
632  break;
633 
634  case MayEscape:
635  if (V.getKind() == RefVal::Owned) {
636  V = V ^ RefVal::NotOwned;
637  break;
638  }
639 
640  // Fall-through.
641 
642  case DoNothing:
643  return state;
644 
645  case Autorelease:
646  // Update the autorelease counts.
647  V = V.autorelease();
648  break;
649 
650  case StopTracking:
651  case StopTrackingHard:
652  return removeRefBinding(state, sym);
653 
654  case IncRef:
655  switch (V.getKind()) {
656  default:
657  llvm_unreachable("Invalid RefVal state for a retain.");
658  case RefVal::Owned:
659  case RefVal::NotOwned:
660  V = V + 1;
661  break;
662  }
663  break;
664 
665  case DecRef:
668  switch (V.getKind()) {
669  default:
670  // case 'RefVal::Released' handled above.
671  llvm_unreachable("Invalid RefVal state for a release.");
672 
673  case RefVal::Owned:
674  assert(V.getCount() > 0);
675  if (V.getCount() == 1) {
676  if (E == DecRefBridgedTransferred ||
677  V.getIvarAccessHistory() ==
679  V = V ^ RefVal::NotOwned;
680  else
681  V = V ^ RefVal::Released;
682  } else if (E == DecRefAndStopTrackingHard) {
683  return removeRefBinding(state, sym);
684  }
685 
686  V = V - 1;
687  break;
688 
689  case RefVal::NotOwned:
690  if (V.getCount() > 0) {
691  if (E == DecRefAndStopTrackingHard)
692  return removeRefBinding(state, sym);
693  V = V - 1;
694  } else if (V.getIvarAccessHistory() ==
696  // Assume that the instance variable was holding on the object at
697  // +1, and we just didn't know.
698  if (E == DecRefAndStopTrackingHard)
699  return removeRefBinding(state, sym);
701  } else {
703  hasErr = V.getKind();
704  }
705  break;
706  }
707  break;
708  }
709  return setRefBinding(state, sym, V);
710 }
711 
713  SourceRange ErrorRange,
715  SymbolRef Sym,
716  CheckerContext &C) const {
717  // HACK: Ignore retain-count issues on values accessed through ivars,
718  // because of cases like this:
719  // [_contentView retain];
720  // [_contentView removeFromSuperview];
721  // [self addSubview:_contentView]; // invalidates 'self'
722  // [_contentView release];
723  if (const RefVal *RV = getRefBinding(St, Sym))
724  if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
725  return;
726 
727  ExplodedNode *N = C.generateErrorNode(St);
728  if (!N)
729  return;
730 
731  CFRefBug *BT;
732  switch (ErrorKind) {
733  default:
734  llvm_unreachable("Unhandled error.");
736  if (!useAfterRelease)
737  useAfterRelease.reset(new UseAfterRelease(this));
738  BT = useAfterRelease.get();
739  break;
741  if (!releaseNotOwned)
742  releaseNotOwned.reset(new BadRelease(this));
743  BT = releaseNotOwned.get();
744  break;
746  if (!deallocNotOwned)
747  deallocNotOwned.reset(new DeallocNotOwned(this));
748  BT = deallocNotOwned.get();
749  break;
750  }
751 
752  assert(BT);
753  auto report = std::unique_ptr<BugReport>(
754  new CFRefReport(*BT, C.getASTContext().getLangOpts(),
755  SummaryLog, N, Sym));
756  report->addRange(ErrorRange);
757  C.emitReport(std::move(report));
758 }
759 
760 //===----------------------------------------------------------------------===//
761 // Handle the return values of retain-count-related functions.
762 //===----------------------------------------------------------------------===//
763 
765  // Get the callee. We're only interested in simple C functions.
767  const FunctionDecl *FD = C.getCalleeDecl(CE);
768  if (!FD)
769  return false;
770 
771  RetainSummaryManager &SmrMgr = getSummaryManager(C);
772  QualType ResultTy = CE->getCallReturnType(C.getASTContext());
773 
774  // See if the function has 'rc_ownership_trusted_implementation'
775  // annotate attribute. If it does, we will not inline it.
776  bool hasTrustedImplementationAnnotation = false;
777 
778  // See if it's one of the specific functions we know how to eval.
779  if (!SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation))
780  return false;
781 
782  // Bind the return value.
783  const LocationContext *LCtx = C.getLocationContext();
784  SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
785  if (RetVal.isUnknown() ||
786  (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
787  // If the receiver is unknown or the function has
788  // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
789  // return value.
790  SValBuilder &SVB = C.getSValBuilder();
791  RetVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
792  }
793  state = state->BindExpr(CE, LCtx, RetVal, false);
794 
795  // FIXME: This should not be necessary, but otherwise the argument seems to be
796  // considered alive during the next statement.
797  if (const MemRegion *ArgRegion = RetVal.getAsRegion()) {
798  // Save the refcount status of the argument.
799  SymbolRef Sym = RetVal.getAsLocSymbol();
800  const RefVal *Binding = nullptr;
801  if (Sym)
802  Binding = getRefBinding(state, Sym);
803 
804  // Invalidate the argument region.
805  state = state->invalidateRegions(
806  ArgRegion, CE, C.blockCount(), LCtx,
807  /*CausesPointerEscape*/ hasTrustedImplementationAnnotation);
808 
809  // Restore the refcount status of the argument.
810  if (Binding)
811  state = setRefBinding(state, Sym, *Binding);
812  }
813 
814  C.addTransition(state);
815  return true;
816 }
817 
818 //===----------------------------------------------------------------------===//
819 // Handle return statements.
820 //===----------------------------------------------------------------------===//
821 
823  CheckerContext &C) const {
824 
825  // Only adjust the reference count if this is the top-level call frame,
826  // and not the result of inlining. In the future, we should do
827  // better checking even for inlined calls, and see if they match
828  // with their expected semantics (e.g., the method should return a retained
829  // object, etc.).
830  if (!C.inTopFrame())
831  return;
832 
833  const Expr *RetE = S->getRetValue();
834  if (!RetE)
835  return;
836 
838  SymbolRef Sym =
839  state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
840  if (!Sym)
841  return;
842 
843  // Get the reference count binding (if any).
844  const RefVal *T = getRefBinding(state, Sym);
845  if (!T)
846  return;
847 
848  // Change the reference count.
849  RefVal X = *T;
850 
851  switch (X.getKind()) {
852  case RefVal::Owned: {
853  unsigned cnt = X.getCount();
854  assert(cnt > 0);
855  X.setCount(cnt - 1);
856  X = X ^ RefVal::ReturnedOwned;
857  break;
858  }
859 
860  case RefVal::NotOwned: {
861  unsigned cnt = X.getCount();
862  if (cnt) {
863  X.setCount(cnt - 1);
864  X = X ^ RefVal::ReturnedOwned;
865  }
866  else {
867  X = X ^ RefVal::ReturnedNotOwned;
868  }
869  break;
870  }
871 
872  default:
873  return;
874  }
875 
876  // Update the binding.
877  state = setRefBinding(state, Sym, X);
878  ExplodedNode *Pred = C.addTransition(state);
879 
880  // At this point we have updated the state properly.
881  // Everything after this is merely checking to see if the return value has
882  // been over- or under-retained.
883 
884  // Did we cache out?
885  if (!Pred)
886  return;
887 
888  // Update the autorelease counts.
889  static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
890  state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X);
891 
892  // Did we cache out?
893  if (!state)
894  return;
895 
896  // Get the updated binding.
897  T = getRefBinding(state, Sym);
898  assert(T);
899  X = *T;
900 
901  // Consult the summary of the enclosing method.
902  RetainSummaryManager &Summaries = getSummaryManager(C);
903  const Decl *CD = &Pred->getCodeDecl();
905 
906  // FIXME: What is the convention for blocks? Is there one?
907  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
908  const RetainSummary *Summ = Summaries.getMethodSummary(MD);
909  RE = Summ->getRetEffect();
910  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
911  if (!isa<CXXMethodDecl>(FD)) {
912  const RetainSummary *Summ = Summaries.getFunctionSummary(FD);
913  RE = Summ->getRetEffect();
914  }
915  }
916 
917  checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
918 }
919 
921  CheckerContext &C,
922  ExplodedNode *Pred,
923  RetEffect RE, RefVal X,
924  SymbolRef Sym,
925  ProgramStateRef state) const {
926  // HACK: Ignore retain-count issues on values accessed through ivars,
927  // because of cases like this:
928  // [_contentView retain];
929  // [_contentView removeFromSuperview];
930  // [self addSubview:_contentView]; // invalidates 'self'
931  // [_contentView release];
933  return;
934 
935  // Any leaks or other errors?
936  if (X.isReturnedOwned() && X.getCount() == 0) {
937  if (RE.getKind() != RetEffect::NoRet) {
938  bool hasError = false;
939  if (!RE.isOwned()) {
940  // The returning type is a CF, we expect the enclosing method should
941  // return ownership.
942  hasError = true;
944  }
945 
946  if (hasError) {
947  // Generate an error node.
948  state = setRefBinding(state, Sym, X);
949 
950  static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
951  ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
952  if (N) {
953  const LangOptions &LOpts = C.getASTContext().getLangOpts();
954  C.emitReport(std::unique_ptr<BugReport>(new CFRefLeakReport(
955  *getLeakAtReturnBug(LOpts), LOpts,
956  SummaryLog, N, Sym, C, IncludeAllocationLine)));
957  }
958  }
959  }
960  } else if (X.isReturnedNotOwned()) {
961  if (RE.isOwned()) {
962  if (X.getIvarAccessHistory() ==
964  // Assume the method was trying to transfer a +1 reference from a
965  // strong ivar to the caller.
966  state = setRefBinding(state, Sym,
968  } else {
969  // Trying to return a not owned object to a caller expecting an
970  // owned object.
971  state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
972 
974  ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
975 
976  ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
977  if (N) {
978  if (!returnNotOwnedForOwned)
979  returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
980 
981  C.emitReport(std::unique_ptr<BugReport>(new CFRefReport(
982  *returnNotOwnedForOwned, C.getASTContext().getLangOpts(),
983  SummaryLog, N, Sym)));
984  }
985  }
986  }
987  }
988 }
989 
990 //===----------------------------------------------------------------------===//
991 // Check various ways a symbol can be invalidated.
992 //===----------------------------------------------------------------------===//
993 
994 void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
995  CheckerContext &C) const {
996  // Are we storing to something that causes the value to "escape"?
997  bool escapes = true;
998 
999  // A value escapes in three possible cases (this may change):
1000  //
1001  // (1) we are binding to something that is not a memory region.
1002  // (2) we are binding to a memregion that does not have stack storage
1003  // (3) we are binding to a memregion with stack storage that the store
1004  // does not understand.
1006 
1007  if (auto regionLoc = loc.getAs<loc::MemRegionVal>()) {
1008  escapes = !regionLoc->getRegion()->hasStackStorage();
1009 
1010  if (!escapes) {
1011  // To test (3), generate a new state with the binding added. If it is
1012  // the same state, then it escapes (since the store cannot represent
1013  // the binding).
1014  // Do this only if we know that the store is not supposed to generate the
1015  // same state.
1016  SVal StoredVal = state->getSVal(regionLoc->getRegion());
1017  if (StoredVal != val)
1018  escapes = (state == (state->bindLoc(*regionLoc, val, C.getLocationContext())));
1019  }
1020  if (!escapes) {
1021  // Case 4: We do not currently model what happens when a symbol is
1022  // assigned to a struct field, so be conservative here and let the symbol
1023  // go. TODO: This could definitely be improved upon.
1024  escapes = !isa<VarRegion>(regionLoc->getRegion());
1025  }
1026  }
1027 
1028  // If we are storing the value into an auto function scope variable annotated
1029  // with (__attribute__((cleanup))), stop tracking the value to avoid leak
1030  // false positives.
1031  if (const auto *LVR = dyn_cast_or_null<VarRegion>(loc.getAsRegion())) {
1032  const VarDecl *VD = LVR->getDecl();
1033  if (VD->hasAttr<CleanupAttr>()) {
1034  escapes = true;
1035  }
1036  }
1037 
1038  // If our store can represent the binding and we aren't storing to something
1039  // that doesn't have local storage then just return and have the simulation
1040  // state continue as is.
1041  if (!escapes)
1042  return;
1043 
1044  // Otherwise, find all symbols referenced by 'val' that we are tracking
1045  // and stop tracking them.
1046  state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1047  C.addTransition(state);
1048 }
1049 
1051  SVal Cond,
1052  bool Assumption) const {
1053  // FIXME: We may add to the interface of evalAssume the list of symbols
1054  // whose assumptions have changed. For now we just iterate through the
1055  // bindings and check if any of the tracked symbols are NULL. This isn't
1056  // too bad since the number of symbols we will track in practice are
1057  // probably small and evalAssume is only called at branches and a few
1058  // other places.
1059  RefBindingsTy B = state->get<RefBindings>();
1060 
1061  if (B.isEmpty())
1062  return state;
1063 
1064  bool changed = false;
1065  RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1066 
1067  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1068  // Check if the symbol is null stop tracking the symbol.
1069  ConstraintManager &CMgr = state->getConstraintManager();
1070  ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
1071  if (AllocFailed.isConstrainedTrue()) {
1072  changed = true;
1073  B = RefBFactory.remove(B, I.getKey());
1074  }
1075  }
1076 
1077  if (changed)
1078  state = state->set<RefBindings>(B);
1079 
1080  return state;
1081 }
1082 
1085  const InvalidatedSymbols *invalidated,
1086  ArrayRef<const MemRegion *> ExplicitRegions,
1088  const LocationContext *LCtx,
1089  const CallEvent *Call) const {
1090  if (!invalidated)
1091  return state;
1092 
1093  llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
1094  for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
1095  E = ExplicitRegions.end(); I != E; ++I) {
1096  if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>())
1097  WhitelistedSymbols.insert(SR->getSymbol());
1098  }
1099 
1100  for (InvalidatedSymbols::const_iterator I=invalidated->begin(),
1101  E = invalidated->end(); I!=E; ++I) {
1102  SymbolRef sym = *I;
1103  if (WhitelistedSymbols.count(sym))
1104  continue;
1105  // Remove any existing reference-count binding.
1106  state = removeRefBinding(state, sym);
1107  }
1108  return state;
1109 }
1110 
1111 //===----------------------------------------------------------------------===//
1112 // Handle dead symbols and end-of-path.
1113 //===----------------------------------------------------------------------===//
1114 
1117  ExplodedNode *Pred,
1118  const ProgramPointTag *Tag,
1119  CheckerContext &Ctx,
1120  SymbolRef Sym, RefVal V) const {
1121  unsigned ACnt = V.getAutoreleaseCount();
1122 
1123  // No autorelease counts? Nothing to be done.
1124  if (!ACnt)
1125  return state;
1126 
1127  unsigned Cnt = V.getCount();
1128 
1129  // FIXME: Handle sending 'autorelease' to already released object.
1130 
1131  if (V.getKind() == RefVal::ReturnedOwned)
1132  ++Cnt;
1133 
1134  // If we would over-release here, but we know the value came from an ivar,
1135  // assume it was a strong ivar that's just been relinquished.
1136  if (ACnt > Cnt &&
1138  V = V.releaseViaIvar();
1139  --ACnt;
1140  }
1141 
1142  if (ACnt <= Cnt) {
1143  if (ACnt == Cnt) {
1144  V.clearCounts();
1145  if (V.getKind() == RefVal::ReturnedOwned)
1146  V = V ^ RefVal::ReturnedNotOwned;
1147  else
1148  V = V ^ RefVal::NotOwned;
1149  } else {
1150  V.setCount(V.getCount() - ACnt);
1151  V.setAutoreleaseCount(0);
1152  }
1153  return setRefBinding(state, Sym, V);
1154  }
1155 
1156  // HACK: Ignore retain-count issues on values accessed through ivars,
1157  // because of cases like this:
1158  // [_contentView retain];
1159  // [_contentView removeFromSuperview];
1160  // [self addSubview:_contentView]; // invalidates 'self'
1161  // [_contentView release];
1163  return state;
1164 
1165  // Woah! More autorelease counts then retain counts left.
1166  // Emit hard error.
1168  state = setRefBinding(state, Sym, V);
1169 
1170  ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
1171  if (N) {
1172  SmallString<128> sbuf;
1173  llvm::raw_svector_ostream os(sbuf);
1174  os << "Object was autoreleased ";
1175  if (V.getAutoreleaseCount() > 1)
1176  os << V.getAutoreleaseCount() << " times but the object ";
1177  else
1178  os << "but ";
1179  os << "has a +" << V.getCount() << " retain count";
1180 
1181  if (!overAutorelease)
1182  overAutorelease.reset(new OverAutorelease(this));
1183 
1184  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1185  Ctx.emitReport(std::unique_ptr<BugReport>(
1186  new CFRefReport(*overAutorelease, LOpts,
1187  SummaryLog, N, Sym, os.str())));
1188  }
1189 
1190  return nullptr;
1191 }
1192 
1195  SymbolRef sid, RefVal V,
1196  SmallVectorImpl<SymbolRef> &Leaked) const {
1197  bool hasLeak;
1198 
1199  // HACK: Ignore retain-count issues on values accessed through ivars,
1200  // because of cases like this:
1201  // [_contentView retain];
1202  // [_contentView removeFromSuperview];
1203  // [self addSubview:_contentView]; // invalidates 'self'
1204  // [_contentView release];
1206  hasLeak = false;
1207  else if (V.isOwned())
1208  hasLeak = true;
1209  else if (V.isNotOwned() || V.isReturnedOwned())
1210  hasLeak = (V.getCount() > 0);
1211  else
1212  hasLeak = false;
1213 
1214  if (!hasLeak)
1215  return removeRefBinding(state, sid);
1216 
1217  Leaked.push_back(sid);
1218  return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
1219 }
1220 
1221 ExplodedNode *
1224  CheckerContext &Ctx,
1225  ExplodedNode *Pred) const {
1226  // Generate an intermediate node representing the leak point.
1227  ExplodedNode *N = Ctx.addTransition(state, Pred);
1228 
1229  if (N) {
1231  I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
1232 
1233  const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1234  CFRefBug *BT = Pred ? getLeakWithinFunctionBug(LOpts)
1235  : getLeakAtReturnBug(LOpts);
1236  assert(BT && "BugType not initialized.");
1237 
1238  Ctx.emitReport(std::unique_ptr<BugReport>(
1239  new CFRefLeakReport(*BT, LOpts, SummaryLog, N, *I, Ctx,
1240  IncludeAllocationLine)));
1241  }
1242  }
1243 
1244  return N;
1245 }
1246 
1247 static bool isISLObjectRef(QualType Ty) {
1248  return StringRef(Ty.getAsString()).startswith("isl_");
1249 }
1250 
1252  if (!Ctx.inTopFrame())
1253  return;
1254 
1255  RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
1256  const LocationContext *LCtx = Ctx.getLocationContext();
1257  const FunctionDecl *FD = dyn_cast<FunctionDecl>(LCtx->getDecl());
1258 
1259  if (!FD || SmrMgr.isTrustedReferenceCountImplementation(FD))
1260  return;
1261 
1262  ProgramStateRef state = Ctx.getState();
1263  const RetainSummary *FunctionSummary = SmrMgr.getFunctionSummary(FD);
1264  ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
1265 
1266  for (unsigned idx = 0, e = FD->getNumParams(); idx != e; ++idx) {
1267  const ParmVarDecl *Param = FD->getParamDecl(idx);
1268  SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1269 
1270  QualType Ty = Param->getType();
1271  const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
1272  if (AE && *AE == DecRef && isISLObjectRef(Ty)) {
1273  state = setRefBinding(
1274  state, Sym, RefVal::makeOwned(RetEffect::ObjKind::Generalized, Ty));
1275  } else if (isISLObjectRef(Ty)) {
1276  state = setRefBinding(
1277  state, Sym,
1278  RefVal::makeNotOwned(RetEffect::ObjKind::Generalized, Ty));
1279  }
1280  }
1281 
1282  Ctx.addTransition(state);
1283 }
1284 
1286  CheckerContext &Ctx) const {
1287  ProgramStateRef state = Ctx.getState();
1288  RefBindingsTy B = state->get<RefBindings>();
1289  ExplodedNode *Pred = Ctx.getPredecessor();
1290 
1291  // Don't process anything within synthesized bodies.
1292  const LocationContext *LCtx = Pred->getLocationContext();
1294  assert(!LCtx->inTopFrame());
1295  return;
1296  }
1297 
1298  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1299  state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
1300  I->first, I->second);
1301  if (!state)
1302  return;
1303  }
1304 
1305  // If the current LocationContext has a parent, don't check for leaks.
1306  // We will do that later.
1307  // FIXME: we should instead check for imbalances of the retain/releases,
1308  // and suggest annotations.
1309  if (LCtx->getParent())
1310  return;
1311 
1312  B = state->get<RefBindings>();
1314 
1315  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
1316  state = handleSymbolDeath(state, I->first, I->second, Leaked);
1317 
1318  processLeaks(state, Leaked, Ctx, Pred);
1319 }
1320 
1321 const ProgramPointTag *
1323  const CheckerProgramPointTag *&tag = DeadSymbolTags[sym];
1324  if (!tag) {
1325  SmallString<64> buf;
1326  llvm::raw_svector_ostream out(buf);
1327  out << "Dead Symbol : ";
1328  sym->dumpToStream(out);
1329  tag = new CheckerProgramPointTag(this, out.str());
1330  }
1331  return tag;
1332 }
1333 
1335  CheckerContext &C) const {
1336  ExplodedNode *Pred = C.getPredecessor();
1337 
1339  RefBindingsTy B = state->get<RefBindings>();
1341 
1342  // Update counts from autorelease pools
1343  for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
1344  E = SymReaper.dead_end(); I != E; ++I) {
1345  SymbolRef Sym = *I;
1346  if (const RefVal *T = B.lookup(Sym)){
1347  // Use the symbol as the tag.
1348  // FIXME: This might not be as unique as we would like.
1349  const ProgramPointTag *Tag = getDeadSymbolTag(Sym);
1350  state = handleAutoreleaseCounts(state, Pred, Tag, C, Sym, *T);
1351  if (!state)
1352  return;
1353 
1354  // Fetch the new reference count from the state, and use it to handle
1355  // this symbol.
1356  state = handleSymbolDeath(state, *I, *getRefBinding(state, Sym), Leaked);
1357  }
1358  }
1359 
1360  if (Leaked.empty()) {
1361  C.addTransition(state);
1362  return;
1363  }
1364 
1365  Pred = processLeaks(state, Leaked, C, Pred);
1366 
1367  // Did we cache out?
1368  if (!Pred)
1369  return;
1370 
1371  // Now generate a new node that nukes the old bindings.
1372  // The only bindings left at this point are the leaked symbols.
1373  RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1374  B = state->get<RefBindings>();
1375 
1376  for (SmallVectorImpl<SymbolRef>::iterator I = Leaked.begin(),
1377  E = Leaked.end();
1378  I != E; ++I)
1379  B = F.remove(B, *I);
1380 
1381  state = state->set<RefBindings>(B);
1382  C.addTransition(state, Pred);
1383 }
1384 
1386  const char *NL, const char *Sep) const {
1387 
1388  RefBindingsTy B = State->get<RefBindings>();
1389 
1390  if (B.isEmpty())
1391  return;
1392 
1393  Out << Sep << NL;
1394 
1395  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1396  Out << I->first << " : ";
1397  I->second.print(Out);
1398  Out << NL;
1399  }
1400 }
1401 
1402 //===----------------------------------------------------------------------===//
1403 // Checker registration.
1404 //===----------------------------------------------------------------------===//
1405 
1406 void ento::registerRetainCountChecker(CheckerManager &Mgr) {
1408 }
const RetainSummary * getFunctionSummary(const FunctionDecl *FD)
const BlockDecl * getBlockDecl() const
Definition: Expr.h:4988
Represents a function declaration or definition.
Definition: Decl.h:1717
A (possibly-)qualified type.
Definition: Type.h:642
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:2354
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
Definition: Decl.h:3946
ProgramStateRef handleSymbolDeath(ProgramStateRef state, SymbolRef sid, RefVal V, SmallVectorImpl< SymbolRef > &Leaked) const
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +0 v...
ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym, RefVal Val)
bool evalCall(const CallExpr *CE, CheckerContext &C) const
Stmt - This represents one statement.
Definition: Stmt.h:66
The argument is treated as potentially escaping, meaning that even when its reference count hits 0 it...
Bridging via __bridge, which does nothing but reinterpret the bits.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
There is no effect.
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
const ProgramStateRef & getState() const
Indicates that no retain count information is tracked for the return value.
ArgEffect getArg(unsigned idx) const
getArg - Return the argument effect on the argument specified by idx (starting from 0)...
const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Definition: CallEvent.h:266
The argument has its reference count decreased by 1.
static RetEffect MakeNoRet()
Represents a variable declaration or definition.
Definition: Decl.h:812
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
Definition: SVals.cpp:85
bool canEval(const CallExpr *CE, const FunctionDecl *FD, bool &hasTrustedImplementationAnnotation)
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6590
const FunctionDecl * getCalleeDecl(const CallExpr *CE) const
Get the declaration of the called function (path-sensitive).
const Decl & getCodeDecl() const
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
virtual const MemRegion * getOriginRegion() const
Find the region from which this symbol originates.
Definition: SymExpr.h:102
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
Represents a parameter to a function.
Definition: Decl.h:1536
const bool wasInlined
If we are post visiting a call, this flag will be set if the call was inlined.
Performs the combined functionality of DecRefMsg and StopTrackingHard.
Symbolic value.
Definition: SymExpr.h:30
const MemRegion * getSuperRegion() const
Definition: MemRegion.h:443
ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym)
Convenience method to query the state to see if a symbol is null or not null, or if neither assumptio...
MemRegionManager & getRegionManager()
Definition: SValBuilder.h:175
All typestate tracking of the object ceases.
llvm::ImmutableMap< unsigned, ArgEffect > ArgEffects
ArgEffects summarizes the effects of a function/method call on all of its arguments.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
LineState State
static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t)
Create a state for an object whose lifetime is not the responsibility of the current function...
const Expr * getRetValue() const
Definition: Stmt.cpp:937
void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange, RefVal::Kind ErrorKind, SymbolRef Sym, CheckerContext &C) const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
Definition: ExprObjC.h:171
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
Summary for a function with respect to ownership changes.
The argument is treated as if an -autorelease message had been sent to the referenced object...
void checkPostCall(const CallEvent &Call, CheckerContext &C) const
virtual void dumpToStream(raw_ostream &os) const
Definition: SymExpr.h:61
Indicates that the return value is an owned object when the receiver is also a tracked object...
child_range children()
Definition: Stmt.cpp:229
const LocationContext * getLocationContext() const
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
const LocationContext * getParent() const
bool isUnknown() const
Definition: SVals.h:137
SVal getReturnValue() const
Returns the return value of the call.
Definition: CallEvent.cpp:412
const RetainSummary * getSummary(const CallEvent &Call, QualType ReceiverType=QualType())
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:2790
Represents an ObjC class declaration.
Definition: DeclObjC.h:1164
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC...
Indicates that the tracked object is an Objective-C object.
virtual QualType getType() const =0
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
Definition: SVals.cpp:127
bool hasAttr() const
Definition: DeclBase.h:536
bool isConstrainedTrue() const
Return true if the constraint is perfectly constrained to &#39;true&#39;.
void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const
bool isSynthesizedAccessor(const StackFrameContext *SFC)
Returns true if this stack frame is for an Objective-C method that is a property getter or setter who...
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
IvarAccessHistory getIvarAccessHistory() const
Returns what the analyzer knows about direct accesses to a particular instance variable.
const RegionTy * getAs() const
Definition: MemRegion.h:1226
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:759
The argument has its reference count increased by 1.
void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const
This represents one expression.
Definition: Expr.h:105
RetEffect getRetEffect() const
getRetEffect - Returns the effect on the return value of the call.
bool isObjCRetainableType() const
Definition: Type.cpp:3879
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:4974
static RefVal makeOwned(RetEffect::ObjKind o, QualType t)
Create a state for an object whose lifetime is the responsibility of the current function, at least partially.
#define bool
Definition: stdbool.h:31
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:288
void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const override
See CheckerManager::runCheckersForPrintState.
const RetainSummary * getMethodSummary(Selector S, const ObjCInterfaceDecl *ID, const ObjCMethodDecl *MD, QualType RetTy, ObjCMethodSummariesTy &CachedSummaries)
ProgramStateRef handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred, const ProgramPointTag *Tag, CheckerContext &Ctx, SymbolRef Sym, RefVal V) const
QualType getType() const
Definition: Expr.h:127
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:1444
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:904
void processObjCLiterals(CheckerContext &C, const Expr *Ex) const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
bool isBodyAutosynthesized() const
Checks if the body of the Decl is generated by the BodyFarm.
The argument is treated as if an -dealloc message had been sent to the referenced object...
ObjKind
Determines the object kind of a tracked object.
ArgEffect
An ArgEffect summarizes the retain count behavior on an argument or receiver to a function or method...
ObjCBridgeCastKind getBridgeKind() const
Determine which kind of bridge is being performed via this cast.
Definition: ExprObjC.h:1607
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:707
ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym, RefVal V, ArgEffect E, RefVal::Kind &hasErr, CheckerContext &C) const
void checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, ExplodedNode *Pred, RetEffect RE, RefVal X, SymbolRef Sym, ProgramStateRef state) const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:112
const VarDecl * getDecl() const
Definition: MemRegion.h:948
Indicates that the tracked object is a CF object.
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
static bool isISLObjectRef(QualType Ty)
Kind
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique &#39;name&#39;.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a sink node.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
Definition: ProgramPoint.h:40
const MemRegion * getAsRegion() const
Definition: SVals.cpp:151
ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, bool Assumption) const
static ProgramStateRef updateOutParameter(ProgramStateRef State, SVal ArgVal, ArgEffect Effect)
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2254
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:76
ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym)
A class responsible for cleaning up unused symbols.
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
ObjCBoxedExpr - used for generalized expression boxing.
Definition: ExprObjC.h:117
The argument has its reference count decreased by 1.
unsigned blockCount() const
Returns the number of times the current block has been visited along the analyzed path...
SymbolSetTy::const_iterator dead_iterator
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers...
Definition: ExprObjC.h:1575
Dataflow Directional Tag Classes.
virtual SourceRange getArgSourceRange(unsigned Index) const
Returns the source range for errors associated with this argument.
Definition: CallEvent.cpp:405
const VarRegion * getVarRegion(const VarDecl *D, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
Definition: MemRegion.cpp:846
static Optional< RefVal > refValFromRetEffect(RetEffect RE, QualType ResultTy)
ProgramStateRef checkRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call) const
ExplodedNode * processLeaks(ProgramStateRef state, SmallVectorImpl< SymbolRef > &Leaked, CheckerContext &Ctx, ExplodedNode *Pred=nullptr) const
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:975
const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1186
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition: Expr.cpp:1342
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:182
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
AnalyzerOptions & getAnalyzerOptions()
const Decl * getDecl() const
dead_iterator dead_begin() const
Represents a pointer to an Objective C object.
Definition: Type.h:5675
const StackFrameContext * getStackFrame() const
const ProgramPointTag * getDeadSymbolTag(SymbolRef sym) const
const ProgramStateRef & getState() const
void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const
const RefVal * getRefBinding(ProgramStateRef State, SymbolRef Sym)
bool isTrustedReferenceCountImplementation(const FunctionDecl *FD)
All typestate tracking of the object ceases.
dead_iterator dead_end() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:513
QualType getResultType() const
Returns the result type, adjusted for references.
Definition: CallEvent.cpp:70
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:13824
Performs the combined functionality of DecRef and StopTrackingHard.
The argument acts as if has been passed to CFMakeCollectable, which transfers the object to the Garba...
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
The argument has its reference count increased by 1.
void checkSummary(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const
void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const
SValBuilder & getSValBuilder()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2285
ArgEffect getReceiverEffect() const
getReceiverEffect - Returns the effect on the receiver of the call.
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:930
The argument has its reference count decreased by 1 to model a transferred bridge cast under ARC...
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
Definition: CallEvent.cpp:398
QualType getType() const
Definition: Decl.h:647
void processSummaryOfInlined(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const
A trivial tuple used to represent a source range.
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
Definition: Checker.h:509
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool inTopFrame() const
Return true if the current LocationContext has no caller context.
AnalysisDeclContext * getAnalysisDeclContext() const
const LocationContext * getLocationContext() const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3019
const LangOptions & getLangOpts() const
Definition: ASTContext.h:716
static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx)
GetReturnType - Used to get the return type of a message expression or function call with the intenti...
RetEffect summarizes a call&#39;s retain/release behavior with respect to its return value.