Coverage Report

Created: 2019-07-24 05:18

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