blob: 424cabc6d82c57b42f846aa0723c037c6a6f49e0 [file] [log] [blame]
George Karpenkov70c2ee32018-08-17 21:41:07 +00001//==-- 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
17using namespace clang;
18using namespace ento;
George Karpenkov70c2ee32018-08-17 21:41:07 +000019using 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 State, SymbolRef Sym) {
29 return State->get<RefBindings>(Sym);
30}
31
32ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
33 RefVal Val) {
George Karpenkovd5ef0d22018-08-29 20:28:33 +000034 assert(Sym != nullptr);
George Karpenkov70c2ee32018-08-17 21:41:07 +000035 return State->set<RefBindings>(Sym, Val);
36}
37
38ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
39 return State->remove<RefBindings>(Sym);
40}
41
George Karpenkov62db8862018-11-30 02:18:23 +000042class UseAfterRelease : public CFRefBug {
43public:
44 UseAfterRelease(const CheckerBase *checker)
45 : CFRefBug(checker, "Use-after-release") {}
46
47 const char *getDescription() const override {
48 return "Reference-counted object is used after it is released";
49 }
50};
51
52class BadRelease : public CFRefBug {
53public:
54 BadRelease(const CheckerBase *checker) : CFRefBug(checker, "Bad release") {}
55
56 const char *getDescription() const override {
57 return "Incorrect decrement of the reference count of an object that is "
58 "not owned at this point by the caller";
59 }
60};
61
62class DeallocNotOwned : public CFRefBug {
63public:
64 DeallocNotOwned(const CheckerBase *checker)
65 : CFRefBug(checker, "-dealloc sent to non-exclusively owned object") {}
66
67 const char *getDescription() const override {
68 return "-dealloc sent to object that may be referenced elsewhere";
69 }
70};
71
72class OverAutorelease : public CFRefBug {
73public:
74 OverAutorelease(const CheckerBase *checker)
75 : CFRefBug(checker, "Object autoreleased too many times") {}
76
77 const char *getDescription() const override {
78 return "Object autoreleased too many times";
79 }
80};
81
82class ReturnedNotOwnedForOwned : public CFRefBug {
83public:
84 ReturnedNotOwnedForOwned(const CheckerBase *checker)
85 : CFRefBug(checker, "Method should return an owned object") {}
86
87 const char *getDescription() const override {
88 return "Object with a +0 retain count returned to caller where a +1 "
89 "(owning) retain count is expected";
90 }
91};
92
93class Leak : public CFRefBug {
94public:
95 Leak(const CheckerBase *checker, StringRef name) : CFRefBug(checker, name) {
96 // Leaks should not be reported if they are post-dominated by a sink.
97 setSuppressOnSink(true);
98 }
99
100 const char *getDescription() const override { return ""; }
101
102 bool isLeak() const override { return true; }
103};
104
George Karpenkov70c2ee32018-08-17 21:41:07 +0000105} // end namespace retaincountchecker
106} // end namespace ento
107} // end namespace clang
108
109void RefVal::print(raw_ostream &Out) const {
110 if (!T.isNull())
George Karpenkov081c4772018-10-23 23:11:50 +0000111 Out << "Tracked " << T.getAsString() << " | ";
George Karpenkov70c2ee32018-08-17 21:41:07 +0000112
113 switch (getKind()) {
114 default: llvm_unreachable("Invalid RefVal kind");
115 case Owned: {
116 Out << "Owned";
117 unsigned cnt = getCount();
118 if (cnt) Out << " (+ " << cnt << ")";
119 break;
120 }
121
122 case NotOwned: {
123 Out << "NotOwned";
124 unsigned cnt = getCount();
125 if (cnt) Out << " (+ " << cnt << ")";
126 break;
127 }
128
129 case ReturnedOwned: {
130 Out << "ReturnedOwned";
131 unsigned cnt = getCount();
132 if (cnt) Out << " (+ " << cnt << ")";
133 break;
134 }
135
136 case ReturnedNotOwned: {
137 Out << "ReturnedNotOwned";
138 unsigned cnt = getCount();
139 if (cnt) Out << " (+ " << cnt << ")";
140 break;
141 }
142
143 case Released:
144 Out << "Released";
145 break;
146
147 case ErrorDeallocNotOwned:
148 Out << "-dealloc (not-owned)";
149 break;
150
151 case ErrorLeak:
152 Out << "Leaked";
153 break;
154
155 case ErrorLeakReturned:
156 Out << "Leaked (Bad naming)";
157 break;
158
159 case ErrorUseAfterRelease:
160 Out << "Use-After-Release [ERROR]";
161 break;
162
163 case ErrorReleaseNotOwned:
164 Out << "Release of Not-Owned [ERROR]";
165 break;
166
167 case RefVal::ErrorOverAutorelease:
168 Out << "Over-autoreleased";
169 break;
170
171 case RefVal::ErrorReturnedNotOwned:
172 Out << "Non-owned object returned instead of owned";
173 break;
174 }
175
176 switch (getIvarAccessHistory()) {
177 case IvarAccessHistory::None:
178 break;
179 case IvarAccessHistory::AccessedDirectly:
180 Out << " [direct ivar access]";
181 break;
182 case IvarAccessHistory::ReleasedAfterDirectAccess:
183 Out << " [released after direct ivar access]";
184 }
185
186 if (ACnt) {
187 Out << " [autorelease -" << ACnt << ']';
188 }
189}
190
191namespace {
192class StopTrackingCallback final : public SymbolVisitor {
193 ProgramStateRef state;
194public:
195 StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
196 ProgramStateRef getState() const { return state; }
197
198 bool VisitSymbol(SymbolRef sym) override {
199 state = state->remove<RefBindings>(sym);
200 return true;
201 }
202};
203} // end anonymous namespace
204
205//===----------------------------------------------------------------------===//
206// Handle statements that may have an effect on refcounts.
207//===----------------------------------------------------------------------===//
208
209void RetainCountChecker::checkPostStmt(const BlockExpr *BE,
210 CheckerContext &C) const {
211
212 // Scan the BlockDecRefExprs for any object the retain count checker
213 // may be tracking.
214 if (!BE->getBlockDecl()->hasCaptures())
215 return;
216
217 ProgramStateRef state = C.getState();
218 auto *R = cast<BlockDataRegion>(C.getSVal(BE).getAsRegion());
219
220 BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
221 E = R->referenced_vars_end();
222
223 if (I == E)
224 return;
225
226 // FIXME: For now we invalidate the tracking of all symbols passed to blocks
227 // via captured variables, even though captured variables result in a copy
228 // and in implicit increment/decrement of a retain count.
229 SmallVector<const MemRegion*, 10> Regions;
230 const LocationContext *LC = C.getLocationContext();
231 MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
232
233 for ( ; I != E; ++I) {
234 const VarRegion *VR = I.getCapturedRegion();
235 if (VR->getSuperRegion() == R) {
236 VR = MemMgr.getVarRegion(VR->getDecl(), LC);
237 }
238 Regions.push_back(VR);
239 }
240
George Karpenkovd3e76752018-10-23 23:12:12 +0000241 state = state->scanReachableSymbols<StopTrackingCallback>(Regions).getState();
George Karpenkov70c2ee32018-08-17 21:41:07 +0000242 C.addTransition(state);
243}
244
245void RetainCountChecker::checkPostStmt(const CastExpr *CE,
246 CheckerContext &C) const {
247 const ObjCBridgedCastExpr *BE = dyn_cast<ObjCBridgedCastExpr>(CE);
248 if (!BE)
249 return;
250
251 ArgEffect AE = IncRef;
252
253 switch (BE->getBridgeKind()) {
254 case OBC_Bridge:
255 // Do nothing.
256 return;
257 case OBC_BridgeRetained:
258 AE = IncRef;
259 break;
260 case OBC_BridgeTransfer:
261 AE = DecRefBridgedTransferred;
262 break;
263 }
264
265 ProgramStateRef state = C.getState();
266 SymbolRef Sym = C.getSVal(CE).getAsLocSymbol();
267 if (!Sym)
268 return;
269 const RefVal* T = getRefBinding(state, Sym);
270 if (!T)
271 return;
272
273 RefVal::Kind hasErr = (RefVal::Kind) 0;
274 state = updateSymbol(state, Sym, *T, AE, hasErr, C);
275
276 if (hasErr) {
277 // FIXME: If we get an error during a bridge cast, should we report it?
278 return;
279 }
280
281 C.addTransition(state);
282}
283
284void RetainCountChecker::processObjCLiterals(CheckerContext &C,
285 const Expr *Ex) const {
286 ProgramStateRef state = C.getState();
287 const ExplodedNode *pred = C.getPredecessor();
288 for (const Stmt *Child : Ex->children()) {
289 SVal V = pred->getSVal(Child);
290 if (SymbolRef sym = V.getAsSymbol())
291 if (const RefVal* T = getRefBinding(state, sym)) {
292 RefVal::Kind hasErr = (RefVal::Kind) 0;
293 state = updateSymbol(state, sym, *T, MayEscape, hasErr, C);
294 if (hasErr) {
295 processNonLeakError(state, Child->getSourceRange(), hasErr, sym, C);
296 return;
297 }
298 }
299 }
300
301 // Return the object as autoreleased.
302 // RetEffect RE = RetEffect::MakeNotOwned(RetEffect::ObjC);
303 if (SymbolRef sym =
304 state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
305 QualType ResultTy = Ex->getType();
306 state = setRefBinding(state, sym,
307 RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
308 }
309
310 C.addTransition(state);
311}
312
313void RetainCountChecker::checkPostStmt(const ObjCArrayLiteral *AL,
314 CheckerContext &C) const {
315 // Apply the 'MayEscape' to all values.
316 processObjCLiterals(C, AL);
317}
318
319void RetainCountChecker::checkPostStmt(const ObjCDictionaryLiteral *DL,
320 CheckerContext &C) const {
321 // Apply the 'MayEscape' to all keys and values.
322 processObjCLiterals(C, DL);
323}
324
325void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
326 CheckerContext &C) const {
327 const ExplodedNode *Pred = C.getPredecessor();
328 ProgramStateRef State = Pred->getState();
329
330 if (SymbolRef Sym = Pred->getSVal(Ex).getAsSymbol()) {
331 QualType ResultTy = Ex->getType();
332 State = setRefBinding(State, Sym,
333 RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
334 }
335
336 C.addTransition(State);
337}
338
339void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
340 CheckerContext &C) const {
341 Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>();
342 if (!IVarLoc)
343 return;
344
345 ProgramStateRef State = C.getState();
346 SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
347 if (!Sym || !dyn_cast_or_null<ObjCIvarRegion>(Sym->getOriginRegion()))
348 return;
349
350 // Accessing an ivar directly is unusual. If we've done that, be more
351 // forgiving about what the surrounding code is allowed to do.
352
353 QualType Ty = Sym->getType();
354 RetEffect::ObjKind Kind;
355 if (Ty->isObjCRetainableType())
356 Kind = RetEffect::ObjC;
357 else if (coreFoundation::isCFObjectRef(Ty))
358 Kind = RetEffect::CF;
359 else
360 return;
361
362 // If the value is already known to be nil, don't bother tracking it.
363 ConstraintManager &CMgr = State->getConstraintManager();
364 if (CMgr.isNull(State, Sym).isConstrainedTrue())
365 return;
366
367 if (const RefVal *RV = getRefBinding(State, Sym)) {
368 // If we've seen this symbol before, or we're only seeing it now because
369 // of something the analyzer has synthesized, don't do anything.
370 if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None ||
371 isSynthesizedAccessor(C.getStackFrame())) {
372 return;
373 }
374
375 // Note that this value has been loaded from an ivar.
376 C.addTransition(setRefBinding(State, Sym, RV->withIvarAccess()));
377 return;
378 }
379
380 RefVal PlusZero = RefVal::makeNotOwned(Kind, Ty);
381
382 // In a synthesized accessor, the effective retain count is +0.
383 if (isSynthesizedAccessor(C.getStackFrame())) {
384 C.addTransition(setRefBinding(State, Sym, PlusZero));
385 return;
386 }
387
388 State = setRefBinding(State, Sym, PlusZero.withIvarAccess());
389 C.addTransition(State);
390}
391
392void RetainCountChecker::checkPostCall(const CallEvent &Call,
393 CheckerContext &C) const {
394 RetainSummaryManager &Summaries = getSummaryManager(C);
George Karpenkovefef49c2018-08-21 03:09:02 +0000395
396 // Leave null if no receiver.
397 QualType ReceiverType;
398 if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
399 if (MC->isInstanceMessage()) {
400 SVal ReceiverV = MC->getReceiverSVal();
401 if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
402 if (const RefVal *T = getRefBinding(C.getState(), Sym))
403 ReceiverType = T->getType();
404 }
405 }
406
407 const RetainSummary *Summ = Summaries.getSummary(Call, ReceiverType);
George Karpenkov70c2ee32018-08-17 21:41:07 +0000408
409 if (C.wasInlined) {
410 processSummaryOfInlined(*Summ, Call, C);
411 return;
412 }
413 checkSummary(*Summ, Call, C);
414}
415
George Karpenkov62db8862018-11-30 02:18:23 +0000416void RetainCountChecker::checkEndAnalysis(ExplodedGraph &G, BugReporter &BR,
417 ExprEngine &Eng) const {
418 // FIXME: This is a hack to make sure the summary log gets cleared between
419 // analyses of different code bodies.
420 //
421 // Why is this necessary? Because a checker's lifetime is tied to a
422 // translation unit, but an ExplodedGraph's lifetime is just a code body.
423 // Once in a blue moon, a new ExplodedNode will have the same address as an
424 // old one with an associated summary, and the bug report visitor gets very
425 // confused. (To make things worse, the summary lifetime is currently also
426 // tied to a code body, so we get a crash instead of incorrect results.)
427 //
428 // Why is this a bad solution? Because if the lifetime of the ExplodedGraph
429 // changes, things will start going wrong again. Really the lifetime of this
430 // log needs to be tied to either the specific nodes in it or the entire
431 // ExplodedGraph, not to a specific part of the code being analyzed.
432 //
433 // (Also, having stateful local data means that the same checker can't be
434 // used from multiple threads, but a lot of checkers have incorrect
435 // assumptions about that anyway. So that wasn't a priority at the time of
436 // this fix.)
437 //
438 // This happens at the end of analysis, but bug reports are emitted /after/
439 // this point. So we can't just clear the summary log now. Instead, we mark
440 // that the next time we access the summary log, it should be cleared.
441
442 // If we never reset the summary log during /this/ code body analysis,
443 // there were no new summaries. There might still have been summaries from
444 // the /last/ analysis, so clear them out to make sure the bug report
445 // visitors don't get confused.
446 if (ShouldResetSummaryLog)
447 SummaryLog.clear();
448
449 ShouldResetSummaryLog = !SummaryLog.empty();
450}
451
452CFRefBug *
453RetainCountChecker::getLeakWithinFunctionBug(const LangOptions &LOpts) const {
454 if (!leakWithinFunction)
455 leakWithinFunction.reset(new Leak(this, "Leak"));
456 return leakWithinFunction.get();
457}
458
459CFRefBug *
460RetainCountChecker::getLeakAtReturnBug(const LangOptions &LOpts) const {
461 if (!leakAtReturn)
462 leakAtReturn.reset(new Leak(this, "Leak of returned object"));
463 return leakAtReturn.get();
464}
465
George Karpenkov70c2ee32018-08-17 21:41:07 +0000466/// GetReturnType - Used to get the return type of a message expression or
467/// function call with the intention of affixing that type to a tracked symbol.
468/// While the return type can be queried directly from RetEx, when
469/// invoking class methods we augment to the return type to be that of
470/// a pointer to the class (as opposed it just being id).
471// FIXME: We may be able to do this with related result types instead.
472// This function is probably overestimating.
473static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) {
474 QualType RetTy = RetE->getType();
475 // If RetE is not a message expression just return its type.
476 // If RetE is a message expression, return its types if it is something
477 /// more specific than id.
478 if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
479 if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>())
480 if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
481 PT->isObjCClassType()) {
482 // At this point we know the return type of the message expression is
483 // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
484 // is a call to a class method whose type we can resolve. In such
485 // cases, promote the return type to XXX* (where XXX is the class).
486 const ObjCInterfaceDecl *D = ME->getReceiverInterface();
487 return !D ? RetTy :
488 Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D));
489 }
490
491 return RetTy;
492}
493
George Karpenkov80c9e782018-08-22 01:16:49 +0000494static Optional<RefVal> refValFromRetEffect(RetEffect RE,
495 QualType ResultTy) {
496 if (RE.isOwned()) {
497 return RefVal::makeOwned(RE.getObjKind(), ResultTy);
498 } else if (RE.notOwned()) {
499 return RefVal::makeNotOwned(RE.getObjKind(), ResultTy);
500 }
501
502 return None;
503}
504
George Karpenkov70c2ee32018-08-17 21:41:07 +0000505// We don't always get the exact modeling of the function with regards to the
506// retain count checker even when the function is inlined. For example, we need
507// to stop tracking the symbols which were marked with StopTrackingHard.
508void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
509 const CallEvent &CallOrMsg,
510 CheckerContext &C) const {
511 ProgramStateRef state = C.getState();
512
513 // Evaluate the effect of the arguments.
514 for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
515 if (Summ.getArg(idx) == StopTrackingHard) {
516 SVal V = CallOrMsg.getArgSVal(idx);
517 if (SymbolRef Sym = V.getAsLocSymbol()) {
518 state = removeRefBinding(state, Sym);
519 }
520 }
521 }
522
523 // Evaluate the effect on the message receiver.
George Karpenkov6e9fd132018-08-22 01:17:09 +0000524 if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
George Karpenkov70c2ee32018-08-17 21:41:07 +0000525 if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
526 if (Summ.getReceiverEffect() == StopTrackingHard) {
527 state = removeRefBinding(state, Sym);
528 }
529 }
530 }
531
532 // Consult the summary for the return value.
533 RetEffect RE = Summ.getRetEffect();
George Karpenkov70c2ee32018-08-17 21:41:07 +0000534
George Karpenkovd5ef0d22018-08-29 20:28:33 +0000535 if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
George Karpenkovd5ef0d22018-08-29 20:28:33 +0000536 if (RE.getKind() == RetEffect::NoRetHard)
537 state = removeRefBinding(state, Sym);
538 }
George Karpenkovab0011e2018-08-23 00:26:59 +0000539
George Karpenkov70c2ee32018-08-17 21:41:07 +0000540 C.addTransition(state);
541}
542
543static ProgramStateRef updateOutParameter(ProgramStateRef State,
544 SVal ArgVal,
545 ArgEffect Effect) {
546 auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.getAsRegion());
547 if (!ArgRegion)
548 return State;
549
550 QualType PointeeTy = ArgRegion->getValueType();
551 if (!coreFoundation::isCFObjectRef(PointeeTy))
552 return State;
553
554 SVal PointeeVal = State->getSVal(ArgRegion);
555 SymbolRef Pointee = PointeeVal.getAsLocSymbol();
556 if (!Pointee)
557 return State;
558
559 switch (Effect) {
560 case UnretainedOutParameter:
561 State = setRefBinding(State, Pointee,
562 RefVal::makeNotOwned(RetEffect::CF, PointeeTy));
563 break;
564 case RetainedOutParameter:
565 // Do nothing. Retained out parameters will either point to a +1 reference
566 // or NULL, but the way you check for failure differs depending on the API.
567 // Consequently, we don't have a good way to track them yet.
568 break;
569
570 default:
571 llvm_unreachable("only for out parameters");
572 }
573
574 return State;
575}
576
577void RetainCountChecker::checkSummary(const RetainSummary &Summ,
578 const CallEvent &CallOrMsg,
579 CheckerContext &C) const {
580 ProgramStateRef state = C.getState();
581
582 // Evaluate the effect of the arguments.
583 RefVal::Kind hasErr = (RefVal::Kind) 0;
584 SourceRange ErrorRange;
585 SymbolRef ErrorSym = nullptr;
586
587 for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
588 SVal V = CallOrMsg.getArgSVal(idx);
589
590 ArgEffect Effect = Summ.getArg(idx);
591 if (Effect == RetainedOutParameter || Effect == UnretainedOutParameter) {
592 state = updateOutParameter(state, V, Effect);
593 } else if (SymbolRef Sym = V.getAsLocSymbol()) {
594 if (const RefVal *T = getRefBinding(state, Sym)) {
595 state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
596 if (hasErr) {
597 ErrorRange = CallOrMsg.getArgSourceRange(idx);
598 ErrorSym = Sym;
599 break;
600 }
601 }
602 }
603 }
604
George Karpenkovab0011e2018-08-23 00:26:59 +0000605 // Evaluate the effect on the message receiver / `this` argument.
George Karpenkov70c2ee32018-08-17 21:41:07 +0000606 bool ReceiverIsTracked = false;
607 if (!hasErr) {
George Karpenkovab0011e2018-08-23 00:26:59 +0000608 if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
George Karpenkov70c2ee32018-08-17 21:41:07 +0000609 if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
610 if (const RefVal *T = getRefBinding(state, Sym)) {
611 ReceiverIsTracked = true;
612 state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
613 hasErr, C);
614 if (hasErr) {
615 ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
616 ErrorSym = Sym;
617 }
618 }
619 }
George Karpenkovab0011e2018-08-23 00:26:59 +0000620 } else if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
621 if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
622 if (const RefVal *T = getRefBinding(state, Sym)) {
623 state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
624 hasErr, C);
625 if (hasErr) {
626 ErrorRange = MCall->getOriginExpr()->getSourceRange();
627 ErrorSym = Sym;
628 }
629 }
630 }
George Karpenkov70c2ee32018-08-17 21:41:07 +0000631 }
632 }
633
634 // Process any errors.
635 if (hasErr) {
636 processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C);
637 return;
638 }
639
640 // Consult the summary for the return value.
641 RetEffect RE = Summ.getRetEffect();
642
643 if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
644 if (ReceiverIsTracked)
645 RE = getSummaryManager(C).getObjAllocRetEffect();
646 else
647 RE = RetEffect::MakeNoRet();
648 }
649
George Karpenkov80c9e782018-08-22 01:16:49 +0000650 if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
651 QualType ResultTy = CallOrMsg.getResultType();
652 if (RE.notOwned()) {
George Karpenkov70c2ee32018-08-17 21:41:07 +0000653 const Expr *Ex = CallOrMsg.getOriginExpr();
George Karpenkov70c2ee32018-08-17 21:41:07 +0000654 assert(Ex);
George Karpenkov80c9e782018-08-22 01:16:49 +0000655 ResultTy = GetReturnType(Ex, C.getASTContext());
George Karpenkov70c2ee32018-08-17 21:41:07 +0000656 }
George Karpenkov80c9e782018-08-22 01:16:49 +0000657 if (Optional<RefVal> updatedRefVal = refValFromRetEffect(RE, ResultTy))
658 state = setRefBinding(state, Sym, *updatedRefVal);
George Karpenkov70c2ee32018-08-17 21:41:07 +0000659 }
660
661 // This check is actually necessary; otherwise the statement builder thinks
662 // we've hit a previously-found path.
663 // Normally addTransition takes care of this, but we want the node pointer.
664 ExplodedNode *NewNode;
665 if (state == C.getState()) {
666 NewNode = C.getPredecessor();
667 } else {
668 NewNode = C.addTransition(state);
669 }
670
671 // Annotate the node with summary we used.
672 if (NewNode) {
673 // FIXME: This is ugly. See checkEndAnalysis for why it's necessary.
674 if (ShouldResetSummaryLog) {
675 SummaryLog.clear();
676 ShouldResetSummaryLog = false;
677 }
678 SummaryLog[NewNode] = &Summ;
679 }
680}
681
682ProgramStateRef
683RetainCountChecker::updateSymbol(ProgramStateRef state, SymbolRef sym,
684 RefVal V, ArgEffect E, RefVal::Kind &hasErr,
685 CheckerContext &C) const {
686 bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
687 switch (E) {
688 default:
689 break;
690 case IncRefMsg:
691 E = IgnoreRetainMsg ? DoNothing : IncRef;
692 break;
693 case DecRefMsg:
694 E = IgnoreRetainMsg ? DoNothing: DecRef;
695 break;
696 case DecRefMsgAndStopTrackingHard:
697 E = IgnoreRetainMsg ? StopTracking : DecRefAndStopTrackingHard;
698 break;
George Karpenkovbc0cddf2018-08-17 21:42:59 +0000699 case MakeCollectable:
700 E = DoNothing;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000701 }
702
703 // Handle all use-after-releases.
704 if (V.getKind() == RefVal::Released) {
705 V = V ^ RefVal::ErrorUseAfterRelease;
706 hasErr = V.getKind();
707 return setRefBinding(state, sym, V);
708 }
709
710 switch (E) {
711 case DecRefMsg:
712 case IncRefMsg:
George Karpenkovbc0cddf2018-08-17 21:42:59 +0000713 case MakeCollectable:
George Karpenkov70c2ee32018-08-17 21:41:07 +0000714 case DecRefMsgAndStopTrackingHard:
George Karpenkovbc0cddf2018-08-17 21:42:59 +0000715 llvm_unreachable("DecRefMsg/IncRefMsg/MakeCollectable already converted");
George Karpenkov70c2ee32018-08-17 21:41:07 +0000716
717 case UnretainedOutParameter:
718 case RetainedOutParameter:
719 llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
720 "not have ref state.");
721
722 case Dealloc:
723 switch (V.getKind()) {
724 default:
725 llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
726 case RefVal::Owned:
727 // The object immediately transitions to the released state.
728 V = V ^ RefVal::Released;
729 V.clearCounts();
730 return setRefBinding(state, sym, V);
731 case RefVal::NotOwned:
732 V = V ^ RefVal::ErrorDeallocNotOwned;
733 hasErr = V.getKind();
734 break;
735 }
736 break;
737
738 case MayEscape:
739 if (V.getKind() == RefVal::Owned) {
740 V = V ^ RefVal::NotOwned;
741 break;
742 }
743
Reid Kleckner4dc0b1a2018-11-01 19:54:45 +0000744 LLVM_FALLTHROUGH;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000745
746 case DoNothing:
747 return state;
748
749 case Autorelease:
750 // Update the autorelease counts.
751 V = V.autorelease();
752 break;
753
754 case StopTracking:
755 case StopTrackingHard:
756 return removeRefBinding(state, sym);
757
758 case IncRef:
759 switch (V.getKind()) {
760 default:
761 llvm_unreachable("Invalid RefVal state for a retain.");
762 case RefVal::Owned:
763 case RefVal::NotOwned:
764 V = V + 1;
765 break;
766 }
767 break;
768
769 case DecRef:
770 case DecRefBridgedTransferred:
771 case DecRefAndStopTrackingHard:
772 switch (V.getKind()) {
773 default:
774 // case 'RefVal::Released' handled above.
775 llvm_unreachable("Invalid RefVal state for a release.");
776
777 case RefVal::Owned:
778 assert(V.getCount() > 0);
779 if (V.getCount() == 1) {
780 if (E == DecRefBridgedTransferred ||
781 V.getIvarAccessHistory() ==
782 RefVal::IvarAccessHistory::AccessedDirectly)
783 V = V ^ RefVal::NotOwned;
784 else
785 V = V ^ RefVal::Released;
786 } else if (E == DecRefAndStopTrackingHard) {
787 return removeRefBinding(state, sym);
788 }
789
790 V = V - 1;
791 break;
792
793 case RefVal::NotOwned:
794 if (V.getCount() > 0) {
795 if (E == DecRefAndStopTrackingHard)
796 return removeRefBinding(state, sym);
797 V = V - 1;
798 } else if (V.getIvarAccessHistory() ==
799 RefVal::IvarAccessHistory::AccessedDirectly) {
800 // Assume that the instance variable was holding on the object at
801 // +1, and we just didn't know.
802 if (E == DecRefAndStopTrackingHard)
803 return removeRefBinding(state, sym);
804 V = V.releaseViaIvar() ^ RefVal::Released;
805 } else {
806 V = V ^ RefVal::ErrorReleaseNotOwned;
807 hasErr = V.getKind();
808 }
809 break;
810 }
811 break;
812 }
813 return setRefBinding(state, sym, V);
814}
815
816void RetainCountChecker::processNonLeakError(ProgramStateRef St,
817 SourceRange ErrorRange,
818 RefVal::Kind ErrorKind,
819 SymbolRef Sym,
820 CheckerContext &C) const {
821 // HACK: Ignore retain-count issues on values accessed through ivars,
822 // because of cases like this:
823 // [_contentView retain];
824 // [_contentView removeFromSuperview];
825 // [self addSubview:_contentView]; // invalidates 'self'
826 // [_contentView release];
827 if (const RefVal *RV = getRefBinding(St, Sym))
828 if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
829 return;
830
831 ExplodedNode *N = C.generateErrorNode(St);
832 if (!N)
833 return;
834
835 CFRefBug *BT;
836 switch (ErrorKind) {
837 default:
838 llvm_unreachable("Unhandled error.");
839 case RefVal::ErrorUseAfterRelease:
840 if (!useAfterRelease)
841 useAfterRelease.reset(new UseAfterRelease(this));
842 BT = useAfterRelease.get();
843 break;
844 case RefVal::ErrorReleaseNotOwned:
845 if (!releaseNotOwned)
846 releaseNotOwned.reset(new BadRelease(this));
847 BT = releaseNotOwned.get();
848 break;
849 case RefVal::ErrorDeallocNotOwned:
850 if (!deallocNotOwned)
851 deallocNotOwned.reset(new DeallocNotOwned(this));
852 BT = deallocNotOwned.get();
853 break;
854 }
855
856 assert(BT);
George Karpenkov6babf2a2018-09-21 20:36:21 +0000857 auto report = llvm::make_unique<CFRefReport>(
858 *BT, C.getASTContext().getLangOpts(), SummaryLog, N, Sym);
George Karpenkov70c2ee32018-08-17 21:41:07 +0000859 report->addRange(ErrorRange);
860 C.emitReport(std::move(report));
861}
862
863//===----------------------------------------------------------------------===//
864// Handle the return values of retain-count-related functions.
865//===----------------------------------------------------------------------===//
866
867bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
868 // Get the callee. We're only interested in simple C functions.
869 ProgramStateRef state = C.getState();
870 const FunctionDecl *FD = C.getCalleeDecl(CE);
871 if (!FD)
872 return false;
873
George Karpenkovc4d6b932018-08-17 21:42:05 +0000874 RetainSummaryManager &SmrMgr = getSummaryManager(C);
875 QualType ResultTy = CE->getCallReturnType(C.getASTContext());
George Karpenkov70c2ee32018-08-17 21:41:07 +0000876
George Karpenkov70c2ee32018-08-17 21:41:07 +0000877 // See if the function has 'rc_ownership_trusted_implementation'
878 // annotate attribute. If it does, we will not inline it.
879 bool hasTrustedImplementationAnnotation = false;
880
George Karpenkov41dc8de2018-10-11 22:59:16 +0000881 const LocationContext *LCtx = C.getLocationContext();
882
George Karpenkov3c2ed8f2018-10-25 23:38:07 +0000883 using BehaviorSummary = RetainSummaryManager::BehaviorSummary;
884 Optional<BehaviorSummary> BSmr =
885 SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation);
886
George Karpenkovc4d6b932018-08-17 21:42:05 +0000887 // See if it's one of the specific functions we know how to eval.
George Karpenkov3c2ed8f2018-10-25 23:38:07 +0000888 if (!BSmr)
George Karpenkov70c2ee32018-08-17 21:41:07 +0000889 return false;
890
891 // Bind the return value.
George Karpenkov3c2ed8f2018-10-25 23:38:07 +0000892 if (BSmr == BehaviorSummary::Identity ||
893 BSmr == BehaviorSummary::IdentityOrZero) {
George Karpenkov48de5822018-10-23 23:11:30 +0000894 SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
895
George Karpenkov70c2ee32018-08-17 21:41:07 +0000896 // If the receiver is unknown or the function has
897 // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
898 // return value.
George Karpenkov48de5822018-10-23 23:11:30 +0000899 if (RetVal.isUnknown() ||
900 (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
901 SValBuilder &SVB = C.getSValBuilder();
902 RetVal =
903 SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
904 }
George Karpenkov3c2ed8f2018-10-25 23:38:07 +0000905 state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
906
907 if (BSmr == BehaviorSummary::IdentityOrZero) {
908 // Add a branch where the output is zero.
909 ProgramStateRef NullOutputState = C.getState();
910
911 // Assume that output is zero on the other branch.
912 NullOutputState = NullOutputState->BindExpr(
913 CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false);
914
915 C.addTransition(NullOutputState);
916
917 // And on the original branch assume that both input and
918 // output are non-zero.
919 if (auto L = RetVal.getAs<DefinedOrUnknownSVal>())
920 state = state->assume(*L, /*Assumption=*/true);
921
922 }
George Karpenkov70c2ee32018-08-17 21:41:07 +0000923 }
George Karpenkov70c2ee32018-08-17 21:41:07 +0000924
George Karpenkov70c2ee32018-08-17 21:41:07 +0000925 C.addTransition(state);
926 return true;
927}
928
George Karpenkov04553e52018-09-21 20:37:20 +0000929ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
930 CheckerContext &C) const {
931 ExplodedNode *Pred = C.getPredecessor();
George Karpenkov70c2ee32018-08-17 21:41:07 +0000932
933 // Only adjust the reference count if this is the top-level call frame,
934 // and not the result of inlining. In the future, we should do
935 // better checking even for inlined calls, and see if they match
936 // with their expected semantics (e.g., the method should return a retained
937 // object, etc.).
938 if (!C.inTopFrame())
George Karpenkov04553e52018-09-21 20:37:20 +0000939 return Pred;
940
941 if (!S)
942 return Pred;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000943
944 const Expr *RetE = S->getRetValue();
945 if (!RetE)
George Karpenkov04553e52018-09-21 20:37:20 +0000946 return Pred;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000947
948 ProgramStateRef state = C.getState();
949 SymbolRef Sym =
950 state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
951 if (!Sym)
George Karpenkov04553e52018-09-21 20:37:20 +0000952 return Pred;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000953
954 // Get the reference count binding (if any).
955 const RefVal *T = getRefBinding(state, Sym);
956 if (!T)
George Karpenkov04553e52018-09-21 20:37:20 +0000957 return Pred;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000958
959 // Change the reference count.
960 RefVal X = *T;
961
962 switch (X.getKind()) {
963 case RefVal::Owned: {
964 unsigned cnt = X.getCount();
965 assert(cnt > 0);
966 X.setCount(cnt - 1);
967 X = X ^ RefVal::ReturnedOwned;
968 break;
969 }
970
971 case RefVal::NotOwned: {
972 unsigned cnt = X.getCount();
973 if (cnt) {
974 X.setCount(cnt - 1);
975 X = X ^ RefVal::ReturnedOwned;
George Karpenkov04553e52018-09-21 20:37:20 +0000976 } else {
George Karpenkov70c2ee32018-08-17 21:41:07 +0000977 X = X ^ RefVal::ReturnedNotOwned;
978 }
979 break;
980 }
981
982 default:
George Karpenkov04553e52018-09-21 20:37:20 +0000983 return Pred;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000984 }
985
986 // Update the binding.
987 state = setRefBinding(state, Sym, X);
George Karpenkov04553e52018-09-21 20:37:20 +0000988 Pred = C.addTransition(state);
George Karpenkov70c2ee32018-08-17 21:41:07 +0000989
990 // At this point we have updated the state properly.
991 // Everything after this is merely checking to see if the return value has
992 // been over- or under-retained.
993
994 // Did we cache out?
995 if (!Pred)
George Karpenkov04553e52018-09-21 20:37:20 +0000996 return nullptr;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000997
998 // Update the autorelease counts.
999 static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
George Karpenkov04553e52018-09-21 20:37:20 +00001000 state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X, S);
George Karpenkov70c2ee32018-08-17 21:41:07 +00001001
George Karpenkov04553e52018-09-21 20:37:20 +00001002 // Have we generated a sink node?
George Karpenkov70c2ee32018-08-17 21:41:07 +00001003 if (!state)
George Karpenkov04553e52018-09-21 20:37:20 +00001004 return nullptr;
George Karpenkov70c2ee32018-08-17 21:41:07 +00001005
1006 // Get the updated binding.
1007 T = getRefBinding(state, Sym);
1008 assert(T);
1009 X = *T;
1010
1011 // Consult the summary of the enclosing method.
1012 RetainSummaryManager &Summaries = getSummaryManager(C);
1013 const Decl *CD = &Pred->getCodeDecl();
1014 RetEffect RE = RetEffect::MakeNoRet();
1015
1016 // FIXME: What is the convention for blocks? Is there one?
1017 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
1018 const RetainSummary *Summ = Summaries.getMethodSummary(MD);
1019 RE = Summ->getRetEffect();
1020 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
1021 if (!isa<CXXMethodDecl>(FD)) {
1022 const RetainSummary *Summ = Summaries.getFunctionSummary(FD);
1023 RE = Summ->getRetEffect();
1024 }
1025 }
1026
George Karpenkov04553e52018-09-21 20:37:20 +00001027 return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
George Karpenkov70c2ee32018-08-17 21:41:07 +00001028}
1029
George Karpenkov04553e52018-09-21 20:37:20 +00001030ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
George Karpenkov70c2ee32018-08-17 21:41:07 +00001031 CheckerContext &C,
1032 ExplodedNode *Pred,
1033 RetEffect RE, RefVal X,
1034 SymbolRef Sym,
1035 ProgramStateRef state) const {
1036 // HACK: Ignore retain-count issues on values accessed through ivars,
1037 // because of cases like this:
1038 // [_contentView retain];
1039 // [_contentView removeFromSuperview];
1040 // [self addSubview:_contentView]; // invalidates 'self'
1041 // [_contentView release];
1042 if (X.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
George Karpenkov04553e52018-09-21 20:37:20 +00001043 return Pred;
George Karpenkov70c2ee32018-08-17 21:41:07 +00001044
1045 // Any leaks or other errors?
1046 if (X.isReturnedOwned() && X.getCount() == 0) {
1047 if (RE.getKind() != RetEffect::NoRet) {
George Karpenkov70c2ee32018-08-17 21:41:07 +00001048 if (!RE.isOwned()) {
George Karpenkov04553e52018-09-21 20:37:20 +00001049
George Karpenkov70c2ee32018-08-17 21:41:07 +00001050 // The returning type is a CF, we expect the enclosing method should
1051 // return ownership.
George Karpenkov70c2ee32018-08-17 21:41:07 +00001052 X = X ^ RefVal::ErrorLeakReturned;
George Karpenkov70c2ee32018-08-17 21:41:07 +00001053
George Karpenkov70c2ee32018-08-17 21:41:07 +00001054 // Generate an error node.
1055 state = setRefBinding(state, Sym, X);
1056
1057 static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
1058 ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
1059 if (N) {
1060 const LangOptions &LOpts = C.getASTContext().getLangOpts();
George Karpenkov04553e52018-09-21 20:37:20 +00001061 auto R = llvm::make_unique<CFRefLeakReport>(
George Karpenkov936a9c92018-12-07 20:21:37 +00001062 *getLeakAtReturnBug(LOpts), LOpts, SummaryLog, N, Sym, C);
George Karpenkov04553e52018-09-21 20:37:20 +00001063 C.emitReport(std::move(R));
George Karpenkov70c2ee32018-08-17 21:41:07 +00001064 }
George Karpenkov04553e52018-09-21 20:37:20 +00001065 return N;
George Karpenkov70c2ee32018-08-17 21:41:07 +00001066 }
1067 }
1068 } else if (X.isReturnedNotOwned()) {
1069 if (RE.isOwned()) {
1070 if (X.getIvarAccessHistory() ==
1071 RefVal::IvarAccessHistory::AccessedDirectly) {
1072 // Assume the method was trying to transfer a +1 reference from a
1073 // strong ivar to the caller.
1074 state = setRefBinding(state, Sym,
1075 X.releaseViaIvar() ^ RefVal::ReturnedOwned);
1076 } else {
1077 // Trying to return a not owned object to a caller expecting an
1078 // owned object.
1079 state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
1080
1081 static CheckerProgramPointTag
1082 ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
1083
1084 ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
1085 if (N) {
1086 if (!returnNotOwnedForOwned)
1087 returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
1088
George Karpenkov04553e52018-09-21 20:37:20 +00001089 auto R = llvm::make_unique<CFRefReport>(
George Karpenkov70c2ee32018-08-17 21:41:07 +00001090 *returnNotOwnedForOwned, C.getASTContext().getLangOpts(),
George Karpenkov04553e52018-09-21 20:37:20 +00001091 SummaryLog, N, Sym);
1092 C.emitReport(std::move(R));
George Karpenkov70c2ee32018-08-17 21:41:07 +00001093 }
George Karpenkov04553e52018-09-21 20:37:20 +00001094 return N;
George Karpenkov70c2ee32018-08-17 21:41:07 +00001095 }
1096 }
1097 }
George Karpenkov04553e52018-09-21 20:37:20 +00001098 return Pred;
George Karpenkov70c2ee32018-08-17 21:41:07 +00001099}
1100
1101//===----------------------------------------------------------------------===//
1102// Check various ways a symbol can be invalidated.
1103//===----------------------------------------------------------------------===//
1104
1105void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
1106 CheckerContext &C) const {
1107 // Are we storing to something that causes the value to "escape"?
1108 bool escapes = true;
1109
1110 // A value escapes in three possible cases (this may change):
1111 //
1112 // (1) we are binding to something that is not a memory region.
1113 // (2) we are binding to a memregion that does not have stack storage
1114 // (3) we are binding to a memregion with stack storage that the store
1115 // does not understand.
1116 ProgramStateRef state = C.getState();
1117
George Karpenkov6e9fd132018-08-22 01:17:09 +00001118 if (auto regionLoc = loc.getAs<loc::MemRegionVal>()) {
George Karpenkov70c2ee32018-08-17 21:41:07 +00001119 escapes = !regionLoc->getRegion()->hasStackStorage();
1120
1121 if (!escapes) {
1122 // To test (3), generate a new state with the binding added. If it is
1123 // the same state, then it escapes (since the store cannot represent
1124 // the binding).
1125 // Do this only if we know that the store is not supposed to generate the
1126 // same state.
1127 SVal StoredVal = state->getSVal(regionLoc->getRegion());
1128 if (StoredVal != val)
1129 escapes = (state == (state->bindLoc(*regionLoc, val, C.getLocationContext())));
1130 }
1131 if (!escapes) {
1132 // Case 4: We do not currently model what happens when a symbol is
1133 // assigned to a struct field, so be conservative here and let the symbol
1134 // go. TODO: This could definitely be improved upon.
1135 escapes = !isa<VarRegion>(regionLoc->getRegion());
1136 }
1137 }
1138
1139 // If we are storing the value into an auto function scope variable annotated
1140 // with (__attribute__((cleanup))), stop tracking the value to avoid leak
1141 // false positives.
George Karpenkov6e9fd132018-08-22 01:17:09 +00001142 if (const auto *LVR = dyn_cast_or_null<VarRegion>(loc.getAsRegion())) {
George Karpenkov70c2ee32018-08-17 21:41:07 +00001143 const VarDecl *VD = LVR->getDecl();
1144 if (VD->hasAttr<CleanupAttr>()) {
1145 escapes = true;
1146 }
1147 }
1148
1149 // If our store can represent the binding and we aren't storing to something
1150 // that doesn't have local storage then just return and have the simulation
1151 // state continue as is.
1152 if (!escapes)
1153 return;
1154
1155 // Otherwise, find all symbols referenced by 'val' that we are tracking
1156 // and stop tracking them.
1157 state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1158 C.addTransition(state);
1159}
1160
1161ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
George Karpenkov6e9fd132018-08-22 01:17:09 +00001162 SVal Cond,
1163 bool Assumption) const {
George Karpenkov70c2ee32018-08-17 21:41:07 +00001164 // FIXME: We may add to the interface of evalAssume the list of symbols
1165 // whose assumptions have changed. For now we just iterate through the
1166 // bindings and check if any of the tracked symbols are NULL. This isn't
1167 // too bad since the number of symbols we will track in practice are
1168 // probably small and evalAssume is only called at branches and a few
1169 // other places.
1170 RefBindingsTy B = state->get<RefBindings>();
1171
1172 if (B.isEmpty())
1173 return state;
1174
1175 bool changed = false;
1176 RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1177
1178 for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1179 // Check if the symbol is null stop tracking the symbol.
1180 ConstraintManager &CMgr = state->getConstraintManager();
1181 ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
1182 if (AllocFailed.isConstrainedTrue()) {
1183 changed = true;
1184 B = RefBFactory.remove(B, I.getKey());
1185 }
1186 }
1187
1188 if (changed)
1189 state = state->set<RefBindings>(B);
1190
1191 return state;
1192}
1193
1194ProgramStateRef
1195RetainCountChecker::checkRegionChanges(ProgramStateRef state,
1196 const InvalidatedSymbols *invalidated,
1197 ArrayRef<const MemRegion *> ExplicitRegions,
1198 ArrayRef<const MemRegion *> Regions,
1199 const LocationContext *LCtx,
1200 const CallEvent *Call) const {
1201 if (!invalidated)
1202 return state;
1203
1204 llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
1205 for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
1206 E = ExplicitRegions.end(); I != E; ++I) {
1207 if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>())
1208 WhitelistedSymbols.insert(SR->getSymbol());
1209 }
1210
George Karpenkov6fd5c86d2018-10-31 17:38:29 +00001211 for (SymbolRef sym :
1212 llvm::make_range(invalidated->begin(), invalidated->end())) {
George Karpenkov70c2ee32018-08-17 21:41:07 +00001213 if (WhitelistedSymbols.count(sym))
1214 continue;
1215 // Remove any existing reference-count binding.
1216 state = removeRefBinding(state, sym);
1217 }
1218 return state;
1219}
1220
George Karpenkov70c2ee32018-08-17 21:41:07 +00001221ProgramStateRef
1222RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
1223 ExplodedNode *Pred,
1224 const ProgramPointTag *Tag,
1225 CheckerContext &Ctx,
George Karpenkov04553e52018-09-21 20:37:20 +00001226 SymbolRef Sym,
1227 RefVal V,
1228 const ReturnStmt *S) const {
George Karpenkov70c2ee32018-08-17 21:41:07 +00001229 unsigned ACnt = V.getAutoreleaseCount();
1230
1231 // No autorelease counts? Nothing to be done.
1232 if (!ACnt)
1233 return state;
1234
1235 unsigned Cnt = V.getCount();
1236
1237 // FIXME: Handle sending 'autorelease' to already released object.
1238
1239 if (V.getKind() == RefVal::ReturnedOwned)
1240 ++Cnt;
1241
1242 // If we would over-release here, but we know the value came from an ivar,
1243 // assume it was a strong ivar that's just been relinquished.
1244 if (ACnt > Cnt &&
1245 V.getIvarAccessHistory() == RefVal::IvarAccessHistory::AccessedDirectly) {
1246 V = V.releaseViaIvar();
1247 --ACnt;
1248 }
1249
1250 if (ACnt <= Cnt) {
1251 if (ACnt == Cnt) {
1252 V.clearCounts();
George Karpenkov04553e52018-09-21 20:37:20 +00001253 if (V.getKind() == RefVal::ReturnedOwned) {
George Karpenkov70c2ee32018-08-17 21:41:07 +00001254 V = V ^ RefVal::ReturnedNotOwned;
George Karpenkov04553e52018-09-21 20:37:20 +00001255 } else {
George Karpenkov70c2ee32018-08-17 21:41:07 +00001256 V = V ^ RefVal::NotOwned;
George Karpenkov04553e52018-09-21 20:37:20 +00001257 }
George Karpenkov70c2ee32018-08-17 21:41:07 +00001258 } else {
1259 V.setCount(V.getCount() - ACnt);
1260 V.setAutoreleaseCount(0);
1261 }
1262 return setRefBinding(state, Sym, V);
1263 }
1264
1265 // HACK: Ignore retain-count issues on values accessed through ivars,
1266 // because of cases like this:
1267 // [_contentView retain];
1268 // [_contentView removeFromSuperview];
1269 // [self addSubview:_contentView]; // invalidates 'self'
1270 // [_contentView release];
1271 if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1272 return state;
1273
1274 // Woah! More autorelease counts then retain counts left.
1275 // Emit hard error.
1276 V = V ^ RefVal::ErrorOverAutorelease;
1277 state = setRefBinding(state, Sym, V);
1278
1279 ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
1280 if (N) {
1281 SmallString<128> sbuf;
1282 llvm::raw_svector_ostream os(sbuf);
1283 os << "Object was autoreleased ";
1284 if (V.getAutoreleaseCount() > 1)
1285 os << V.getAutoreleaseCount() << " times but the object ";
1286 else
1287 os << "but ";
1288 os << "has a +" << V.getCount() << " retain count";
1289
1290 if (!overAutorelease)
1291 overAutorelease.reset(new OverAutorelease(this));
1292
1293 const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
George Karpenkov04553e52018-09-21 20:37:20 +00001294 auto R = llvm::make_unique<CFRefReport>(*overAutorelease, LOpts, SummaryLog,
1295 N, Sym, os.str());
1296 Ctx.emitReport(std::move(R));
George Karpenkov70c2ee32018-08-17 21:41:07 +00001297 }
1298
1299 return nullptr;
1300}
1301
1302ProgramStateRef
1303RetainCountChecker::handleSymbolDeath(ProgramStateRef state,
1304 SymbolRef sid, RefVal V,
1305 SmallVectorImpl<SymbolRef> &Leaked) const {
1306 bool hasLeak;
1307
1308 // HACK: Ignore retain-count issues on values accessed through ivars,
1309 // because of cases like this:
1310 // [_contentView retain];
1311 // [_contentView removeFromSuperview];
1312 // [self addSubview:_contentView]; // invalidates 'self'
1313 // [_contentView release];
1314 if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1315 hasLeak = false;
1316 else if (V.isOwned())
1317 hasLeak = true;
1318 else if (V.isNotOwned() || V.isReturnedOwned())
1319 hasLeak = (V.getCount() > 0);
1320 else
1321 hasLeak = false;
1322
1323 if (!hasLeak)
1324 return removeRefBinding(state, sid);
1325
1326 Leaked.push_back(sid);
1327 return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
1328}
1329
1330ExplodedNode *
1331RetainCountChecker::processLeaks(ProgramStateRef state,
1332 SmallVectorImpl<SymbolRef> &Leaked,
1333 CheckerContext &Ctx,
1334 ExplodedNode *Pred) const {
1335 // Generate an intermediate node representing the leak point.
1336 ExplodedNode *N = Ctx.addTransition(state, Pred);
1337
1338 if (N) {
1339 for (SmallVectorImpl<SymbolRef>::iterator
1340 I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
1341
1342 const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1343 CFRefBug *BT = Pred ? getLeakWithinFunctionBug(LOpts)
1344 : getLeakAtReturnBug(LOpts);
1345 assert(BT && "BugType not initialized.");
1346
George Karpenkov6babf2a2018-09-21 20:36:21 +00001347 Ctx.emitReport(llvm::make_unique<CFRefLeakReport>(
George Karpenkov936a9c92018-12-07 20:21:37 +00001348 *BT, LOpts, SummaryLog, N, *I, Ctx));
George Karpenkov70c2ee32018-08-17 21:41:07 +00001349 }
1350 }
1351
1352 return N;
1353}
1354
George Karpenkovb1b791b2018-08-17 21:43:27 +00001355static bool isISLObjectRef(QualType Ty) {
1356 return StringRef(Ty.getAsString()).startswith("isl_");
George Karpenkov70c2ee32018-08-17 21:41:07 +00001357}
1358
1359void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
1360 if (!Ctx.inTopFrame())
1361 return;
1362
George Karpenkovc4d6b932018-08-17 21:42:05 +00001363 RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
George Karpenkov70c2ee32018-08-17 21:41:07 +00001364 const LocationContext *LCtx = Ctx.getLocationContext();
1365 const FunctionDecl *FD = dyn_cast<FunctionDecl>(LCtx->getDecl());
1366
George Karpenkovc4d6b932018-08-17 21:42:05 +00001367 if (!FD || SmrMgr.isTrustedReferenceCountImplementation(FD))
George Karpenkov70c2ee32018-08-17 21:41:07 +00001368 return;
1369
1370 ProgramStateRef state = Ctx.getState();
George Karpenkovc4d6b932018-08-17 21:42:05 +00001371 const RetainSummary *FunctionSummary = SmrMgr.getFunctionSummary(FD);
George Karpenkov70c2ee32018-08-17 21:41:07 +00001372 ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
1373
1374 for (unsigned idx = 0, e = FD->getNumParams(); idx != e; ++idx) {
1375 const ParmVarDecl *Param = FD->getParamDecl(idx);
1376 SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1377
1378 QualType Ty = Param->getType();
1379 const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
George Karpenkovb1b791b2018-08-17 21:43:27 +00001380 if (AE && *AE == DecRef && isISLObjectRef(Ty)) {
George Karpenkov6e9fd132018-08-22 01:17:09 +00001381 state = setRefBinding(
1382 state, Sym, RefVal::makeOwned(RetEffect::ObjKind::Generalized, Ty));
George Karpenkovb1b791b2018-08-17 21:43:27 +00001383 } else if (isISLObjectRef(Ty)) {
George Karpenkov70c2ee32018-08-17 21:41:07 +00001384 state = setRefBinding(
1385 state, Sym,
1386 RefVal::makeNotOwned(RetEffect::ObjKind::Generalized, Ty));
1387 }
1388 }
1389
1390 Ctx.addTransition(state);
1391}
1392
1393void RetainCountChecker::checkEndFunction(const ReturnStmt *RS,
1394 CheckerContext &Ctx) const {
George Karpenkov04553e52018-09-21 20:37:20 +00001395 ExplodedNode *Pred = processReturn(RS, Ctx);
1396
1397 // Created state cached out.
1398 if (!Pred) {
1399 return;
1400 }
1401
1402 ProgramStateRef state = Pred->getState();
George Karpenkov70c2ee32018-08-17 21:41:07 +00001403 RefBindingsTy B = state->get<RefBindings>();
George Karpenkov70c2ee32018-08-17 21:41:07 +00001404
1405 // Don't process anything within synthesized bodies.
1406 const LocationContext *LCtx = Pred->getLocationContext();
1407 if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
1408 assert(!LCtx->inTopFrame());
1409 return;
1410 }
1411
1412 for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1413 state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
1414 I->first, I->second);
1415 if (!state)
1416 return;
1417 }
1418
1419 // If the current LocationContext has a parent, don't check for leaks.
1420 // We will do that later.
1421 // FIXME: we should instead check for imbalances of the retain/releases,
1422 // and suggest annotations.
1423 if (LCtx->getParent())
1424 return;
1425
1426 B = state->get<RefBindings>();
1427 SmallVector<SymbolRef, 10> Leaked;
1428
1429 for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
1430 state = handleSymbolDeath(state, I->first, I->second, Leaked);
1431
1432 processLeaks(state, Leaked, Ctx, Pred);
1433}
1434
George Karpenkov70c2ee32018-08-17 21:41:07 +00001435void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
1436 CheckerContext &C) const {
1437 ExplodedNode *Pred = C.getPredecessor();
1438
1439 ProgramStateRef state = C.getState();
1440 RefBindingsTy B = state->get<RefBindings>();
1441 SmallVector<SymbolRef, 10> Leaked;
1442
1443 // Update counts from autorelease pools
Artem Dergachevbbc6d682018-11-30 03:27:50 +00001444 for (const auto &I: state->get<RefBindings>()) {
1445 SymbolRef Sym = I.first;
1446 if (SymReaper.isDead(Sym)) {
Artem Dergachev65b4d7d2018-10-15 17:47:56 +00001447 static CheckerProgramPointTag Tag(this, "DeadSymbolAutorelease");
Artem Dergachevbbc6d682018-11-30 03:27:50 +00001448 const RefVal &V = I.second;
1449 state = handleAutoreleaseCounts(state, Pred, &Tag, C, Sym, V);
George Karpenkov70c2ee32018-08-17 21:41:07 +00001450 if (!state)
1451 return;
1452
1453 // Fetch the new reference count from the state, and use it to handle
1454 // this symbol.
Artem Dergachevbbc6d682018-11-30 03:27:50 +00001455 state = handleSymbolDeath(state, Sym, *getRefBinding(state, Sym), Leaked);
George Karpenkov70c2ee32018-08-17 21:41:07 +00001456 }
1457 }
1458
1459 if (Leaked.empty()) {
1460 C.addTransition(state);
1461 return;
1462 }
1463
1464 Pred = processLeaks(state, Leaked, C, Pred);
1465
1466 // Did we cache out?
1467 if (!Pred)
1468 return;
1469
1470 // Now generate a new node that nukes the old bindings.
1471 // The only bindings left at this point are the leaked symbols.
1472 RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1473 B = state->get<RefBindings>();
1474
1475 for (SmallVectorImpl<SymbolRef>::iterator I = Leaked.begin(),
1476 E = Leaked.end();
1477 I != E; ++I)
1478 B = F.remove(B, *I);
1479
1480 state = state->set<RefBindings>(B);
1481 C.addTransition(state, Pred);
1482}
1483
1484void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
1485 const char *NL, const char *Sep) const {
1486
1487 RefBindingsTy B = State->get<RefBindings>();
1488
1489 if (B.isEmpty())
1490 return;
1491
1492 Out << Sep << NL;
1493
1494 for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1495 Out << I->first << " : ";
1496 I->second.print(Out);
1497 Out << NL;
1498 }
1499}
1500
1501//===----------------------------------------------------------------------===//
George Karpenkov70c2ee32018-08-17 21:41:07 +00001502// Checker registration.
1503//===----------------------------------------------------------------------===//
1504
1505void ento::registerRetainCountChecker(CheckerManager &Mgr) {
Kristof Umannc83b0dd2018-11-02 15:48:10 +00001506 auto *Chk = Mgr.registerChecker<RetainCountChecker>();
1507
1508 AnalyzerOptions &Options = Mgr.getAnalyzerOptions();
1509
Kristof Umann0a1f91c2018-11-05 03:50:37 +00001510 Chk->ShouldCheckOSObjectRetainCount = Options.getCheckerBooleanOption(
1511 "CheckOSObject", true, Chk);
George Karpenkov70c2ee32018-08-17 21:41:07 +00001512}