1//===-- NullabilityChecker.cpp - Nullability checker ----------------------===//
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 checker tries to find nullability violations. There are several kinds of
10// possible violations:
11// * Null pointer is passed to a pointer which has a _Nonnull type.
12// * Null pointer is returned from a function which has a _Nonnull return type.
13// * Nullable pointer is passed to a pointer which has a _Nonnull type.
14// * Nullable pointer is returned from a function which has a _Nonnull return
15//   type.
16// * Nullable pointer is dereferenced.
17//
18// This checker propagates the nullability information of the pointers and looks
19// for the patterns that are described above. Explicit casts are trusted and are
20// considered a way to suppress false positives for this checker. The other way
21// to suppress warnings would be to add asserts or guarding if statements to the
22// code. In addition to the nullability propagation this checker also uses some
23// heuristics to suppress potential false positives.
24//
25//===----------------------------------------------------------------------===//
26
27#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
28
29#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
30#include "clang/StaticAnalyzer/Core/Checker.h"
31#include "clang/StaticAnalyzer/Core/CheckerManager.h"
32#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
33#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
34#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
35
36#include "llvm/ADT/StringExtras.h"
37#include "llvm/Support/Path.h"
38
39using namespace clang;
40using namespace ento;
41
42namespace {
43
44/// Returns the most nullable nullability. This is used for message expressions
45/// like [receiver method], where the nullability of this expression is either
46/// the nullability of the receiver or the nullability of the return type of the
47/// method, depending on which is more nullable. Contradicted is considered to
48/// be the most nullable, to avoid false positive results.
49Nullability getMostNullable(Nullability Lhs, Nullability Rhs) {
50  return static_cast<Nullability>(
51      std::min(static_cast<char>(Lhs), static_cast<char>(Rhs)));
52}
53
54const char *getNullabilityString(Nullability Nullab) {
55  switch (Nullab) {
56  case Nullability::Contradicted:
57    return "contradicted";
58  case Nullability::Nullable:
59    return "nullable";
60  case Nullability::Unspecified:
61    return "unspecified";
62  case Nullability::Nonnull:
63    return "nonnull";
64  }
65  llvm_unreachable("Unexpected enumeration.");
66  return "";
67}
68
69// These enums are used as an index to ErrorMessages array.
70enum class ErrorKind : int {
71  NilAssignedToNonnull,
72  NilPassedToNonnull,
73  NilReturnedToNonnull,
74  NullableAssignedToNonnull,
75  NullableReturnedToNonnull,
76  NullableDereferenced,
77  NullablePassedToNonnull
78};
79
80class NullabilityChecker
81    : public Checker<check::Bind, check::PreCall, check::PreStmt<ReturnStmt>,
82                     check::PostCall, check::PostStmt<ExplicitCastExpr>,
83                     check::PostObjCMessage, check::DeadSymbols,
84                     check::Location, check::Event<ImplicitNullDerefEvent>> {
85
86public:
87  // If true, the checker will not diagnose nullabilility issues for calls
88  // to system headers. This option is motivated by the observation that large
89  // projects may have many nullability warnings. These projects may
90  // find warnings about nullability annotations that they have explicitly
91  // added themselves higher priority to fix than warnings on calls to system
92  // libraries.
93  DefaultBool NoDiagnoseCallsToSystemHeaders;
94
95  void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
96  void checkPostStmt(const ExplicitCastExpr *CE, CheckerContext &C) const;
97  void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
98  void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
99  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
100  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
101  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
102  void checkEvent(ImplicitNullDerefEvent Event) const;
103  void checkLocation(SVal Location, bool IsLoad, const Stmt *S,
104                     CheckerContext &C) const;
105
106  void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
107                  const char *Sep) const override;
108
109  enum CheckKind {
110    CK_NullPassedToNonnull,
111    CK_NullReturnedFromNonnull,
112    CK_NullableDereferenced,
113    CK_NullablePassedToNonnull,
114    CK_NullableReturnedFromNonnull,
115    CK_NumCheckKinds
116  };
117
118  DefaultBool ChecksEnabled[CK_NumCheckKinds];
119  CheckerNameRef CheckNames[CK_NumCheckKinds];
120  mutable std::unique_ptr<BugType> BTs[CK_NumCheckKinds];
121
122  const std::unique_ptr<BugType> &getBugType(CheckKind Kind) const {
123    if (!BTs[Kind])
124      BTs[Kind].reset(new BugType(CheckNames[Kind], "Nullability",
125                                  categories::MemoryError));
126    return BTs[Kind];
127  }
128
129  // When set to false no nullability information will be tracked in
130  // NullabilityMap. It is possible to catch errors like passing a null pointer
131  // to a callee that expects nonnull argument without the information that is
132  // stroed in the NullabilityMap. This is an optimization.
133  DefaultBool NeedTracking;
134
135private:
136  class NullabilityBugVisitor : public BugReporterVisitor {
137  public:
138    NullabilityBugVisitor(const MemRegion *M) : Region(M) {}
139
140    void Profile(llvm::FoldingSetNodeID &ID) const override {
141      static int X = 0;
142      ID.AddPointer(&X);
143      ID.AddPointer(Region);
144    }
145
146    PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
147                                     BugReporterContext &BRC,
148                                     PathSensitiveBugReport &BR) override;
149
150  private:
151    // The tracked region.
152    const MemRegion *Region;
153  };
154
155  /// When any of the nonnull arguments of the analyzed function is null, do not
156  /// report anything and turn off the check.
157  ///
158  /// When \p SuppressPath is set to true, no more bugs will be reported on this
159  /// path by this checker.
160  void reportBugIfInvariantHolds(StringRef Msg, ErrorKind Error, CheckKind CK,
161                                 ExplodedNode *N, const MemRegion *Region,
162                                 CheckerContext &C,
163                                 const Stmt *ValueExpr = nullptr,
164                                 bool SuppressPath = false) const;
165
166  void reportBug(StringRef Msg, ErrorKind Error, CheckKind CK, ExplodedNode *N,
167                 const MemRegion *Region, BugReporter &BR,
168                 const Stmt *ValueExpr = nullptr) const {
169    const std::unique_ptr<BugType> &BT = getBugType(CK);
170    auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
171    if (Region) {
172      R->markInteresting(Region);
173      R->addVisitor(std::make_unique<NullabilityBugVisitor>(Region));
174    }
175    if (ValueExpr) {
176      R->addRange(ValueExpr->getSourceRange());
177      if (Error == ErrorKind::NilAssignedToNonnull ||
178          Error == ErrorKind::NilPassedToNonnull ||
179          Error == ErrorKind::NilReturnedToNonnull)
180        if (const auto *Ex = dyn_cast<Expr>(ValueExpr))
181          bugreporter::trackExpressionValue(N, Ex, *R);
182    }
183    BR.emitReport(std::move(R));
184  }
185
186  /// If an SVal wraps a region that should be tracked, it will return a pointer
187  /// to the wrapped region. Otherwise it will return a nullptr.
188  const SymbolicRegion *getTrackRegion(SVal Val,
189                                       bool CheckSuperRegion = false) const;
190
191  /// Returns true if the call is diagnosable in the current analyzer
192  /// configuration.
193  bool isDiagnosableCall(const CallEvent &Call) const {
194    if (NoDiagnoseCallsToSystemHeaders && Call.isInSystemHeader())
195      return false;
196
197    return true;
198  }
199};
200
201class NullabilityState {
202public:
203  NullabilityState(Nullability Nullab, const Stmt *Source = nullptr)
204      : Nullab(Nullab), Source(Source) {}
205
206  const Stmt *getNullabilitySource() const { return Source; }
207
208  Nullability getValue() const { return Nullab; }
209
210  void Profile(llvm::FoldingSetNodeID &ID) const {
211    ID.AddInteger(static_cast<char>(Nullab));
212    ID.AddPointer(Source);
213  }
214
215  void print(raw_ostream &Out) const {
216    Out << getNullabilityString(Nullab) << "\n";
217  }
218
219private:
220  Nullability Nullab;
221  // Source is the expression which determined the nullability. For example in a
222  // message like [nullable nonnull_returning] has nullable nullability, because
223  // the receiver is nullable. Here the receiver will be the source of the
224  // nullability. This is useful information when the diagnostics are generated.
225  const Stmt *Source;
226};
227
228bool operator==(NullabilityState Lhs, NullabilityState Rhs) {
229  return Lhs.getValue() == Rhs.getValue() &&
230         Lhs.getNullabilitySource() == Rhs.getNullabilitySource();
231}
232
233} // end anonymous namespace
234
235REGISTER_MAP_WITH_PROGRAMSTATE(NullabilityMap, const MemRegion *,
236                               NullabilityState)
237
238// We say "the nullability type invariant is violated" when a location with a
239// non-null type contains NULL or a function with a non-null return type returns
240// NULL. Violations of the nullability type invariant can be detected either
241// directly (for example, when NULL is passed as an argument to a nonnull
242// parameter) or indirectly (for example, when, inside a function, the
243// programmer defensively checks whether a nonnull parameter contains NULL and
244// finds that it does).
245//
246// As a matter of policy, the nullability checker typically warns on direct
247// violations of the nullability invariant (although it uses various
248// heuristics to suppress warnings in some cases) but will not warn if the
249// invariant has already been violated along the path (either directly or
250// indirectly). As a practical matter, this prevents the analyzer from
251// (1) warning on defensive code paths where a nullability precondition is
252// determined to have been violated, (2) warning additional times after an
253// initial direct violation has been discovered, and (3) warning after a direct
254// violation that has been implicitly or explicitly suppressed (for
255// example, with a cast of NULL to _Nonnull). In essence, once an invariant
256// violation is detected on a path, this checker will be essentially turned off
257// for the rest of the analysis
258//
259// The analyzer takes this approach (rather than generating a sink node) to
260// ensure coverage of defensive paths, which may be important for backwards
261// compatibility in codebases that were developed without nullability in mind.
262REGISTER_TRAIT_WITH_PROGRAMSTATE(InvariantViolated, bool)
263
264enum class NullConstraint { IsNull, IsNotNull, Unknown };
265
266static NullConstraint getNullConstraint(DefinedOrUnknownSVal Val,
267                                        ProgramStateRef State) {
268  ConditionTruthVal Nullness = State->isNull(Val);
269  if (Nullness.isConstrainedFalse())
270    return NullConstraint::IsNotNull;
271  if (Nullness.isConstrainedTrue())
272    return NullConstraint::IsNull;
273  return NullConstraint::Unknown;
274}
275
276const SymbolicRegion *
277NullabilityChecker::getTrackRegion(SVal Val, bool CheckSuperRegion) const {
278  if (!NeedTracking)
279    return nullptr;
280
281  auto RegionSVal = Val.getAs<loc::MemRegionVal>();
282  if (!RegionSVal)
283    return nullptr;
284
285  const MemRegion *Region = RegionSVal->getRegion();
286
287  if (CheckSuperRegion) {
288    if (auto FieldReg = Region->getAs<FieldRegion>())
289      return dyn_cast<SymbolicRegion>(FieldReg->getSuperRegion());
290    if (auto ElementReg = Region->getAs<ElementRegion>())
291      return dyn_cast<SymbolicRegion>(ElementReg->getSuperRegion());
292  }
293
294  return dyn_cast<SymbolicRegion>(Region);
295}
296
297PathDiagnosticPieceRef NullabilityChecker::NullabilityBugVisitor::VisitNode(
298    const ExplodedNode *N, BugReporterContext &BRC,
299    PathSensitiveBugReport &BR) {
300  ProgramStateRef State = N->getState();
301  ProgramStateRef StatePrev = N->getFirstPred()->getState();
302
303  const NullabilityState *TrackedNullab = State->get<NullabilityMap>(Region);
304  const NullabilityState *TrackedNullabPrev =
305      StatePrev->get<NullabilityMap>(Region);
306  if (!TrackedNullab)
307    return nullptr;
308
309  if (TrackedNullabPrev &&
310      TrackedNullabPrev->getValue() == TrackedNullab->getValue())
311    return nullptr;
312
313  // Retrieve the associated statement.
314  const Stmt *S = TrackedNullab->getNullabilitySource();
315  if (!S || S->getBeginLoc().isInvalid()) {
316    S = N->getStmtForDiagnostics();
317  }
318
319  if (!S)
320    return nullptr;
321
322  std::string InfoText =
323      (llvm::Twine("Nullability '") +
324       getNullabilityString(TrackedNullab->getValue()) + "' is inferred")
325          .str();
326
327  // Generate the extra diagnostic.
328  PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
329                             N->getLocationContext());
330  return std::make_shared<PathDiagnosticEventPiece>(Pos, InfoText, true);
331}
332
333/// Returns true when the value stored at the given location has been
334/// constrained to null after being passed through an object of nonnnull type.
335static bool checkValueAtLValForInvariantViolation(ProgramStateRef State,
336                                                  SVal LV, QualType T) {
337  if (getNullabilityAnnotation(T) != Nullability::Nonnull)
338    return false;
339
340  auto RegionVal = LV.getAs<loc::MemRegionVal>();
341  if (!RegionVal)
342    return false;
343
344  // If the value was constrained to null *after* it was passed through that
345  // location, it could not have been a concrete pointer *when* it was passed.
346  // In that case we would have handled the situation when the value was
347  // bound to that location, by emitting (or not emitting) a report.
348  // Therefore we are only interested in symbolic regions that can be either
349  // null or non-null depending on the value of their respective symbol.
350  auto StoredVal = State->getSVal(*RegionVal).getAs<loc::MemRegionVal>();
351  if (!StoredVal || !isa<SymbolicRegion>(StoredVal->getRegion()))
352    return false;
353
354  if (getNullConstraint(*StoredVal, State) == NullConstraint::IsNull)
355    return true;
356
357  return false;
358}
359
360static bool
361checkParamsForPreconditionViolation(ArrayRef<ParmVarDecl *> Params,
362                                    ProgramStateRef State,
363                                    const LocationContext *LocCtxt) {
364  for (const auto *ParamDecl : Params) {
365    if (ParamDecl->isParameterPack())
366      break;
367
368    SVal LV = State->getLValue(ParamDecl, LocCtxt);
369    if (checkValueAtLValForInvariantViolation(State, LV,
370                                              ParamDecl->getType())) {
371      return true;
372    }
373  }
374  return false;
375}
376
377static bool
378checkSelfIvarsForInvariantViolation(ProgramStateRef State,
379                                    const LocationContext *LocCtxt) {
380  auto *MD = dyn_cast<ObjCMethodDecl>(LocCtxt->getDecl());
381  if (!MD || !MD->isInstanceMethod())
382    return false;
383
384  const ImplicitParamDecl *SelfDecl = LocCtxt->getSelfDecl();
385  if (!SelfDecl)
386    return false;
387
388  SVal SelfVal = State->getSVal(State->getRegion(SelfDecl, LocCtxt));
389
390  const ObjCObjectPointerType *SelfType =
391      dyn_cast<ObjCObjectPointerType>(SelfDecl->getType());
392  if (!SelfType)
393    return false;
394
395  const ObjCInterfaceDecl *ID = SelfType->getInterfaceDecl();
396  if (!ID)
397    return false;
398
399  for (const auto *IvarDecl : ID->ivars()) {
400    SVal LV = State->getLValue(IvarDecl, SelfVal);
401    if (checkValueAtLValForInvariantViolation(State, LV, IvarDecl->getType())) {
402      return true;
403    }
404  }
405  return false;
406}
407
408static bool checkInvariantViolation(ProgramStateRef State, ExplodedNode *N,
409                                    CheckerContext &C) {
410  if (State->get<InvariantViolated>())
411    return true;
412
413  const LocationContext *LocCtxt = C.getLocationContext();
414  const Decl *D = LocCtxt->getDecl();
415  if (!D)
416    return false;
417
418  ArrayRef<ParmVarDecl*> Params;
419  if (const auto *BD = dyn_cast<BlockDecl>(D))
420    Params = BD->parameters();
421  else if (const auto *FD = dyn_cast<FunctionDecl>(D))
422    Params = FD->parameters();
423  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
424    Params = MD->parameters();
425  else
426    return false;
427
428  if (checkParamsForPreconditionViolation(Params, State, LocCtxt) ||
429      checkSelfIvarsForInvariantViolation(State, LocCtxt)) {
430    if (!N->isSink())
431      C.addTransition(State->set<InvariantViolated>(true), N);
432    return true;
433  }
434  return false;
435}
436
437void NullabilityChecker::reportBugIfInvariantHolds(
438    StringRef Msg, ErrorKind Error, CheckKind CK, ExplodedNode *N,
439    const MemRegion *Region, CheckerContext &C, const Stmt *ValueExpr,
440    bool SuppressPath) const {
441  ProgramStateRef OriginalState = N->getState();
442
443  if (checkInvariantViolation(OriginalState, N, C))
444    return;
445  if (SuppressPath) {
446    OriginalState = OriginalState->set<InvariantViolated>(true);
447    N = C.addTransition(OriginalState, N);
448  }
449
450  reportBug(Msg, Error, CK, N, Region, C.getBugReporter(), ValueExpr);
451}
452
453/// Cleaning up the program state.
454void NullabilityChecker::checkDeadSymbols(SymbolReaper &SR,
455                                          CheckerContext &C) const {
456  ProgramStateRef State = C.getState();
457  NullabilityMapTy Nullabilities = State->get<NullabilityMap>();
458  for (NullabilityMapTy::iterator I = Nullabilities.begin(),
459                                  E = Nullabilities.end();
460       I != E; ++I) {
461    const auto *Region = I->first->getAs<SymbolicRegion>();
462    assert(Region && "Non-symbolic region is tracked.");
463    if (SR.isDead(Region->getSymbol())) {
464      State = State->remove<NullabilityMap>(I->first);
465    }
466  }
467  // When one of the nonnull arguments are constrained to be null, nullability
468  // preconditions are violated. It is not enough to check this only when we
469  // actually report an error, because at that time interesting symbols might be
470  // reaped.
471  if (checkInvariantViolation(State, C.getPredecessor(), C))
472    return;
473  C.addTransition(State);
474}
475
476/// This callback triggers when a pointer is dereferenced and the analyzer does
477/// not know anything about the value of that pointer. When that pointer is
478/// nullable, this code emits a warning.
479void NullabilityChecker::checkEvent(ImplicitNullDerefEvent Event) const {
480  if (Event.SinkNode->getState()->get<InvariantViolated>())
481    return;
482
483  const MemRegion *Region =
484      getTrackRegion(Event.Location, /*CheckSuperRegion=*/true);
485  if (!Region)
486    return;
487
488  ProgramStateRef State = Event.SinkNode->getState();
489  const NullabilityState *TrackedNullability =
490      State->get<NullabilityMap>(Region);
491
492  if (!TrackedNullability)
493    return;
494
495  if (ChecksEnabled[CK_NullableDereferenced] &&
496      TrackedNullability->getValue() == Nullability::Nullable) {
497    BugReporter &BR = *Event.BR;
498    // Do not suppress errors on defensive code paths, because dereferencing
499    // a nullable pointer is always an error.
500    if (Event.IsDirectDereference)
501      reportBug("Nullable pointer is dereferenced",
502                ErrorKind::NullableDereferenced, CK_NullableDereferenced,
503                Event.SinkNode, Region, BR);
504    else {
505      reportBug("Nullable pointer is passed to a callee that requires a "
506                "non-null",
507                ErrorKind::NullablePassedToNonnull, CK_NullableDereferenced,
508                Event.SinkNode, Region, BR);
509    }
510  }
511}
512
513// Whenever we see a load from a typed memory region that's been annotated as
514// 'nonnull', we want to trust the user on that and assume that it is is indeed
515// non-null.
516//
517// We do so even if the value is known to have been assigned to null.
518// The user should be warned on assigning the null value to a non-null pointer
519// as opposed to warning on the later dereference of this pointer.
520//
521// \code
522//   int * _Nonnull var = 0; // we want to warn the user here...
523//   // . . .
524//   *var = 42;              // ...and not here
525// \endcode
526void NullabilityChecker::checkLocation(SVal Location, bool IsLoad,
527                                       const Stmt *S,
528                                       CheckerContext &Context) const {
529  // We should care only about loads.
530  // The main idea is to add a constraint whenever we're loading a value from
531  // an annotated pointer type.
532  if (!IsLoad)
533    return;
534
535  // Annotations that we want to consider make sense only for types.
536  const auto *Region =
537      dyn_cast_or_null<TypedValueRegion>(Location.getAsRegion());
538  if (!Region)
539    return;
540
541  ProgramStateRef State = Context.getState();
542
543  auto StoredVal = State->getSVal(Region).getAs<loc::MemRegionVal>();
544  if (!StoredVal)
545    return;
546
547  Nullability NullabilityOfTheLoadedValue =
548      getNullabilityAnnotation(Region->getValueType());
549
550  if (NullabilityOfTheLoadedValue == Nullability::Nonnull) {
551    // It doesn't matter what we think about this particular pointer, it should
552    // be considered non-null as annotated by the developer.
553    if (ProgramStateRef NewState = State->assume(*StoredVal, true)) {
554      Context.addTransition(NewState);
555    }
556  }
557}
558
559/// Find the outermost subexpression of E that is not an implicit cast.
560/// This looks through the implicit casts to _Nonnull that ARC adds to
561/// return expressions of ObjC types when the return type of the function or
562/// method is non-null but the express is not.
563static const Expr *lookThroughImplicitCasts(const Expr *E) {
564  return E->IgnoreImpCasts();
565}
566
567/// This method check when nullable pointer or null value is returned from a
568/// function that has nonnull return type.
569void NullabilityChecker::checkPreStmt(const ReturnStmt *S,
570                                      CheckerContext &C) const {
571  auto RetExpr = S->getRetValue();
572  if (!RetExpr)
573    return;
574
575  if (!RetExpr->getType()->isAnyPointerType())
576    return;
577
578  ProgramStateRef State = C.getState();
579  if (State->get<InvariantViolated>())
580    return;
581
582  auto RetSVal = C.getSVal(S).getAs<DefinedOrUnknownSVal>();
583  if (!RetSVal)
584    return;
585
586  bool InSuppressedMethodFamily = false;
587
588  QualType RequiredRetType;
589  AnalysisDeclContext *DeclCtxt =
590      C.getLocationContext()->getAnalysisDeclContext();
591  const Decl *D = DeclCtxt->getDecl();
592  if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
593    // HACK: This is a big hammer to avoid warning when there are defensive
594    // nil checks in -init and -copy methods. We should add more sophisticated
595    // logic here to suppress on common defensive idioms but still
596    // warn when there is a likely problem.
597    ObjCMethodFamily Family = MD->getMethodFamily();
598    if (OMF_init == Family || OMF_copy == Family || OMF_mutableCopy == Family)
599      InSuppressedMethodFamily = true;
600
601    RequiredRetType = MD->getReturnType();
602  } else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
603    RequiredRetType = FD->getReturnType();
604  } else {
605    return;
606  }
607
608  NullConstraint Nullness = getNullConstraint(*RetSVal, State);
609
610  Nullability RequiredNullability = getNullabilityAnnotation(RequiredRetType);
611
612  // If the returned value is null but the type of the expression
613  // generating it is nonnull then we will suppress the diagnostic.
614  // This enables explicit suppression when returning a nil literal in a
615  // function with a _Nonnull return type:
616  //    return (NSString * _Nonnull)0;
617  Nullability RetExprTypeLevelNullability =
618        getNullabilityAnnotation(lookThroughImplicitCasts(RetExpr)->getType());
619
620  bool NullReturnedFromNonNull = (RequiredNullability == Nullability::Nonnull &&
621                                  Nullness == NullConstraint::IsNull);
622  if (ChecksEnabled[CK_NullReturnedFromNonnull] && NullReturnedFromNonNull &&
623      RetExprTypeLevelNullability != Nullability::Nonnull &&
624      !InSuppressedMethodFamily && C.getLocationContext()->inTopFrame()) {
625    static CheckerProgramPointTag Tag(this, "NullReturnedFromNonnull");
626    ExplodedNode *N = C.generateErrorNode(State, &Tag);
627    if (!N)
628      return;
629
630    SmallString<256> SBuf;
631    llvm::raw_svector_ostream OS(SBuf);
632    OS << (RetExpr->getType()->isObjCObjectPointerType() ? "nil" : "Null");
633    OS << " returned from a " << C.getDeclDescription(D) <<
634          " that is expected to return a non-null value";
635    reportBugIfInvariantHolds(OS.str(), ErrorKind::NilReturnedToNonnull,
636                              CK_NullReturnedFromNonnull, N, nullptr, C,
637                              RetExpr);
638    return;
639  }
640
641  // If null was returned from a non-null function, mark the nullability
642  // invariant as violated even if the diagnostic was suppressed.
643  if (NullReturnedFromNonNull) {
644    State = State->set<InvariantViolated>(true);
645    C.addTransition(State);
646    return;
647  }
648
649  const MemRegion *Region = getTrackRegion(*RetSVal);
650  if (!Region)
651    return;
652
653  const NullabilityState *TrackedNullability =
654      State->get<NullabilityMap>(Region);
655  if (TrackedNullability) {
656    Nullability TrackedNullabValue = TrackedNullability->getValue();
657    if (ChecksEnabled[CK_NullableReturnedFromNonnull] &&
658        Nullness != NullConstraint::IsNotNull &&
659        TrackedNullabValue == Nullability::Nullable &&
660        RequiredNullability == Nullability::Nonnull) {
661      static CheckerProgramPointTag Tag(this, "NullableReturnedFromNonnull");
662      ExplodedNode *N = C.addTransition(State, C.getPredecessor(), &Tag);
663
664      SmallString<256> SBuf;
665      llvm::raw_svector_ostream OS(SBuf);
666      OS << "Nullable pointer is returned from a " << C.getDeclDescription(D) <<
667            " that is expected to return a non-null value";
668
669      reportBugIfInvariantHolds(OS.str(), ErrorKind::NullableReturnedToNonnull,
670                                CK_NullableReturnedFromNonnull, N, Region, C);
671    }
672    return;
673  }
674  if (RequiredNullability == Nullability::Nullable) {
675    State = State->set<NullabilityMap>(Region,
676                                       NullabilityState(RequiredNullability,
677                                                        S));
678    C.addTransition(State);
679  }
680}
681
682/// This callback warns when a nullable pointer or a null value is passed to a
683/// function that expects its argument to be nonnull.
684void NullabilityChecker::checkPreCall(const CallEvent &Call,
685                                      CheckerContext &C) const {
686  if (!Call.getDecl())
687    return;
688
689  ProgramStateRef State = C.getState();
690  if (State->get<InvariantViolated>())
691    return;
692
693  ProgramStateRef OrigState = State;
694
695  unsigned Idx = 0;
696  for (const ParmVarDecl *Param : Call.parameters()) {
697    if (Param->isParameterPack())
698      break;
699
700    if (Idx >= Call.getNumArgs())
701      break;
702
703    const Expr *ArgExpr = Call.getArgExpr(Idx);
704    auto ArgSVal = Call.getArgSVal(Idx++).getAs<DefinedOrUnknownSVal>();
705    if (!ArgSVal)
706      continue;
707
708    if (!Param->getType()->isAnyPointerType() &&
709        !Param->getType()->isReferenceType())
710      continue;
711
712    NullConstraint Nullness = getNullConstraint(*ArgSVal, State);
713
714    Nullability RequiredNullability =
715        getNullabilityAnnotation(Param->getType());
716    Nullability ArgExprTypeLevelNullability =
717        getNullabilityAnnotation(ArgExpr->getType());
718
719    unsigned ParamIdx = Param->getFunctionScopeIndex() + 1;
720
721    if (ChecksEnabled[CK_NullPassedToNonnull] &&
722        Nullness == NullConstraint::IsNull &&
723        ArgExprTypeLevelNullability != Nullability::Nonnull &&
724        RequiredNullability == Nullability::Nonnull &&
725        isDiagnosableCall(Call)) {
726      ExplodedNode *N = C.generateErrorNode(State);
727      if (!N)
728        return;
729
730      SmallString<256> SBuf;
731      llvm::raw_svector_ostream OS(SBuf);
732      OS << (Param->getType()->isObjCObjectPointerType() ? "nil" : "Null");
733      OS << " passed to a callee that requires a non-null " << ParamIdx
734         << llvm::getOrdinalSuffix(ParamIdx) << " parameter";
735      reportBugIfInvariantHolds(OS.str(), ErrorKind::NilPassedToNonnull,
736                                CK_NullPassedToNonnull, N, nullptr, C, ArgExpr,
737                                /*SuppressPath=*/false);
738      return;
739    }
740
741    const MemRegion *Region = getTrackRegion(*ArgSVal);
742    if (!Region)
743      continue;
744
745    const NullabilityState *TrackedNullability =
746        State->get<NullabilityMap>(Region);
747
748    if (TrackedNullability) {
749      if (Nullness == NullConstraint::IsNotNull ||
750          TrackedNullability->getValue() != Nullability::Nullable)
751        continue;
752
753      if (ChecksEnabled[CK_NullablePassedToNonnull] &&
754          RequiredNullability == Nullability::Nonnull &&
755          isDiagnosableCall(Call)) {
756        ExplodedNode *N = C.addTransition(State);
757        SmallString<256> SBuf;
758        llvm::raw_svector_ostream OS(SBuf);
759        OS << "Nullable pointer is passed to a callee that requires a non-null "
760           << ParamIdx << llvm::getOrdinalSuffix(ParamIdx) << " parameter";
761        reportBugIfInvariantHolds(OS.str(), ErrorKind::NullablePassedToNonnull,
762                                  CK_NullablePassedToNonnull, N, Region, C,
763                                  ArgExpr, /*SuppressPath=*/true);
764        return;
765      }
766      if (ChecksEnabled[CK_NullableDereferenced] &&
767          Param->getType()->isReferenceType()) {
768        ExplodedNode *N = C.addTransition(State);
769        reportBugIfInvariantHolds("Nullable pointer is dereferenced",
770                                  ErrorKind::NullableDereferenced,
771                                  CK_NullableDereferenced, N, Region, C,
772                                  ArgExpr, /*SuppressPath=*/true);
773        return;
774      }
775      continue;
776    }
777  }
778  if (State != OrigState)
779    C.addTransition(State);
780}
781
782/// Suppress the nullability warnings for some functions.
783void NullabilityChecker::checkPostCall(const CallEvent &Call,
784                                       CheckerContext &C) const {
785  auto Decl = Call.getDecl();
786  if (!Decl)
787    return;
788  // ObjC Messages handles in a different callback.
789  if (Call.getKind() == CE_ObjCMessage)
790    return;
791  const FunctionType *FuncType = Decl->getFunctionType();
792  if (!FuncType)
793    return;
794  QualType ReturnType = FuncType->getReturnType();
795  if (!ReturnType->isAnyPointerType())
796    return;
797  ProgramStateRef State = C.getState();
798  if (State->get<InvariantViolated>())
799    return;
800
801  const MemRegion *Region = getTrackRegion(Call.getReturnValue());
802  if (!Region)
803    return;
804
805  // CG headers are misannotated. Do not warn for symbols that are the results
806  // of CG calls.
807  const SourceManager &SM = C.getSourceManager();
808  StringRef FilePath = SM.getFilename(SM.getSpellingLoc(Decl->getBeginLoc()));
809  if (llvm::sys::path::filename(FilePath).startswith("CG")) {
810    State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
811    C.addTransition(State);
812    return;
813  }
814
815  const NullabilityState *TrackedNullability =
816      State->get<NullabilityMap>(Region);
817
818  if (!TrackedNullability &&
819      getNullabilityAnnotation(ReturnType) == Nullability::Nullable) {
820    State = State->set<NullabilityMap>(Region, Nullability::Nullable);
821    C.addTransition(State);
822  }
823}
824
825static Nullability getReceiverNullability(const ObjCMethodCall &M,
826                                          ProgramStateRef State) {
827  if (M.isReceiverSelfOrSuper()) {
828    // For super and super class receivers we assume that the receiver is
829    // nonnull.
830    return Nullability::Nonnull;
831  }
832  // Otherwise look up nullability in the state.
833  SVal Receiver = M.getReceiverSVal();
834  if (auto DefOrUnknown = Receiver.getAs<DefinedOrUnknownSVal>()) {
835    // If the receiver is constrained to be nonnull, assume that it is nonnull
836    // regardless of its type.
837    NullConstraint Nullness = getNullConstraint(*DefOrUnknown, State);
838    if (Nullness == NullConstraint::IsNotNull)
839      return Nullability::Nonnull;
840  }
841  auto ValueRegionSVal = Receiver.getAs<loc::MemRegionVal>();
842  if (ValueRegionSVal) {
843    const MemRegion *SelfRegion = ValueRegionSVal->getRegion();
844    assert(SelfRegion);
845
846    const NullabilityState *TrackedSelfNullability =
847        State->get<NullabilityMap>(SelfRegion);
848    if (TrackedSelfNullability)
849      return TrackedSelfNullability->getValue();
850  }
851  return Nullability::Unspecified;
852}
853
854/// Calculate the nullability of the result of a message expr based on the
855/// nullability of the receiver, the nullability of the return value, and the
856/// constraints.
857void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M,
858                                              CheckerContext &C) const {
859  auto Decl = M.getDecl();
860  if (!Decl)
861    return;
862  QualType RetType = Decl->getReturnType();
863  if (!RetType->isAnyPointerType())
864    return;
865
866  ProgramStateRef State = C.getState();
867  if (State->get<InvariantViolated>())
868    return;
869
870  const MemRegion *ReturnRegion = getTrackRegion(M.getReturnValue());
871  if (!ReturnRegion)
872    return;
873
874  auto Interface = Decl->getClassInterface();
875  auto Name = Interface ? Interface->getName() : "";
876  // In order to reduce the noise in the diagnostics generated by this checker,
877  // some framework and programming style based heuristics are used. These
878  // heuristics are for Cocoa APIs which have NS prefix.
879  if (Name.startswith("NS")) {
880    // Developers rely on dynamic invariants such as an item should be available
881    // in a collection, or a collection is not empty often. Those invariants can
882    // not be inferred by any static analysis tool. To not to bother the users
883    // with too many false positives, every item retrieval function should be
884    // ignored for collections. The instance methods of dictionaries in Cocoa
885    // are either item retrieval related or not interesting nullability wise.
886    // Using this fact, to keep the code easier to read just ignore the return
887    // value of every instance method of dictionaries.
888    if (M.isInstanceMessage() && Name.contains("Dictionary")) {
889      State =
890          State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
891      C.addTransition(State);
892      return;
893    }
894    // For similar reasons ignore some methods of Cocoa arrays.
895    StringRef FirstSelectorSlot = M.getSelector().getNameForSlot(0);
896    if (Name.contains("Array") &&
897        (FirstSelectorSlot == "firstObject" ||
898         FirstSelectorSlot == "lastObject")) {
899      State =
900          State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
901      C.addTransition(State);
902      return;
903    }
904
905    // Encoding related methods of string should not fail when lossless
906    // encodings are used. Using lossless encodings is so frequent that ignoring
907    // this class of methods reduced the emitted diagnostics by about 30% on
908    // some projects (and all of that was false positives).
909    if (Name.contains("String")) {
910      for (auto Param : M.parameters()) {
911        if (Param->getName() == "encoding") {
912          State = State->set<NullabilityMap>(ReturnRegion,
913                                             Nullability::Contradicted);
914          C.addTransition(State);
915          return;
916        }
917      }
918    }
919  }
920
921  const ObjCMessageExpr *Message = M.getOriginExpr();
922  Nullability SelfNullability = getReceiverNullability(M, State);
923
924  const NullabilityState *NullabilityOfReturn =
925      State->get<NullabilityMap>(ReturnRegion);
926
927  if (NullabilityOfReturn) {
928    // When we have a nullability tracked for the return value, the nullability
929    // of the expression will be the most nullable of the receiver and the
930    // return value.
931    Nullability RetValTracked = NullabilityOfReturn->getValue();
932    Nullability ComputedNullab =
933        getMostNullable(RetValTracked, SelfNullability);
934    if (ComputedNullab != RetValTracked &&
935        ComputedNullab != Nullability::Unspecified) {
936      const Stmt *NullabilitySource =
937          ComputedNullab == RetValTracked
938              ? NullabilityOfReturn->getNullabilitySource()
939              : Message->getInstanceReceiver();
940      State = State->set<NullabilityMap>(
941          ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
942      C.addTransition(State);
943    }
944    return;
945  }
946
947  // No tracked information. Use static type information for return value.
948  Nullability RetNullability = getNullabilityAnnotation(RetType);
949
950  // Properties might be computed. For this reason the static analyzer creates a
951  // new symbol each time an unknown property  is read. To avoid false pozitives
952  // do not treat unknown properties as nullable, even when they explicitly
953  // marked nullable.
954  if (M.getMessageKind() == OCM_PropertyAccess && !C.wasInlined)
955    RetNullability = Nullability::Nonnull;
956
957  Nullability ComputedNullab = getMostNullable(RetNullability, SelfNullability);
958  if (ComputedNullab == Nullability::Nullable) {
959    const Stmt *NullabilitySource = ComputedNullab == RetNullability
960                                        ? Message
961                                        : Message->getInstanceReceiver();
962    State = State->set<NullabilityMap>(
963        ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
964    C.addTransition(State);
965  }
966}
967
968/// Explicit casts are trusted. If there is a disagreement in the nullability
969/// annotations in the destination and the source or '0' is casted to nonnull
970/// track the value as having contraditory nullability. This will allow users to
971/// suppress warnings.
972void NullabilityChecker::checkPostStmt(const ExplicitCastExpr *CE,
973                                       CheckerContext &C) const {
974  QualType OriginType = CE->getSubExpr()->getType();
975  QualType DestType = CE->getType();
976  if (!OriginType->isAnyPointerType())
977    return;
978  if (!DestType->isAnyPointerType())
979    return;
980
981  ProgramStateRef State = C.getState();
982  if (State->get<InvariantViolated>())
983    return;
984
985  Nullability DestNullability = getNullabilityAnnotation(DestType);
986
987  // No explicit nullability in the destination type, so this cast does not
988  // change the nullability.
989  if (DestNullability == Nullability::Unspecified)
990    return;
991
992  auto RegionSVal = C.getSVal(CE).getAs<DefinedOrUnknownSVal>();
993  const MemRegion *Region = getTrackRegion(*RegionSVal);
994  if (!Region)
995    return;
996
997  // When 0 is converted to nonnull mark it as contradicted.
998  if (DestNullability == Nullability::Nonnull) {
999    NullConstraint Nullness = getNullConstraint(*RegionSVal, State);
1000    if (Nullness == NullConstraint::IsNull) {
1001      State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
1002      C.addTransition(State);
1003      return;
1004    }
1005  }
1006
1007  const NullabilityState *TrackedNullability =
1008      State->get<NullabilityMap>(Region);
1009
1010  if (!TrackedNullability) {
1011    if (DestNullability != Nullability::Nullable)
1012      return;
1013    State = State->set<NullabilityMap>(Region,
1014                                       NullabilityState(DestNullability, CE));
1015    C.addTransition(State);
1016    return;
1017  }
1018
1019  if (TrackedNullability->getValue() != DestNullability &&
1020      TrackedNullability->getValue() != Nullability::Contradicted) {
1021    State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
1022    C.addTransition(State);
1023  }
1024}
1025
1026/// For a given statement performing a bind, attempt to syntactically
1027/// match the expression resulting in the bound value.
1028static const Expr * matchValueExprForBind(const Stmt *S) {
1029  // For `x = e` the value expression is the right-hand side.
1030  if (auto *BinOp = dyn_cast<BinaryOperator>(S)) {
1031    if (BinOp->getOpcode() == BO_Assign)
1032      return BinOp->getRHS();
1033  }
1034
1035  // For `int x = e` the value expression is the initializer.
1036  if (auto *DS = dyn_cast<DeclStmt>(S))  {
1037    if (DS->isSingleDecl()) {
1038      auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
1039      if (!VD)
1040        return nullptr;
1041
1042      if (const Expr *Init = VD->getInit())
1043        return Init;
1044    }
1045  }
1046
1047  return nullptr;
1048}
1049
1050/// Returns true if \param S is a DeclStmt for a local variable that
1051/// ObjC automated reference counting initialized with zero.
1052static bool isARCNilInitializedLocal(CheckerContext &C, const Stmt *S) {
1053  // We suppress diagnostics for ARC zero-initialized _Nonnull locals. This
1054  // prevents false positives when a _Nonnull local variable cannot be
1055  // initialized with an initialization expression:
1056  //    NSString * _Nonnull s; // no-warning
1057  //    @autoreleasepool {
1058  //      s = ...
1059  //    }
1060  //
1061  // FIXME: We should treat implicitly zero-initialized _Nonnull locals as
1062  // uninitialized in Sema's UninitializedValues analysis to warn when a use of
1063  // the zero-initialized definition will unexpectedly yield nil.
1064
1065  // Locals are only zero-initialized when automated reference counting
1066  // is turned on.
1067  if (!C.getASTContext().getLangOpts().ObjCAutoRefCount)
1068    return false;
1069
1070  auto *DS = dyn_cast<DeclStmt>(S);
1071  if (!DS || !DS->isSingleDecl())
1072    return false;
1073
1074  auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
1075  if (!VD)
1076    return false;
1077
1078  // Sema only zero-initializes locals with ObjCLifetimes.
1079  if(!VD->getType().getQualifiers().hasObjCLifetime())
1080    return false;
1081
1082  const Expr *Init = VD->getInit();
1083  assert(Init && "ObjC local under ARC without initializer");
1084
1085  // Return false if the local is explicitly initialized (e.g., with '= nil').
1086  if (!isa<ImplicitValueInitExpr>(Init))
1087    return false;
1088
1089  return true;
1090}
1091
1092/// Propagate the nullability information through binds and warn when nullable
1093/// pointer or null symbol is assigned to a pointer with a nonnull type.
1094void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S,
1095                                   CheckerContext &C) const {
1096  const TypedValueRegion *TVR =
1097      dyn_cast_or_null<TypedValueRegion>(L.getAsRegion());
1098  if (!TVR)
1099    return;
1100
1101  QualType LocType = TVR->getValueType();
1102  if (!LocType->isAnyPointerType())
1103    return;
1104
1105  ProgramStateRef State = C.getState();
1106  if (State->get<InvariantViolated>())
1107    return;
1108
1109  auto ValDefOrUnknown = V.getAs<DefinedOrUnknownSVal>();
1110  if (!ValDefOrUnknown)
1111    return;
1112
1113  NullConstraint RhsNullness = getNullConstraint(*ValDefOrUnknown, State);
1114
1115  Nullability ValNullability = Nullability::Unspecified;
1116  if (SymbolRef Sym = ValDefOrUnknown->getAsSymbol())
1117    ValNullability = getNullabilityAnnotation(Sym->getType());
1118
1119  Nullability LocNullability = getNullabilityAnnotation(LocType);
1120
1121  // If the type of the RHS expression is nonnull, don't warn. This
1122  // enables explicit suppression with a cast to nonnull.
1123  Nullability ValueExprTypeLevelNullability = Nullability::Unspecified;
1124  const Expr *ValueExpr = matchValueExprForBind(S);
1125  if (ValueExpr) {
1126    ValueExprTypeLevelNullability =
1127      getNullabilityAnnotation(lookThroughImplicitCasts(ValueExpr)->getType());
1128  }
1129
1130  bool NullAssignedToNonNull = (LocNullability == Nullability::Nonnull &&
1131                                RhsNullness == NullConstraint::IsNull);
1132  if (ChecksEnabled[CK_NullPassedToNonnull] && NullAssignedToNonNull &&
1133      ValNullability != Nullability::Nonnull &&
1134      ValueExprTypeLevelNullability != Nullability::Nonnull &&
1135      !isARCNilInitializedLocal(C, S)) {
1136    static CheckerProgramPointTag Tag(this, "NullPassedToNonnull");
1137    ExplodedNode *N = C.generateErrorNode(State, &Tag);
1138    if (!N)
1139      return;
1140
1141
1142    const Stmt *ValueStmt = S;
1143    if (ValueExpr)
1144      ValueStmt = ValueExpr;
1145
1146    SmallString<256> SBuf;
1147    llvm::raw_svector_ostream OS(SBuf);
1148    OS << (LocType->isObjCObjectPointerType() ? "nil" : "Null");
1149    OS << " assigned to a pointer which is expected to have non-null value";
1150    reportBugIfInvariantHolds(OS.str(), ErrorKind::NilAssignedToNonnull,
1151                              CK_NullPassedToNonnull, N, nullptr, C, ValueStmt);
1152    return;
1153  }
1154
1155  // If null was returned from a non-null function, mark the nullability
1156  // invariant as violated even if the diagnostic was suppressed.
1157  if (NullAssignedToNonNull) {
1158    State = State->set<InvariantViolated>(true);
1159    C.addTransition(State);
1160    return;
1161  }
1162
1163  // Intentionally missing case: '0' is bound to a reference. It is handled by
1164  // the DereferenceChecker.
1165
1166  const MemRegion *ValueRegion = getTrackRegion(*ValDefOrUnknown);
1167  if (!ValueRegion)
1168    return;
1169
1170  const NullabilityState *TrackedNullability =
1171      State->get<NullabilityMap>(ValueRegion);
1172
1173  if (TrackedNullability) {
1174    if (RhsNullness == NullConstraint::IsNotNull ||
1175        TrackedNullability->getValue() != Nullability::Nullable)
1176      return;
1177    if (ChecksEnabled[CK_NullablePassedToNonnull] &&
1178        LocNullability == Nullability::Nonnull) {
1179      static CheckerProgramPointTag Tag(this, "NullablePassedToNonnull");
1180      ExplodedNode *N = C.addTransition(State, C.getPredecessor(), &Tag);
1181      reportBugIfInvariantHolds("Nullable pointer is assigned to a pointer "
1182                                "which is expected to have non-null value",
1183                                ErrorKind::NullableAssignedToNonnull,
1184                                CK_NullablePassedToNonnull, N, ValueRegion, C);
1185    }
1186    return;
1187  }
1188
1189  const auto *BinOp = dyn_cast<BinaryOperator>(S);
1190
1191  if (ValNullability == Nullability::Nullable) {
1192    // Trust the static information of the value more than the static
1193    // information on the location.
1194    const Stmt *NullabilitySource = BinOp ? BinOp->getRHS() : S;
1195    State = State->set<NullabilityMap>(
1196        ValueRegion, NullabilityState(ValNullability, NullabilitySource));
1197    C.addTransition(State);
1198    return;
1199  }
1200
1201  if (LocNullability == Nullability::Nullable) {
1202    const Stmt *NullabilitySource = BinOp ? BinOp->getLHS() : S;
1203    State = State->set<NullabilityMap>(
1204        ValueRegion, NullabilityState(LocNullability, NullabilitySource));
1205    C.addTransition(State);
1206  }
1207}
1208
1209void NullabilityChecker::printState(raw_ostream &Out, ProgramStateRef State,
1210                                    const char *NL, const char *Sep) const {
1211
1212  NullabilityMapTy B = State->get<NullabilityMap>();
1213
1214  if (State->get<InvariantViolated>())
1215    Out << Sep << NL
1216        << "Nullability invariant was violated, warnings suppressed." << NL;
1217
1218  if (B.isEmpty())
1219    return;
1220
1221  if (!State->get<InvariantViolated>())
1222    Out << Sep << NL;
1223
1224  for (NullabilityMapTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1225    Out << I->first << " : ";
1226    I->second.print(Out);
1227    Out << NL;
1228  }
1229}
1230
1231void ento::registerNullabilityBase(CheckerManager &mgr) {
1232  mgr.registerChecker<NullabilityChecker>();
1233}
1234
1235bool ento::shouldRegisterNullabilityBase(const CheckerManager &mgr) {
1236  return true;
1237}
1238
1239#define REGISTER_CHECKER(name, trackingRequired)                               \
1240  void ento::register##name##Checker(CheckerManager &mgr) {                    \
1241    NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>();        \
1242    checker->ChecksEnabled[NullabilityChecker::CK_##name] = true;              \
1243    checker->CheckNames[NullabilityChecker::CK_##name] =                       \
1244        mgr.getCurrentCheckerName();                                           \
1245    checker->NeedTracking = checker->NeedTracking || trackingRequired;         \
1246    checker->NoDiagnoseCallsToSystemHeaders =                                  \
1247        checker->NoDiagnoseCallsToSystemHeaders ||                             \
1248        mgr.getAnalyzerOptions().getCheckerBooleanOption(                      \
1249            checker, "NoDiagnoseCallsToSystemHeaders", true);                  \
1250  }                                                                            \
1251                                                                               \
1252  bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) {        \
1253    return true;                                                               \
1254  }
1255
1256// The checks are likely to be turned on by default and it is possible to do
1257// them without tracking any nullability related information. As an optimization
1258// no nullability information will be tracked when only these two checks are
1259// enables.
1260REGISTER_CHECKER(NullPassedToNonnull, false)
1261REGISTER_CHECKER(NullReturnedFromNonnull, false)
1262
1263REGISTER_CHECKER(NullableDereferenced, true)
1264REGISTER_CHECKER(NullablePassedToNonnull, true)
1265REGISTER_CHECKER(NullableReturnedFromNonnull, true)
1266