1 //== BasicObjCFoundationChecks.cpp - Simple Apple-Foundation checks -*- 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 BasicObjCFoundationChecks, a class that encapsulates
11 //  a set of simple checks to run on Objective-C code using Apple's Foundation
12 //  classes.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "ClangSACheckers.h"
17 #include "SelectorExtras.h"
18 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/DeclObjC.h"
20 #include "clang/AST/Expr.h"
21 #include "clang/AST/ExprObjC.h"
22 #include "clang/AST/StmtObjC.h"
23 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
24 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
25 #include "clang/StaticAnalyzer/Core/Checker.h"
26 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
27 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
28 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
29 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
30 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
31 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
32 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
33 #include "llvm/ADT/SmallString.h"
34 #include "llvm/ADT/StringMap.h"
35 #include "llvm/Support/raw_ostream.h"
36 
37 using namespace clang;
38 using namespace ento;
39 
40 namespace {
41 class APIMisuse : public BugType {
42 public:
43   APIMisuse(const CheckerBase *checker, const char *name)
44       : BugType(checker, name, "API Misuse (Apple)") {}
45 };
46 } // end anonymous namespace
47 
48 //===----------------------------------------------------------------------===//
49 // Utility functions.
50 //===----------------------------------------------------------------------===//
51 
52 static StringRef GetReceiverInterfaceName(const ObjCMethodCall &msg) {
53   if (const ObjCInterfaceDecl *ID = msg.getReceiverInterface())
54     return ID->getIdentifier()->getName();
55   return StringRef();
56 }
57 
58 enum FoundationClass {
59   FC_None,
60   FC_NSArray,
61   FC_NSDictionary,
62   FC_NSEnumerator,
63   FC_NSNull,
64   FC_NSOrderedSet,
65   FC_NSSet,
66   FC_NSString
67 };
68 
69 static FoundationClass findKnownClass(const ObjCInterfaceDecl *ID,
70                                       bool IncludeSuperclasses = true) {
71   static llvm::StringMap<FoundationClass> Classes;
72   if (Classes.empty()) {
73     Classes["NSArray"] = FC_NSArray;
74     Classes["NSDictionary"] = FC_NSDictionary;
75     Classes["NSEnumerator"] = FC_NSEnumerator;
76     Classes["NSNull"] = FC_NSNull;
77     Classes["NSOrderedSet"] = FC_NSOrderedSet;
78     Classes["NSSet"] = FC_NSSet;
79     Classes["NSString"] = FC_NSString;
80   }
81 
82   // FIXME: Should we cache this at all?
83   FoundationClass result = Classes.lookup(ID->getIdentifier()->getName());
84   if (result == FC_None && IncludeSuperclasses)
85     if (const ObjCInterfaceDecl *Super = ID->getSuperClass())
86       return findKnownClass(Super);
87 
88   return result;
89 }
90 
91 //===----------------------------------------------------------------------===//
92 // NilArgChecker - Check for prohibited nil arguments to ObjC method calls.
93 //===----------------------------------------------------------------------===//
94 
95 namespace {
96   class NilArgChecker : public Checker<check::PreObjCMessage,
97                                        check::PostStmt<ObjCDictionaryLiteral>,
98                                        check::PostStmt<ObjCArrayLiteral> > {
99     mutable std::unique_ptr<APIMisuse> BT;
100 
101     mutable llvm::SmallDenseMap<Selector, unsigned, 16> StringSelectors;
102     mutable Selector ArrayWithObjectSel;
103     mutable Selector AddObjectSel;
104     mutable Selector InsertObjectAtIndexSel;
105     mutable Selector ReplaceObjectAtIndexWithObjectSel;
106     mutable Selector SetObjectAtIndexedSubscriptSel;
107     mutable Selector ArrayByAddingObjectSel;
108     mutable Selector DictionaryWithObjectForKeySel;
109     mutable Selector SetObjectForKeySel;
110     mutable Selector SetObjectForKeyedSubscriptSel;
111     mutable Selector RemoveObjectForKeySel;
112 
113     void warnIfNilExpr(const Expr *E,
114                        const char *Msg,
115                        CheckerContext &C) const;
116 
117     void warnIfNilArg(CheckerContext &C,
118                       const ObjCMethodCall &msg, unsigned Arg,
119                       FoundationClass Class,
120                       bool CanBeSubscript = false) const;
121 
122     void generateBugReport(ExplodedNode *N,
123                            StringRef Msg,
124                            SourceRange Range,
125                            const Expr *Expr,
126                            CheckerContext &C) const;
127 
128   public:
129     void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
130     void checkPostStmt(const ObjCDictionaryLiteral *DL,
131                        CheckerContext &C) const;
132     void checkPostStmt(const ObjCArrayLiteral *AL,
133                        CheckerContext &C) const;
134   };
135 } // end anonymous namespace
136 
137 void NilArgChecker::warnIfNilExpr(const Expr *E,
138                                   const char *Msg,
139                                   CheckerContext &C) const {
140   ProgramStateRef State = C.getState();
141   if (State->isNull(C.getSVal(E)).isConstrainedTrue()) {
142 
143     if (ExplodedNode *N = C.generateErrorNode()) {
144       generateBugReport(N, Msg, E->getSourceRange(), E, C);
145     }
146   }
147 }
148 
149 void NilArgChecker::warnIfNilArg(CheckerContext &C,
150                                  const ObjCMethodCall &msg,
151                                  unsigned int Arg,
152                                  FoundationClass Class,
153                                  bool CanBeSubscript) const {
154   // Check if the argument is nil.
155   ProgramStateRef State = C.getState();
156   if (!State->isNull(msg.getArgSVal(Arg)).isConstrainedTrue())
157       return;
158 
159   if (ExplodedNode *N = C.generateErrorNode()) {
160     SmallString<128> sbuf;
161     llvm::raw_svector_ostream os(sbuf);
162 
163     if (CanBeSubscript && msg.getMessageKind() == OCM_Subscript) {
164 
165       if (Class == FC_NSArray) {
166         os << "Array element cannot be nil";
167       } else if (Class == FC_NSDictionary) {
168         if (Arg == 0) {
169           os << "Value stored into '";
170           os << GetReceiverInterfaceName(msg) << "' cannot be nil";
171         } else {
172           assert(Arg == 1);
173           os << "'"<< GetReceiverInterfaceName(msg) << "' key cannot be nil";
174         }
175       } else
176         llvm_unreachable("Missing foundation class for the subscript expr");
177 
178     } else {
179       if (Class == FC_NSDictionary) {
180         if (Arg == 0)
181           os << "Value argument ";
182         else {
183           assert(Arg == 1);
184           os << "Key argument ";
185         }
186         os << "to '";
187         msg.getSelector().print(os);
188         os << "' cannot be nil";
189       } else {
190         os << "Argument to '" << GetReceiverInterfaceName(msg) << "' method '";
191         msg.getSelector().print(os);
192         os << "' cannot be nil";
193       }
194     }
195 
196     generateBugReport(N, os.str(), msg.getArgSourceRange(Arg),
197                       msg.getArgExpr(Arg), C);
198   }
199 }
200 
201 void NilArgChecker::generateBugReport(ExplodedNode *N,
202                                       StringRef Msg,
203                                       SourceRange Range,
204                                       const Expr *E,
205                                       CheckerContext &C) const {
206   if (!BT)
207     BT.reset(new APIMisuse(this, "nil argument"));
208 
209   auto R = llvm::make_unique<BugReport>(*BT, Msg, N);
210   R->addRange(Range);
211   bugreporter::trackNullOrUndefValue(N, E, *R);
212   C.emitReport(std::move(R));
213 }
214 
215 void NilArgChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
216                                         CheckerContext &C) const {
217   const ObjCInterfaceDecl *ID = msg.getReceiverInterface();
218   if (!ID)
219     return;
220 
221   FoundationClass Class = findKnownClass(ID);
222 
223   static const unsigned InvalidArgIndex = UINT_MAX;
224   unsigned Arg = InvalidArgIndex;
225   bool CanBeSubscript = false;
226 
227   if (Class == FC_NSString) {
228     Selector S = msg.getSelector();
229 
230     if (S.isUnarySelector())
231       return;
232 
233     if (StringSelectors.empty()) {
234       ASTContext &Ctx = C.getASTContext();
235       Selector Sels[] = {
236           getKeywordSelector(Ctx, "caseInsensitiveCompare"),
237           getKeywordSelector(Ctx, "compare"),
238           getKeywordSelector(Ctx, "compare", "options"),
239           getKeywordSelector(Ctx, "compare", "options", "range"),
240           getKeywordSelector(Ctx, "compare", "options", "range", "locale"),
241           getKeywordSelector(Ctx, "componentsSeparatedByCharactersInSet"),
242           getKeywordSelector(Ctx, "initWithFormat"),
243           getKeywordSelector(Ctx, "localizedCaseInsensitiveCompare"),
244           getKeywordSelector(Ctx, "localizedCompare"),
245           getKeywordSelector(Ctx, "localizedStandardCompare"),
246       };
247       for (Selector KnownSel : Sels)
248         StringSelectors[KnownSel] = 0;
249     }
250     auto I = StringSelectors.find(S);
251     if (I == StringSelectors.end())
252       return;
253     Arg = I->second;
254   } else if (Class == FC_NSArray) {
255     Selector S = msg.getSelector();
256 
257     if (S.isUnarySelector())
258       return;
259 
260     if (ArrayWithObjectSel.isNull()) {
261       ASTContext &Ctx = C.getASTContext();
262       ArrayWithObjectSel = getKeywordSelector(Ctx, "arrayWithObject");
263       AddObjectSel = getKeywordSelector(Ctx, "addObject");
264       InsertObjectAtIndexSel =
265           getKeywordSelector(Ctx, "insertObject", "atIndex");
266       ReplaceObjectAtIndexWithObjectSel =
267           getKeywordSelector(Ctx, "replaceObjectAtIndex", "withObject");
268       SetObjectAtIndexedSubscriptSel =
269           getKeywordSelector(Ctx, "setObject", "atIndexedSubscript");
270       ArrayByAddingObjectSel = getKeywordSelector(Ctx, "arrayByAddingObject");
271     }
272 
273     if (S == ArrayWithObjectSel || S == AddObjectSel ||
274         S == InsertObjectAtIndexSel || S == ArrayByAddingObjectSel) {
275       Arg = 0;
276     } else if (S == SetObjectAtIndexedSubscriptSel) {
277       Arg = 0;
278       CanBeSubscript = true;
279     } else if (S == ReplaceObjectAtIndexWithObjectSel) {
280       Arg = 1;
281     }
282   } else if (Class == FC_NSDictionary) {
283     Selector S = msg.getSelector();
284 
285     if (S.isUnarySelector())
286       return;
287 
288     if (DictionaryWithObjectForKeySel.isNull()) {
289       ASTContext &Ctx = C.getASTContext();
290       DictionaryWithObjectForKeySel =
291           getKeywordSelector(Ctx, "dictionaryWithObject", "forKey");
292       SetObjectForKeySel = getKeywordSelector(Ctx, "setObject", "forKey");
293       SetObjectForKeyedSubscriptSel =
294           getKeywordSelector(Ctx, "setObject", "forKeyedSubscript");
295       RemoveObjectForKeySel = getKeywordSelector(Ctx, "removeObjectForKey");
296     }
297 
298     if (S == DictionaryWithObjectForKeySel || S == SetObjectForKeySel) {
299       Arg = 0;
300       warnIfNilArg(C, msg, /* Arg */1, Class);
301     } else if (S == SetObjectForKeyedSubscriptSel) {
302       CanBeSubscript = true;
303       Arg = 1;
304     } else if (S == RemoveObjectForKeySel) {
305       Arg = 0;
306     }
307   }
308 
309   // If argument is '0', report a warning.
310   if ((Arg != InvalidArgIndex))
311     warnIfNilArg(C, msg, Arg, Class, CanBeSubscript);
312 }
313 
314 void NilArgChecker::checkPostStmt(const ObjCArrayLiteral *AL,
315                                   CheckerContext &C) const {
316   unsigned NumOfElements = AL->getNumElements();
317   for (unsigned i = 0; i < NumOfElements; ++i) {
318     warnIfNilExpr(AL->getElement(i), "Array element cannot be nil", C);
319   }
320 }
321 
322 void NilArgChecker::checkPostStmt(const ObjCDictionaryLiteral *DL,
323                                   CheckerContext &C) const {
324   unsigned NumOfElements = DL->getNumElements();
325   for (unsigned i = 0; i < NumOfElements; ++i) {
326     ObjCDictionaryElement Element = DL->getKeyValueElement(i);
327     warnIfNilExpr(Element.Key, "Dictionary key cannot be nil", C);
328     warnIfNilExpr(Element.Value, "Dictionary value cannot be nil", C);
329   }
330 }
331 
332 //===----------------------------------------------------------------------===//
333 // Checking for mismatched types passed to CFNumberCreate/CFNumberGetValue.
334 //===----------------------------------------------------------------------===//
335 
336 namespace {
337 class CFNumberChecker : public Checker< check::PreStmt<CallExpr> > {
338   mutable std::unique_ptr<APIMisuse> BT;
339   mutable IdentifierInfo *ICreate, *IGetValue;
340 public:
341   CFNumberChecker() : ICreate(nullptr), IGetValue(nullptr) {}
342 
343   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
344 
345 private:
346   void EmitError(const TypedRegion* R, const Expr *Ex,
347                 uint64_t SourceSize, uint64_t TargetSize, uint64_t NumberKind);
348 };
349 } // end anonymous namespace
350 
351 enum CFNumberType {
352   kCFNumberSInt8Type = 1,
353   kCFNumberSInt16Type = 2,
354   kCFNumberSInt32Type = 3,
355   kCFNumberSInt64Type = 4,
356   kCFNumberFloat32Type = 5,
357   kCFNumberFloat64Type = 6,
358   kCFNumberCharType = 7,
359   kCFNumberShortType = 8,
360   kCFNumberIntType = 9,
361   kCFNumberLongType = 10,
362   kCFNumberLongLongType = 11,
363   kCFNumberFloatType = 12,
364   kCFNumberDoubleType = 13,
365   kCFNumberCFIndexType = 14,
366   kCFNumberNSIntegerType = 15,
367   kCFNumberCGFloatType = 16
368 };
369 
370 static Optional<uint64_t> GetCFNumberSize(ASTContext &Ctx, uint64_t i) {
371   static const unsigned char FixedSize[] = { 8, 16, 32, 64, 32, 64 };
372 
373   if (i < kCFNumberCharType)
374     return FixedSize[i-1];
375 
376   QualType T;
377 
378   switch (i) {
379     case kCFNumberCharType:     T = Ctx.CharTy;     break;
380     case kCFNumberShortType:    T = Ctx.ShortTy;    break;
381     case kCFNumberIntType:      T = Ctx.IntTy;      break;
382     case kCFNumberLongType:     T = Ctx.LongTy;     break;
383     case kCFNumberLongLongType: T = Ctx.LongLongTy; break;
384     case kCFNumberFloatType:    T = Ctx.FloatTy;    break;
385     case kCFNumberDoubleType:   T = Ctx.DoubleTy;   break;
386     case kCFNumberCFIndexType:
387     case kCFNumberNSIntegerType:
388     case kCFNumberCGFloatType:
389       // FIXME: We need a way to map from names to Type*.
390     default:
391       return None;
392   }
393 
394   return Ctx.getTypeSize(T);
395 }
396 
397 #if 0
398 static const char* GetCFNumberTypeStr(uint64_t i) {
399   static const char* Names[] = {
400     "kCFNumberSInt8Type",
401     "kCFNumberSInt16Type",
402     "kCFNumberSInt32Type",
403     "kCFNumberSInt64Type",
404     "kCFNumberFloat32Type",
405     "kCFNumberFloat64Type",
406     "kCFNumberCharType",
407     "kCFNumberShortType",
408     "kCFNumberIntType",
409     "kCFNumberLongType",
410     "kCFNumberLongLongType",
411     "kCFNumberFloatType",
412     "kCFNumberDoubleType",
413     "kCFNumberCFIndexType",
414     "kCFNumberNSIntegerType",
415     "kCFNumberCGFloatType"
416   };
417 
418   return i <= kCFNumberCGFloatType ? Names[i-1] : "Invalid CFNumberType";
419 }
420 #endif
421 
422 void CFNumberChecker::checkPreStmt(const CallExpr *CE,
423                                          CheckerContext &C) const {
424   ProgramStateRef state = C.getState();
425   const FunctionDecl *FD = C.getCalleeDecl(CE);
426   if (!FD)
427     return;
428 
429   ASTContext &Ctx = C.getASTContext();
430   if (!ICreate) {
431     ICreate = &Ctx.Idents.get("CFNumberCreate");
432     IGetValue = &Ctx.Idents.get("CFNumberGetValue");
433   }
434   if (!(FD->getIdentifier() == ICreate || FD->getIdentifier() == IGetValue) ||
435       CE->getNumArgs() != 3)
436     return;
437 
438   // Get the value of the "theType" argument.
439   const LocationContext *LCtx = C.getLocationContext();
440   SVal TheTypeVal = state->getSVal(CE->getArg(1), LCtx);
441 
442   // FIXME: We really should allow ranges of valid theType values, and
443   //   bifurcate the state appropriately.
444   Optional<nonloc::ConcreteInt> V = TheTypeVal.getAs<nonloc::ConcreteInt>();
445   if (!V)
446     return;
447 
448   uint64_t NumberKind = V->getValue().getLimitedValue();
449   Optional<uint64_t> OptCFNumberSize = GetCFNumberSize(Ctx, NumberKind);
450 
451   // FIXME: In some cases we can emit an error.
452   if (!OptCFNumberSize)
453     return;
454 
455   uint64_t CFNumberSize = *OptCFNumberSize;
456 
457   // Look at the value of the integer being passed by reference.  Essentially
458   // we want to catch cases where the value passed in is not equal to the
459   // size of the type being created.
460   SVal TheValueExpr = state->getSVal(CE->getArg(2), LCtx);
461 
462   // FIXME: Eventually we should handle arbitrary locations.  We can do this
463   //  by having an enhanced memory model that does low-level typing.
464   Optional<loc::MemRegionVal> LV = TheValueExpr.getAs<loc::MemRegionVal>();
465   if (!LV)
466     return;
467 
468   const TypedValueRegion* R = dyn_cast<TypedValueRegion>(LV->stripCasts());
469   if (!R)
470     return;
471 
472   QualType T = Ctx.getCanonicalType(R->getValueType());
473 
474   // FIXME: If the pointee isn't an integer type, should we flag a warning?
475   //  People can do weird stuff with pointers.
476 
477   if (!T->isIntegralOrEnumerationType())
478     return;
479 
480   uint64_t PrimitiveTypeSize = Ctx.getTypeSize(T);
481 
482   if (PrimitiveTypeSize == CFNumberSize)
483     return;
484 
485   // FIXME: We can actually create an abstract "CFNumber" object that has
486   //  the bits initialized to the provided values.
487   ExplodedNode *N = C.generateNonFatalErrorNode();
488   if (N) {
489     SmallString<128> sbuf;
490     llvm::raw_svector_ostream os(sbuf);
491     bool isCreate = (FD->getIdentifier() == ICreate);
492 
493     if (isCreate) {
494       os << (PrimitiveTypeSize == 8 ? "An " : "A ")
495          << PrimitiveTypeSize << "-bit integer is used to initialize a "
496          << "CFNumber object that represents "
497          << (CFNumberSize == 8 ? "an " : "a ")
498          << CFNumberSize << "-bit integer; ";
499     } else {
500       os << "A CFNumber object that represents "
501          << (CFNumberSize == 8 ? "an " : "a ")
502          << CFNumberSize << "-bit integer is used to initialize "
503          << (PrimitiveTypeSize == 8 ? "an " : "a ")
504          << PrimitiveTypeSize << "-bit integer; ";
505     }
506 
507     if (PrimitiveTypeSize < CFNumberSize)
508       os << (CFNumberSize - PrimitiveTypeSize)
509       << " bits of the CFNumber value will "
510       << (isCreate ? "be garbage." : "overwrite adjacent storage.");
511     else
512       os << (PrimitiveTypeSize - CFNumberSize)
513       << " bits of the integer value will be "
514       << (isCreate ? "lost." : "garbage.");
515 
516     if (!BT)
517       BT.reset(new APIMisuse(this, "Bad use of CFNumber APIs"));
518 
519     auto report = llvm::make_unique<BugReport>(*BT, os.str(), N);
520     report->addRange(CE->getArg(2)->getSourceRange());
521     C.emitReport(std::move(report));
522   }
523 }
524 
525 //===----------------------------------------------------------------------===//
526 // CFRetain/CFRelease/CFMakeCollectable/CFAutorelease checking for null arguments.
527 //===----------------------------------------------------------------------===//
528 
529 namespace {
530 class CFRetainReleaseChecker : public Checker< check::PreStmt<CallExpr> > {
531   mutable std::unique_ptr<APIMisuse> BT;
532   mutable IdentifierInfo *Retain, *Release, *MakeCollectable, *Autorelease;
533 
534 public:
535   CFRetainReleaseChecker()
536       : Retain(nullptr), Release(nullptr), MakeCollectable(nullptr),
537         Autorelease(nullptr) {}
538   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
539 };
540 } // end anonymous namespace
541 
542 void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
543                                           CheckerContext &C) const {
544   // If the CallExpr doesn't have exactly 1 argument just give up checking.
545   if (CE->getNumArgs() != 1)
546     return;
547 
548   ProgramStateRef state = C.getState();
549   const FunctionDecl *FD = C.getCalleeDecl(CE);
550   if (!FD)
551     return;
552 
553   if (!BT) {
554     ASTContext &Ctx = C.getASTContext();
555     Retain = &Ctx.Idents.get("CFRetain");
556     Release = &Ctx.Idents.get("CFRelease");
557     MakeCollectable = &Ctx.Idents.get("CFMakeCollectable");
558     Autorelease = &Ctx.Idents.get("CFAutorelease");
559     BT.reset(new APIMisuse(
560         this, "null passed to CF memory management function"));
561   }
562 
563   // Check if we called CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
564   const IdentifierInfo *FuncII = FD->getIdentifier();
565   if (!(FuncII == Retain || FuncII == Release || FuncII == MakeCollectable ||
566         FuncII == Autorelease))
567     return;
568 
569   // FIXME: The rest of this just checks that the argument is non-null.
570   // It should probably be refactored and combined with NonNullParamChecker.
571 
572   // Get the argument's value.
573   const Expr *Arg = CE->getArg(0);
574   SVal ArgVal = state->getSVal(Arg, C.getLocationContext());
575   Optional<DefinedSVal> DefArgVal = ArgVal.getAs<DefinedSVal>();
576   if (!DefArgVal)
577     return;
578 
579   // Get a NULL value.
580   SValBuilder &svalBuilder = C.getSValBuilder();
581   DefinedSVal zero =
582       svalBuilder.makeZeroVal(Arg->getType()).castAs<DefinedSVal>();
583 
584   // Make an expression asserting that they're equal.
585   DefinedOrUnknownSVal ArgIsNull = svalBuilder.evalEQ(state, zero, *DefArgVal);
586 
587   // Are they equal?
588   ProgramStateRef stateTrue, stateFalse;
589   std::tie(stateTrue, stateFalse) = state->assume(ArgIsNull);
590 
591   if (stateTrue && !stateFalse) {
592     ExplodedNode *N = C.generateErrorNode(stateTrue);
593     if (!N)
594       return;
595 
596     const char *description;
597     if (FuncII == Retain)
598       description = "Null pointer argument in call to CFRetain";
599     else if (FuncII == Release)
600       description = "Null pointer argument in call to CFRelease";
601     else if (FuncII == MakeCollectable)
602       description = "Null pointer argument in call to CFMakeCollectable";
603     else if (FuncII == Autorelease)
604       description = "Null pointer argument in call to CFAutorelease";
605     else
606       llvm_unreachable("impossible case");
607 
608     auto report = llvm::make_unique<BugReport>(*BT, description, N);
609     report->addRange(Arg->getSourceRange());
610     bugreporter::trackNullOrUndefValue(N, Arg, *report);
611     C.emitReport(std::move(report));
612     return;
613   }
614 
615   // From here on, we know the argument is non-null.
616   C.addTransition(stateFalse);
617 }
618 
619 //===----------------------------------------------------------------------===//
620 // Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
621 //===----------------------------------------------------------------------===//
622 
623 namespace {
624 class ClassReleaseChecker : public Checker<check::PreObjCMessage> {
625   mutable Selector releaseS;
626   mutable Selector retainS;
627   mutable Selector autoreleaseS;
628   mutable Selector drainS;
629   mutable std::unique_ptr<BugType> BT;
630 
631 public:
632   void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
633 };
634 } // end anonymous namespace
635 
636 void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
637                                               CheckerContext &C) const {
638   if (!BT) {
639     BT.reset(new APIMisuse(
640         this, "message incorrectly sent to class instead of class instance"));
641 
642     ASTContext &Ctx = C.getASTContext();
643     releaseS = GetNullarySelector("release", Ctx);
644     retainS = GetNullarySelector("retain", Ctx);
645     autoreleaseS = GetNullarySelector("autorelease", Ctx);
646     drainS = GetNullarySelector("drain", Ctx);
647   }
648 
649   if (msg.isInstanceMessage())
650     return;
651   const ObjCInterfaceDecl *Class = msg.getReceiverInterface();
652   assert(Class);
653 
654   Selector S = msg.getSelector();
655   if (!(S == releaseS || S == retainS || S == autoreleaseS || S == drainS))
656     return;
657 
658   if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
659     SmallString<200> buf;
660     llvm::raw_svector_ostream os(buf);
661 
662     os << "The '";
663     S.print(os);
664     os << "' message should be sent to instances "
665           "of class '" << Class->getName()
666        << "' and not the class directly";
667 
668     auto report = llvm::make_unique<BugReport>(*BT, os.str(), N);
669     report->addRange(msg.getSourceRange());
670     C.emitReport(std::move(report));
671   }
672 }
673 
674 //===----------------------------------------------------------------------===//
675 // Check for passing non-Objective-C types to variadic methods that expect
676 // only Objective-C types.
677 //===----------------------------------------------------------------------===//
678 
679 namespace {
680 class VariadicMethodTypeChecker : public Checker<check::PreObjCMessage> {
681   mutable Selector arrayWithObjectsS;
682   mutable Selector dictionaryWithObjectsAndKeysS;
683   mutable Selector setWithObjectsS;
684   mutable Selector orderedSetWithObjectsS;
685   mutable Selector initWithObjectsS;
686   mutable Selector initWithObjectsAndKeysS;
687   mutable std::unique_ptr<BugType> BT;
688 
689   bool isVariadicMessage(const ObjCMethodCall &msg) const;
690 
691 public:
692   void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
693 };
694 } // end anonymous namespace
695 
696 /// isVariadicMessage - Returns whether the given message is a variadic message,
697 /// where all arguments must be Objective-C types.
698 bool
699 VariadicMethodTypeChecker::isVariadicMessage(const ObjCMethodCall &msg) const {
700   const ObjCMethodDecl *MD = msg.getDecl();
701 
702   if (!MD || !MD->isVariadic() || isa<ObjCProtocolDecl>(MD->getDeclContext()))
703     return false;
704 
705   Selector S = msg.getSelector();
706 
707   if (msg.isInstanceMessage()) {
708     // FIXME: Ideally we'd look at the receiver interface here, but that's not
709     // useful for init, because alloc returns 'id'. In theory, this could lead
710     // to false positives, for example if there existed a class that had an
711     // initWithObjects: implementation that does accept non-Objective-C pointer
712     // types, but the chance of that happening is pretty small compared to the
713     // gains that this analysis gives.
714     const ObjCInterfaceDecl *Class = MD->getClassInterface();
715 
716     switch (findKnownClass(Class)) {
717     case FC_NSArray:
718     case FC_NSOrderedSet:
719     case FC_NSSet:
720       return S == initWithObjectsS;
721     case FC_NSDictionary:
722       return S == initWithObjectsAndKeysS;
723     default:
724       return false;
725     }
726   } else {
727     const ObjCInterfaceDecl *Class = msg.getReceiverInterface();
728 
729     switch (findKnownClass(Class)) {
730       case FC_NSArray:
731         return S == arrayWithObjectsS;
732       case FC_NSOrderedSet:
733         return S == orderedSetWithObjectsS;
734       case FC_NSSet:
735         return S == setWithObjectsS;
736       case FC_NSDictionary:
737         return S == dictionaryWithObjectsAndKeysS;
738       default:
739         return false;
740     }
741   }
742 }
743 
744 void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
745                                                     CheckerContext &C) const {
746   if (!BT) {
747     BT.reset(new APIMisuse(this,
748                            "Arguments passed to variadic method aren't all "
749                            "Objective-C pointer types"));
750 
751     ASTContext &Ctx = C.getASTContext();
752     arrayWithObjectsS = GetUnarySelector("arrayWithObjects", Ctx);
753     dictionaryWithObjectsAndKeysS =
754       GetUnarySelector("dictionaryWithObjectsAndKeys", Ctx);
755     setWithObjectsS = GetUnarySelector("setWithObjects", Ctx);
756     orderedSetWithObjectsS = GetUnarySelector("orderedSetWithObjects", Ctx);
757 
758     initWithObjectsS = GetUnarySelector("initWithObjects", Ctx);
759     initWithObjectsAndKeysS = GetUnarySelector("initWithObjectsAndKeys", Ctx);
760   }
761 
762   if (!isVariadicMessage(msg))
763       return;
764 
765   // We are not interested in the selector arguments since they have
766   // well-defined types, so the compiler will issue a warning for them.
767   unsigned variadicArgsBegin = msg.getSelector().getNumArgs();
768 
769   // We're not interested in the last argument since it has to be nil or the
770   // compiler would have issued a warning for it elsewhere.
771   unsigned variadicArgsEnd = msg.getNumArgs() - 1;
772 
773   if (variadicArgsEnd <= variadicArgsBegin)
774     return;
775 
776   // Verify that all arguments have Objective-C types.
777   Optional<ExplodedNode*> errorNode;
778 
779   for (unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
780     QualType ArgTy = msg.getArgExpr(I)->getType();
781     if (ArgTy->isObjCObjectPointerType())
782       continue;
783 
784     // Block pointers are treaded as Objective-C pointers.
785     if (ArgTy->isBlockPointerType())
786       continue;
787 
788     // Ignore pointer constants.
789     if (msg.getArgSVal(I).getAs<loc::ConcreteInt>())
790       continue;
791 
792     // Ignore pointer types annotated with 'NSObject' attribute.
793     if (C.getASTContext().isObjCNSObjectType(ArgTy))
794       continue;
795 
796     // Ignore CF references, which can be toll-free bridged.
797     if (coreFoundation::isCFObjectRef(ArgTy))
798       continue;
799 
800     // Generate only one error node to use for all bug reports.
801     if (!errorNode.hasValue())
802       errorNode = C.generateNonFatalErrorNode();
803 
804     if (!errorNode.getValue())
805       continue;
806 
807     SmallString<128> sbuf;
808     llvm::raw_svector_ostream os(sbuf);
809 
810     StringRef TypeName = GetReceiverInterfaceName(msg);
811     if (!TypeName.empty())
812       os << "Argument to '" << TypeName << "' method '";
813     else
814       os << "Argument to method '";
815 
816     msg.getSelector().print(os);
817     os << "' should be an Objective-C pointer type, not '";
818     ArgTy.print(os, C.getLangOpts());
819     os << "'";
820 
821     auto R = llvm::make_unique<BugReport>(*BT, os.str(), errorNode.getValue());
822     R->addRange(msg.getArgSourceRange(I));
823     C.emitReport(std::move(R));
824   }
825 }
826 
827 //===----------------------------------------------------------------------===//
828 // Improves the modeling of loops over Cocoa collections.
829 //===----------------------------------------------------------------------===//
830 
831 // The map from container symbol to the container count symbol.
832 // We currently will remember the last countainer count symbol encountered.
833 REGISTER_MAP_WITH_PROGRAMSTATE(ContainerCountMap, SymbolRef, SymbolRef)
834 REGISTER_MAP_WITH_PROGRAMSTATE(ContainerNonEmptyMap, SymbolRef, bool)
835 
836 namespace {
837 class ObjCLoopChecker
838   : public Checker<check::PostStmt<ObjCForCollectionStmt>,
839                    check::PostObjCMessage,
840                    check::DeadSymbols,
841                    check::PointerEscape > {
842   mutable IdentifierInfo *CountSelectorII;
843 
844   bool isCollectionCountMethod(const ObjCMethodCall &M,
845                                CheckerContext &C) const;
846 
847 public:
848   ObjCLoopChecker() : CountSelectorII(nullptr) {}
849   void checkPostStmt(const ObjCForCollectionStmt *FCS, CheckerContext &C) const;
850   void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
851   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
852   ProgramStateRef checkPointerEscape(ProgramStateRef State,
853                                      const InvalidatedSymbols &Escaped,
854                                      const CallEvent *Call,
855                                      PointerEscapeKind Kind) const;
856 };
857 } // end anonymous namespace
858 
859 static bool isKnownNonNilCollectionType(QualType T) {
860   const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
861   if (!PT)
862     return false;
863 
864   const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
865   if (!ID)
866     return false;
867 
868   switch (findKnownClass(ID)) {
869   case FC_NSArray:
870   case FC_NSDictionary:
871   case FC_NSEnumerator:
872   case FC_NSOrderedSet:
873   case FC_NSSet:
874     return true;
875   default:
876     return false;
877   }
878 }
879 
880 /// Assumes that the collection is non-nil.
881 ///
882 /// If the collection is known to be nil, returns NULL to indicate an infeasible
883 /// path.
884 static ProgramStateRef checkCollectionNonNil(CheckerContext &C,
885                                              ProgramStateRef State,
886                                              const ObjCForCollectionStmt *FCS) {
887   if (!State)
888     return nullptr;
889 
890   SVal CollectionVal = C.getSVal(FCS->getCollection());
891   Optional<DefinedSVal> KnownCollection = CollectionVal.getAs<DefinedSVal>();
892   if (!KnownCollection)
893     return State;
894 
895   ProgramStateRef StNonNil, StNil;
896   std::tie(StNonNil, StNil) = State->assume(*KnownCollection);
897   if (StNil && !StNonNil) {
898     // The collection is nil. This path is infeasible.
899     return nullptr;
900   }
901 
902   return StNonNil;
903 }
904 
905 /// Assumes that the collection elements are non-nil.
906 ///
907 /// This only applies if the collection is one of those known not to contain
908 /// nil values.
909 static ProgramStateRef checkElementNonNil(CheckerContext &C,
910                                           ProgramStateRef State,
911                                           const ObjCForCollectionStmt *FCS) {
912   if (!State)
913     return nullptr;
914 
915   // See if the collection is one where we /know/ the elements are non-nil.
916   if (!isKnownNonNilCollectionType(FCS->getCollection()->getType()))
917     return State;
918 
919   const LocationContext *LCtx = C.getLocationContext();
920   const Stmt *Element = FCS->getElement();
921 
922   // FIXME: Copied from ExprEngineObjC.
923   Optional<Loc> ElementLoc;
924   if (const DeclStmt *DS = dyn_cast<DeclStmt>(Element)) {
925     const VarDecl *ElemDecl = cast<VarDecl>(DS->getSingleDecl());
926     assert(ElemDecl->getInit() == nullptr);
927     ElementLoc = State->getLValue(ElemDecl, LCtx);
928   } else {
929     ElementLoc = State->getSVal(Element, LCtx).getAs<Loc>();
930   }
931 
932   if (!ElementLoc)
933     return State;
934 
935   // Go ahead and assume the value is non-nil.
936   SVal Val = State->getSVal(*ElementLoc);
937   return State->assume(Val.castAs<DefinedOrUnknownSVal>(), true);
938 }
939 
940 /// Returns NULL state if the collection is known to contain elements
941 /// (or is known not to contain elements if the Assumption parameter is false.)
942 static ProgramStateRef
943 assumeCollectionNonEmpty(CheckerContext &C, ProgramStateRef State,
944                          SymbolRef CollectionS, bool Assumption) {
945   if (!State || !CollectionS)
946     return State;
947 
948   const SymbolRef *CountS = State->get<ContainerCountMap>(CollectionS);
949   if (!CountS) {
950     const bool *KnownNonEmpty = State->get<ContainerNonEmptyMap>(CollectionS);
951     if (!KnownNonEmpty)
952       return State->set<ContainerNonEmptyMap>(CollectionS, Assumption);
953     return (Assumption == *KnownNonEmpty) ? State : nullptr;
954   }
955 
956   SValBuilder &SvalBuilder = C.getSValBuilder();
957   SVal CountGreaterThanZeroVal =
958     SvalBuilder.evalBinOp(State, BO_GT,
959                           nonloc::SymbolVal(*CountS),
960                           SvalBuilder.makeIntVal(0, (*CountS)->getType()),
961                           SvalBuilder.getConditionType());
962   Optional<DefinedSVal> CountGreaterThanZero =
963     CountGreaterThanZeroVal.getAs<DefinedSVal>();
964   if (!CountGreaterThanZero) {
965     // The SValBuilder cannot construct a valid SVal for this condition.
966     // This means we cannot properly reason about it.
967     return State;
968   }
969 
970   return State->assume(*CountGreaterThanZero, Assumption);
971 }
972 
973 static ProgramStateRef
974 assumeCollectionNonEmpty(CheckerContext &C, ProgramStateRef State,
975                          const ObjCForCollectionStmt *FCS,
976                          bool Assumption) {
977   if (!State)
978     return nullptr;
979 
980   SymbolRef CollectionS =
981     State->getSVal(FCS->getCollection(), C.getLocationContext()).getAsSymbol();
982   return assumeCollectionNonEmpty(C, State, CollectionS, Assumption);
983 }
984 
985 /// If the fist block edge is a back edge, we are reentering the loop.
986 static bool alreadyExecutedAtLeastOneLoopIteration(const ExplodedNode *N,
987                                              const ObjCForCollectionStmt *FCS) {
988   if (!N)
989     return false;
990 
991   ProgramPoint P = N->getLocation();
992   if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
993     return BE->getSrc()->getLoopTarget() == FCS;
994   }
995 
996   // Keep looking for a block edge.
997   for (ExplodedNode::const_pred_iterator I = N->pred_begin(),
998                                          E = N->pred_end(); I != E; ++I) {
999     if (alreadyExecutedAtLeastOneLoopIteration(*I, FCS))
1000       return true;
1001   }
1002 
1003   return false;
1004 }
1005 
1006 void ObjCLoopChecker::checkPostStmt(const ObjCForCollectionStmt *FCS,
1007                                     CheckerContext &C) const {
1008   ProgramStateRef State = C.getState();
1009 
1010   // Check if this is the branch for the end of the loop.
1011   SVal CollectionSentinel = C.getSVal(FCS);
1012   if (CollectionSentinel.isZeroConstant()) {
1013     if (!alreadyExecutedAtLeastOneLoopIteration(C.getPredecessor(), FCS))
1014       State = assumeCollectionNonEmpty(C, State, FCS, /*Assumption*/false);
1015 
1016   // Otherwise, this is a branch that goes through the loop body.
1017   } else {
1018     State = checkCollectionNonNil(C, State, FCS);
1019     State = checkElementNonNil(C, State, FCS);
1020     State = assumeCollectionNonEmpty(C, State, FCS, /*Assumption*/true);
1021   }
1022 
1023   if (!State)
1024     C.generateSink(C.getState(), C.getPredecessor());
1025   else if (State != C.getState())
1026     C.addTransition(State);
1027 }
1028 
1029 bool ObjCLoopChecker::isCollectionCountMethod(const ObjCMethodCall &M,
1030                                               CheckerContext &C) const {
1031   Selector S = M.getSelector();
1032   // Initialize the identifiers on first use.
1033   if (!CountSelectorII)
1034     CountSelectorII = &C.getASTContext().Idents.get("count");
1035 
1036   // If the method returns collection count, record the value.
1037   return S.isUnarySelector() &&
1038          (S.getIdentifierInfoForSlot(0) == CountSelectorII);
1039 }
1040 
1041 void ObjCLoopChecker::checkPostObjCMessage(const ObjCMethodCall &M,
1042                                            CheckerContext &C) const {
1043   if (!M.isInstanceMessage())
1044     return;
1045 
1046   const ObjCInterfaceDecl *ClassID = M.getReceiverInterface();
1047   if (!ClassID)
1048     return;
1049 
1050   FoundationClass Class = findKnownClass(ClassID);
1051   if (Class != FC_NSDictionary &&
1052       Class != FC_NSArray &&
1053       Class != FC_NSSet &&
1054       Class != FC_NSOrderedSet)
1055     return;
1056 
1057   SymbolRef ContainerS = M.getReceiverSVal().getAsSymbol();
1058   if (!ContainerS)
1059     return;
1060 
1061   // If we are processing a call to "count", get the symbolic value returned by
1062   // a call to "count" and add it to the map.
1063   if (!isCollectionCountMethod(M, C))
1064     return;
1065 
1066   const Expr *MsgExpr = M.getOriginExpr();
1067   SymbolRef CountS = C.getSVal(MsgExpr).getAsSymbol();
1068   if (CountS) {
1069     ProgramStateRef State = C.getState();
1070 
1071     C.getSymbolManager().addSymbolDependency(ContainerS, CountS);
1072     State = State->set<ContainerCountMap>(ContainerS, CountS);
1073 
1074     if (const bool *NonEmpty = State->get<ContainerNonEmptyMap>(ContainerS)) {
1075       State = State->remove<ContainerNonEmptyMap>(ContainerS);
1076       State = assumeCollectionNonEmpty(C, State, ContainerS, *NonEmpty);
1077     }
1078 
1079     C.addTransition(State);
1080   }
1081 }
1082 
1083 static SymbolRef getMethodReceiverIfKnownImmutable(const CallEvent *Call) {
1084   const ObjCMethodCall *Message = dyn_cast_or_null<ObjCMethodCall>(Call);
1085   if (!Message)
1086     return nullptr;
1087 
1088   const ObjCMethodDecl *MD = Message->getDecl();
1089   if (!MD)
1090     return nullptr;
1091 
1092   const ObjCInterfaceDecl *StaticClass;
1093   if (isa<ObjCProtocolDecl>(MD->getDeclContext())) {
1094     // We can't find out where the method was declared without doing more work.
1095     // Instead, see if the receiver is statically typed as a known immutable
1096     // collection.
1097     StaticClass = Message->getOriginExpr()->getReceiverInterface();
1098   } else {
1099     StaticClass = MD->getClassInterface();
1100   }
1101 
1102   if (!StaticClass)
1103     return nullptr;
1104 
1105   switch (findKnownClass(StaticClass, /*IncludeSuper=*/false)) {
1106   case FC_None:
1107     return nullptr;
1108   case FC_NSArray:
1109   case FC_NSDictionary:
1110   case FC_NSEnumerator:
1111   case FC_NSNull:
1112   case FC_NSOrderedSet:
1113   case FC_NSSet:
1114   case FC_NSString:
1115     break;
1116   }
1117 
1118   return Message->getReceiverSVal().getAsSymbol();
1119 }
1120 
1121 ProgramStateRef
1122 ObjCLoopChecker::checkPointerEscape(ProgramStateRef State,
1123                                     const InvalidatedSymbols &Escaped,
1124                                     const CallEvent *Call,
1125                                     PointerEscapeKind Kind) const {
1126   SymbolRef ImmutableReceiver = getMethodReceiverIfKnownImmutable(Call);
1127 
1128   // Remove the invalidated symbols form the collection count map.
1129   for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
1130        E = Escaped.end();
1131        I != E; ++I) {
1132     SymbolRef Sym = *I;
1133 
1134     // Don't invalidate this symbol's count if we know the method being called
1135     // is declared on an immutable class. This isn't completely correct if the
1136     // receiver is also passed as an argument, but in most uses of NSArray,
1137     // NSDictionary, etc. this isn't likely to happen in a dangerous way.
1138     if (Sym == ImmutableReceiver)
1139       continue;
1140 
1141     // The symbol escaped. Pessimistically, assume that the count could have
1142     // changed.
1143     State = State->remove<ContainerCountMap>(Sym);
1144     State = State->remove<ContainerNonEmptyMap>(Sym);
1145   }
1146   return State;
1147 }
1148 
1149 void ObjCLoopChecker::checkDeadSymbols(SymbolReaper &SymReaper,
1150                                        CheckerContext &C) const {
1151   ProgramStateRef State = C.getState();
1152 
1153   // Remove the dead symbols from the collection count map.
1154   ContainerCountMapTy Tracked = State->get<ContainerCountMap>();
1155   for (ContainerCountMapTy::iterator I = Tracked.begin(),
1156                                      E = Tracked.end(); I != E; ++I) {
1157     SymbolRef Sym = I->first;
1158     if (SymReaper.isDead(Sym)) {
1159       State = State->remove<ContainerCountMap>(Sym);
1160       State = State->remove<ContainerNonEmptyMap>(Sym);
1161     }
1162   }
1163 
1164   C.addTransition(State);
1165 }
1166 
1167 namespace {
1168 /// \class ObjCNonNilReturnValueChecker
1169 /// \brief The checker restricts the return values of APIs known to
1170 /// never (or almost never) return 'nil'.
1171 class ObjCNonNilReturnValueChecker
1172   : public Checker<check::PostObjCMessage,
1173                    check::PostStmt<ObjCArrayLiteral>,
1174                    check::PostStmt<ObjCDictionaryLiteral>,
1175                    check::PostStmt<ObjCBoxedExpr> > {
1176     mutable bool Initialized;
1177     mutable Selector ObjectAtIndex;
1178     mutable Selector ObjectAtIndexedSubscript;
1179     mutable Selector NullSelector;
1180 
1181 public:
1182   ObjCNonNilReturnValueChecker() : Initialized(false) {}
1183 
1184   ProgramStateRef assumeExprIsNonNull(const Expr *NonNullExpr,
1185                                       ProgramStateRef State,
1186                                       CheckerContext &C) const;
1187   void assumeExprIsNonNull(const Expr *E, CheckerContext &C) const {
1188     C.addTransition(assumeExprIsNonNull(E, C.getState(), C));
1189   }
1190 
1191   void checkPostStmt(const ObjCArrayLiteral *E, CheckerContext &C) const {
1192     assumeExprIsNonNull(E, C);
1193   }
1194   void checkPostStmt(const ObjCDictionaryLiteral *E, CheckerContext &C) const {
1195     assumeExprIsNonNull(E, C);
1196   }
1197   void checkPostStmt(const ObjCBoxedExpr *E, CheckerContext &C) const {
1198     assumeExprIsNonNull(E, C);
1199   }
1200 
1201   void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
1202 };
1203 } // end anonymous namespace
1204 
1205 ProgramStateRef
1206 ObjCNonNilReturnValueChecker::assumeExprIsNonNull(const Expr *NonNullExpr,
1207                                                   ProgramStateRef State,
1208                                                   CheckerContext &C) const {
1209   SVal Val = State->getSVal(NonNullExpr, C.getLocationContext());
1210   if (Optional<DefinedOrUnknownSVal> DV = Val.getAs<DefinedOrUnknownSVal>())
1211     return State->assume(*DV, true);
1212   return State;
1213 }
1214 
1215 void ObjCNonNilReturnValueChecker::checkPostObjCMessage(const ObjCMethodCall &M,
1216                                                         CheckerContext &C)
1217                                                         const {
1218   ProgramStateRef State = C.getState();
1219 
1220   if (!Initialized) {
1221     ASTContext &Ctx = C.getASTContext();
1222     ObjectAtIndex = GetUnarySelector("objectAtIndex", Ctx);
1223     ObjectAtIndexedSubscript = GetUnarySelector("objectAtIndexedSubscript", Ctx);
1224     NullSelector = GetNullarySelector("null", Ctx);
1225   }
1226 
1227   // Check the receiver type.
1228   if (const ObjCInterfaceDecl *Interface = M.getReceiverInterface()) {
1229 
1230     // Assume that object returned from '[self init]' or '[super init]' is not
1231     // 'nil' if we are processing an inlined function/method.
1232     //
1233     // A defensive callee will (and should) check if the object returned by
1234     // '[super init]' is 'nil' before doing it's own initialization. However,
1235     // since 'nil' is rarely returned in practice, we should not warn when the
1236     // caller to the defensive constructor uses the object in contexts where
1237     // 'nil' is not accepted.
1238     if (!C.inTopFrame() && M.getDecl() &&
1239         M.getDecl()->getMethodFamily() == OMF_init &&
1240         M.isReceiverSelfOrSuper()) {
1241       State = assumeExprIsNonNull(M.getOriginExpr(), State, C);
1242     }
1243 
1244     FoundationClass Cl = findKnownClass(Interface);
1245 
1246     // Objects returned from
1247     // [NSArray|NSOrderedSet]::[ObjectAtIndex|ObjectAtIndexedSubscript]
1248     // are never 'nil'.
1249     if (Cl == FC_NSArray || Cl == FC_NSOrderedSet) {
1250       Selector Sel = M.getSelector();
1251       if (Sel == ObjectAtIndex || Sel == ObjectAtIndexedSubscript) {
1252         // Go ahead and assume the value is non-nil.
1253         State = assumeExprIsNonNull(M.getOriginExpr(), State, C);
1254       }
1255     }
1256 
1257     // Objects returned from [NSNull null] are not nil.
1258     if (Cl == FC_NSNull) {
1259       if (M.getSelector() == NullSelector) {
1260         // Go ahead and assume the value is non-nil.
1261         State = assumeExprIsNonNull(M.getOriginExpr(), State, C);
1262       }
1263     }
1264   }
1265   C.addTransition(State);
1266 }
1267 
1268 //===----------------------------------------------------------------------===//
1269 // Check registration.
1270 //===----------------------------------------------------------------------===//
1271 
1272 void ento::registerNilArgChecker(CheckerManager &mgr) {
1273   mgr.registerChecker<NilArgChecker>();
1274 }
1275 
1276 void ento::registerCFNumberChecker(CheckerManager &mgr) {
1277   mgr.registerChecker<CFNumberChecker>();
1278 }
1279 
1280 void ento::registerCFRetainReleaseChecker(CheckerManager &mgr) {
1281   mgr.registerChecker<CFRetainReleaseChecker>();
1282 }
1283 
1284 void ento::registerClassReleaseChecker(CheckerManager &mgr) {
1285   mgr.registerChecker<ClassReleaseChecker>();
1286 }
1287 
1288 void ento::registerVariadicMethodTypeChecker(CheckerManager &mgr) {
1289   mgr.registerChecker<VariadicMethodTypeChecker>();
1290 }
1291 
1292 void ento::registerObjCLoopChecker(CheckerManager &mgr) {
1293   mgr.registerChecker<ObjCLoopChecker>();
1294 }
1295 
1296 void
1297 ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
1298   mgr.registerChecker<ObjCNonNilReturnValueChecker>();
1299 }
1300