xref: /llvm-project/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp (revision 17dacc401c70ca5b316b91c98387b2bc06a4902c)
1 //== Nullabilityhecker.cpp - Nullability checker ----------------*- 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 checker tries to find nullability violations. There are several kinds of
11 // possible violations:
12 // * Null pointer is passed to a pointer which has a _Nonnull type.
13 // * Null pointer is returned from a function which has a _Nonnull return type.
14 // * Nullable pointer is passed to a pointer which has a _Nonnull type.
15 // * Nullable pointer is returned from a function which has a _Nonnull return
16 //   type.
17 // * Nullable pointer is dereferenced.
18 //
19 // This checker propagates the nullability information of the pointers and looks
20 // for the patterns that are described above. Explicit casts are trusted and are
21 // considered a way to suppress false positives for this checker. The other way
22 // to suppress warnings would be to add asserts or guarding if statements to the
23 // code. In addition to the nullability propagation this checker also uses some
24 // heuristics to suppress potential false positives.
25 //
26 //===----------------------------------------------------------------------===//
27 
28 #include "ClangSACheckers.h"
29 #include "llvm/Support/Path.h"
30 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
31 #include "clang/StaticAnalyzer/Core/Checker.h"
32 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
33 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
34 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
35 
36 using namespace clang;
37 using namespace ento;
38 
39 namespace {
40 // Do not reorder! The getMostNullable method relies on the order.
41 // Optimization: Most pointers expected to be unspecified. When a symbol has an
42 // unspecified or nonnull type non of the rules would indicate any problem for
43 // that symbol. For this reason only nullable and contradicted nullability are
44 // stored for a symbol. When a symbol is already contradicted, it can not be
45 // casted back to nullable.
46 enum class Nullability : char {
47   Contradicted, // Tracked nullability is contradicted by an explicit cast. Do
48                 // not report any nullability related issue for this symbol.
49                 // This nullability is propagated agressively to avoid false
50                 // positive results. See the comment on getMostNullable method.
51   Nullable,
52   Unspecified,
53   Nonnull
54 };
55 
56 /// Returns the most nullable nullability. This is used for message expressions
57 /// like [reciever method], where the nullability of this expression is either
58 /// the nullability of the receiver or the nullability of the return type of the
59 /// method, depending on which is more nullable. Contradicted is considered to
60 /// be the most nullable, to avoid false positive results.
61 Nullability getMostNullable(Nullability Lhs, Nullability Rhs) {
62   return static_cast<Nullability>(
63       std::min(static_cast<char>(Lhs), static_cast<char>(Rhs)));
64 }
65 
66 const char *getNullabilityString(Nullability Nullab) {
67   switch (Nullab) {
68   case Nullability::Contradicted:
69     return "contradicted";
70   case Nullability::Nullable:
71     return "nullable";
72   case Nullability::Unspecified:
73     return "unspecified";
74   case Nullability::Nonnull:
75     return "nonnull";
76   }
77   llvm_unreachable("Unexpected enumeration.");
78   return "";
79 }
80 
81 // These enums are used as an index to ErrorMessages array.
82 enum class ErrorKind : int {
83   NilAssignedToNonnull,
84   NilPassedToNonnull,
85   NilReturnedToNonnull,
86   NullableAssignedToNonnull,
87   NullableReturnedToNonnull,
88   NullableDereferenced,
89   NullablePassedToNonnull
90 };
91 
92 const char *const ErrorMessages[] = {
93     "Null is assigned to a pointer which is expected to have non-null value",
94     "Null passed to a callee that requires a non-null argument",
95     "Null is returned from a function that is expected to return a non-null "
96     "value",
97     "Nullable pointer is assigned to a pointer which is expected to have "
98     "non-null value",
99     "Nullable pointer is returned from a function that is expected to return a "
100     "non-null value",
101     "Nullable pointer is dereferenced",
102     "Nullable pointer is passed to a callee that requires a non-null argument"};
103 
104 class NullabilityChecker
105     : public Checker<check::Bind, check::PreCall, check::PreStmt<ReturnStmt>,
106                      check::PostCall, check::PostStmt<ExplicitCastExpr>,
107                      check::PostObjCMessage, check::DeadSymbols,
108                      check::Event<ImplicitNullDerefEvent>> {
109   mutable std::unique_ptr<BugType> BT;
110 
111 public:
112   void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
113   void checkPostStmt(const ExplicitCastExpr *CE, CheckerContext &C) const;
114   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
115   void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
116   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
117   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
118   void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
119   void checkEvent(ImplicitNullDerefEvent Event) const;
120 
121   void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
122                   const char *Sep) const override;
123 
124   struct NullabilityChecksFilter {
125     DefaultBool CheckNullPassedToNonnull;
126     DefaultBool CheckNullReturnedFromNonnull;
127     DefaultBool CheckNullableDereferenced;
128     DefaultBool CheckNullablePassedToNonnull;
129     DefaultBool CheckNullableReturnedFromNonnull;
130 
131     CheckName CheckNameNullPassedToNonnull;
132     CheckName CheckNameNullReturnedFromNonnull;
133     CheckName CheckNameNullableDereferenced;
134     CheckName CheckNameNullablePassedToNonnull;
135     CheckName CheckNameNullableReturnedFromNonnull;
136   };
137 
138   NullabilityChecksFilter Filter;
139 
140 private:
141   class NullabilityBugVisitor
142       : public BugReporterVisitorImpl<NullabilityBugVisitor> {
143   public:
144     NullabilityBugVisitor(const MemRegion *M) : Region(M) {}
145 
146     void Profile(llvm::FoldingSetNodeID &ID) const override {
147       static int X = 0;
148       ID.AddPointer(&X);
149       ID.AddPointer(Region);
150     }
151 
152     PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
153                                    const ExplodedNode *PrevN,
154                                    BugReporterContext &BRC,
155                                    BugReport &BR) override;
156 
157   private:
158     // The tracked region.
159     const MemRegion *Region;
160   };
161 
162   /// When any of the nonnull arguments of the analyzed function is null, do not
163   /// report anything and turn off the check.
164   ///
165   /// When \p SuppressPath is set to true, no more bugs will be reported on this
166   /// path by this checker.
167   void reportBugIfPreconditionHolds(ErrorKind Error, ExplodedNode *N,
168                                     const MemRegion *Region, CheckerContext &C,
169                                     const Stmt *ValueExpr = nullptr,
170                                     bool SuppressPath = false) const;
171 
172   void reportBug(ErrorKind Error, ExplodedNode *N, const MemRegion *Region,
173                  BugReporter &BR, const Stmt *ValueExpr = nullptr) const {
174     if (!BT)
175       BT.reset(new BugType(this, "Nullability", "Memory error"));
176     const char *Msg = ErrorMessages[static_cast<int>(Error)];
177     std::unique_ptr<BugReport> R(new BugReport(*BT, Msg, N));
178     if (Region) {
179       R->markInteresting(Region);
180       R->addVisitor(llvm::make_unique<NullabilityBugVisitor>(Region));
181     }
182     if (ValueExpr) {
183       R->addRange(ValueExpr->getSourceRange());
184       if (Error == ErrorKind::NilAssignedToNonnull ||
185           Error == ErrorKind::NilPassedToNonnull ||
186           Error == ErrorKind::NilReturnedToNonnull)
187         bugreporter::trackNullOrUndefValue(N, ValueExpr, *R);
188     }
189     BR.emitReport(std::move(R));
190   }
191 };
192 
193 class NullabilityState {
194 public:
195   NullabilityState(Nullability Nullab, const Stmt *Source = nullptr)
196       : Nullab(Nullab), Source(Source) {}
197 
198   const Stmt *getNullabilitySource() const { return Source; }
199 
200   Nullability getValue() const { return Nullab; }
201 
202   void Profile(llvm::FoldingSetNodeID &ID) const {
203     ID.AddInteger(static_cast<char>(Nullab));
204     ID.AddPointer(Source);
205   }
206 
207   void print(raw_ostream &Out) const {
208     Out << getNullabilityString(Nullab) << "\n";
209   }
210 
211 private:
212   Nullability Nullab;
213   // Source is the expression which determined the nullability. For example in a
214   // message like [nullable nonnull_returning] has nullable nullability, because
215   // the receiver is nullable. Here the receiver will be the source of the
216   // nullability. This is useful information when the diagnostics are generated.
217   const Stmt *Source;
218 };
219 
220 bool operator==(NullabilityState Lhs, NullabilityState Rhs) {
221   return Lhs.getValue() == Rhs.getValue() &&
222          Lhs.getNullabilitySource() == Rhs.getNullabilitySource();
223 }
224 
225 } // end anonymous namespace
226 
227 REGISTER_MAP_WITH_PROGRAMSTATE(NullabilityMap, const MemRegion *,
228                                NullabilityState)
229 
230 // If the nullability precondition of a function is violated, we should not
231 // report nullability related issues on that path. For this reason once a
232 // precondition is not met on a path, this checker will be esentially turned off
233 // for the rest of the analysis. We do not want to generate a sink node however,
234 // so this checker would not lead to reduced coverage.
235 REGISTER_TRAIT_WITH_PROGRAMSTATE(PreconditionViolated, bool)
236 
237 enum class NullConstraint { IsNull, IsNotNull, Unknown };
238 
239 static NullConstraint getNullConstraint(DefinedOrUnknownSVal Val,
240                                         ProgramStateRef State) {
241   ConditionTruthVal Nullness = State->isNull(Val);
242   if (Nullness.isConstrainedFalse())
243     return NullConstraint::IsNotNull;
244   if (Nullness.isConstrainedTrue())
245     return NullConstraint::IsNull;
246   return NullConstraint::Unknown;
247 }
248 
249 // If an SVal wraps a region that should be tracked, it will return a pointer
250 // to the wrapped region. Otherwise it will return a nullptr.
251 static const SymbolicRegion *getTrackRegion(SVal Val,
252                                             bool CheckSuperRegion = false) {
253   auto RegionSVal = Val.getAs<loc::MemRegionVal>();
254   if (!RegionSVal)
255     return nullptr;
256 
257   const MemRegion *Region = RegionSVal->getRegion();
258 
259   if (CheckSuperRegion) {
260     if (auto FieldReg = Region->getAs<FieldRegion>())
261       return dyn_cast<SymbolicRegion>(FieldReg->getSuperRegion());
262     if (auto ElementReg = Region->getAs<ElementRegion>())
263       return dyn_cast<SymbolicRegion>(ElementReg->getSuperRegion());
264   }
265 
266   return dyn_cast<SymbolicRegion>(Region);
267 }
268 
269 PathDiagnosticPiece *NullabilityChecker::NullabilityBugVisitor::VisitNode(
270     const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
271     BugReport &BR) {
272   ProgramStateRef State = N->getState();
273   ProgramStateRef StatePrev = PrevN->getState();
274 
275   const NullabilityState *TrackedNullab = State->get<NullabilityMap>(Region);
276   const NullabilityState *TrackedNullabPrev =
277       StatePrev->get<NullabilityMap>(Region);
278   if (!TrackedNullab)
279     return nullptr;
280 
281   if (TrackedNullabPrev &&
282       TrackedNullabPrev->getValue() == TrackedNullab->getValue())
283     return nullptr;
284 
285   // Retrieve the associated statement.
286   const Stmt *S = TrackedNullab->getNullabilitySource();
287   if (!S) {
288     ProgramPoint ProgLoc = N->getLocation();
289     if (Optional<StmtPoint> SP = ProgLoc.getAs<StmtPoint>()) {
290       S = SP->getStmt();
291     }
292   }
293 
294   if (!S)
295     return nullptr;
296 
297   std::string InfoText =
298       (llvm::Twine("Nullability '") +
299        getNullabilityString(TrackedNullab->getValue()) + "' is infered")
300           .str();
301 
302   // Generate the extra diagnostic.
303   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
304                              N->getLocationContext());
305   return new PathDiagnosticEventPiece(Pos, InfoText, true, nullptr);
306 }
307 
308 static Nullability getNullabilityAnnotation(QualType Type) {
309   const auto *AttrType = Type->getAs<AttributedType>();
310   if (!AttrType)
311     return Nullability::Unspecified;
312   if (AttrType->getAttrKind() == AttributedType::attr_nullable)
313     return Nullability::Nullable;
314   else if (AttrType->getAttrKind() == AttributedType::attr_nonnull)
315     return Nullability::Nonnull;
316   return Nullability::Unspecified;
317 }
318 
319 template <typename ParamVarDeclRange>
320 static bool
321 checkParamsForPreconditionViolation(const ParamVarDeclRange &Params,
322                                     ProgramStateRef State,
323                                     const LocationContext *LocCtxt) {
324   for (const auto *ParamDecl : Params) {
325     if (ParamDecl->isParameterPack())
326       break;
327 
328     if (getNullabilityAnnotation(ParamDecl->getType()) != Nullability::Nonnull)
329       continue;
330 
331     auto RegVal = State->getLValue(ParamDecl, LocCtxt)
332                       .template getAs<loc::MemRegionVal>();
333     if (!RegVal)
334       continue;
335 
336     auto ParamValue = State->getSVal(RegVal->getRegion())
337                           .template getAs<DefinedOrUnknownSVal>();
338     if (!ParamValue)
339       continue;
340 
341     if (getNullConstraint(*ParamValue, State) == NullConstraint::IsNull) {
342       return true;
343     }
344   }
345   return false;
346 }
347 
348 static bool checkPreconditionViolation(ProgramStateRef State, ExplodedNode *N,
349                                        CheckerContext &C) {
350   if (State->get<PreconditionViolated>())
351     return true;
352 
353   const LocationContext *LocCtxt = C.getLocationContext();
354   const Decl *D = LocCtxt->getDecl();
355   if (!D)
356     return false;
357 
358   if (const auto *BlockD = dyn_cast<BlockDecl>(D)) {
359     if (checkParamsForPreconditionViolation(BlockD->parameters(), State,
360                                             LocCtxt)) {
361       if (!N->isSink())
362         C.addTransition(State->set<PreconditionViolated>(true), N);
363       return true;
364     }
365     return false;
366   }
367 
368   if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
369     if (checkParamsForPreconditionViolation(FuncDecl->parameters(), State,
370                                             LocCtxt)) {
371       if (!N->isSink())
372         C.addTransition(State->set<PreconditionViolated>(true), N);
373       return true;
374     }
375     return false;
376   }
377   return false;
378 }
379 
380 void NullabilityChecker::reportBugIfPreconditionHolds(
381     ErrorKind Error, ExplodedNode *N, const MemRegion *Region,
382     CheckerContext &C, const Stmt *ValueExpr, bool SuppressPath) const {
383   ProgramStateRef OriginalState = N->getState();
384 
385   if (checkPreconditionViolation(OriginalState, N, C))
386     return;
387   if (SuppressPath) {
388     OriginalState = OriginalState->set<PreconditionViolated>(true);
389     N = C.addTransition(OriginalState, N);
390   }
391 
392   reportBug(Error, N, Region, C.getBugReporter(), ValueExpr);
393 }
394 
395 /// Cleaning up the program state.
396 void NullabilityChecker::checkDeadSymbols(SymbolReaper &SR,
397                                           CheckerContext &C) const {
398   ProgramStateRef State = C.getState();
399   NullabilityMapTy Nullabilities = State->get<NullabilityMap>();
400   for (NullabilityMapTy::iterator I = Nullabilities.begin(),
401                                   E = Nullabilities.end();
402        I != E; ++I) {
403     if (!SR.isLiveRegion(I->first)) {
404       State = State->remove<NullabilityMap>(I->first);
405     }
406   }
407   // When one of the nonnull arguments are constrained to be null, nullability
408   // preconditions are violated. It is not enough to check this only when we
409   // actually report an error, because at that time interesting symbols might be
410   // reaped.
411   if (checkPreconditionViolation(State, C.getPredecessor(), C))
412     return;
413   C.addTransition(State);
414 }
415 
416 /// This callback triggers when a pointer is dereferenced and the analyzer does
417 /// not know anything about the value of that pointer. When that pointer is
418 /// nullable, this code emits a warning.
419 void NullabilityChecker::checkEvent(ImplicitNullDerefEvent Event) const {
420   if (Event.SinkNode->getState()->get<PreconditionViolated>())
421     return;
422 
423   const MemRegion *Region =
424       getTrackRegion(Event.Location, /*CheckSuperregion=*/true);
425   if (!Region)
426     return;
427 
428   ProgramStateRef State = Event.SinkNode->getState();
429   const NullabilityState *TrackedNullability =
430       State->get<NullabilityMap>(Region);
431 
432   if (!TrackedNullability)
433     return;
434 
435   if (Filter.CheckNullableDereferenced &&
436       TrackedNullability->getValue() == Nullability::Nullable) {
437     BugReporter &BR = *Event.BR;
438     // Do not suppress errors on defensive code paths, because dereferencing
439     // a nullable pointer is always an error.
440     if (Event.IsDirectDereference)
441       reportBug(ErrorKind::NullableDereferenced, Event.SinkNode, Region, BR);
442     else
443       reportBug(ErrorKind::NullablePassedToNonnull, Event.SinkNode, Region, BR);
444   }
445 }
446 
447 /// This method check when nullable pointer or null value is returned from a
448 /// function that has nonnull return type.
449 ///
450 /// TODO: when nullability preconditons are violated, it is ok to violate the
451 /// nullability postconditons (i.e.: when one of the nonnull parameters are null
452 /// this check should not report any nullability related issue).
453 void NullabilityChecker::checkPreStmt(const ReturnStmt *S,
454                                       CheckerContext &C) const {
455   auto RetExpr = S->getRetValue();
456   if (!RetExpr)
457     return;
458 
459   if (!RetExpr->getType()->isAnyPointerType())
460     return;
461 
462   ProgramStateRef State = C.getState();
463   if (State->get<PreconditionViolated>())
464     return;
465 
466   auto RetSVal =
467       State->getSVal(S, C.getLocationContext()).getAs<DefinedOrUnknownSVal>();
468   if (!RetSVal)
469     return;
470 
471   AnalysisDeclContext *DeclCtxt =
472       C.getLocationContext()->getAnalysisDeclContext();
473   const FunctionType *FuncType = DeclCtxt->getDecl()->getFunctionType();
474   if (!FuncType)
475     return;
476 
477   NullConstraint Nullness = getNullConstraint(*RetSVal, State);
478 
479   Nullability StaticNullability =
480       getNullabilityAnnotation(FuncType->getReturnType());
481 
482   if (Filter.CheckNullReturnedFromNonnull &&
483       Nullness == NullConstraint::IsNull &&
484       StaticNullability == Nullability::Nonnull) {
485     static CheckerProgramPointTag Tag(this, "NullReturnedFromNonnull");
486     ExplodedNode *N = C.generateSink(State, C.getPredecessor(), &Tag);
487     reportBugIfPreconditionHolds(ErrorKind::NilReturnedToNonnull, N, nullptr, C,
488                                  RetExpr);
489     return;
490   }
491 
492   const MemRegion *Region = getTrackRegion(*RetSVal);
493   if (!Region)
494     return;
495 
496   const NullabilityState *TrackedNullability =
497       State->get<NullabilityMap>(Region);
498   if (TrackedNullability) {
499     Nullability TrackedNullabValue = TrackedNullability->getValue();
500     if (Filter.CheckNullableReturnedFromNonnull &&
501         Nullness != NullConstraint::IsNotNull &&
502         TrackedNullabValue == Nullability::Nullable &&
503         StaticNullability == Nullability::Nonnull) {
504       static CheckerProgramPointTag Tag(this, "NullableReturnedFromNonnull");
505       ExplodedNode *N = C.addTransition(State, C.getPredecessor(), &Tag);
506       reportBugIfPreconditionHolds(ErrorKind::NullableReturnedToNonnull, N,
507                                    Region, C);
508     }
509     return;
510   }
511   if (StaticNullability == Nullability::Nullable) {
512     State = State->set<NullabilityMap>(Region,
513                                        NullabilityState(StaticNullability, S));
514     C.addTransition(State);
515   }
516 }
517 
518 /// This callback warns when a nullable pointer or a null value is passed to a
519 /// function that expects its argument to be nonnull.
520 void NullabilityChecker::checkPreCall(const CallEvent &Call,
521                                       CheckerContext &C) const {
522   if (!Call.getDecl())
523     return;
524 
525   ProgramStateRef State = C.getState();
526   if (State->get<PreconditionViolated>())
527     return;
528 
529   ProgramStateRef OrigState = State;
530 
531   unsigned Idx = 0;
532   for (const ParmVarDecl *Param : Call.parameters()) {
533     if (Param->isParameterPack())
534       break;
535 
536     const Expr *ArgExpr = nullptr;
537     if (Idx < Call.getNumArgs())
538       ArgExpr = Call.getArgExpr(Idx);
539     auto ArgSVal = Call.getArgSVal(Idx++).getAs<DefinedOrUnknownSVal>();
540     if (!ArgSVal)
541       continue;
542 
543     if (!Param->getType()->isAnyPointerType() &&
544         !Param->getType()->isReferenceType())
545       continue;
546 
547     NullConstraint Nullness = getNullConstraint(*ArgSVal, State);
548 
549     Nullability ParamNullability = getNullabilityAnnotation(Param->getType());
550     Nullability ArgStaticNullability =
551         getNullabilityAnnotation(ArgExpr->getType());
552 
553     if (Filter.CheckNullPassedToNonnull && Nullness == NullConstraint::IsNull &&
554         ArgStaticNullability != Nullability::Nonnull &&
555         ParamNullability == Nullability::Nonnull) {
556       ExplodedNode *N = C.generateSink(State);
557       reportBugIfPreconditionHolds(ErrorKind::NilPassedToNonnull, N, nullptr, C,
558                                    ArgExpr);
559       return;
560     }
561 
562     const MemRegion *Region = getTrackRegion(*ArgSVal);
563     if (!Region)
564       continue;
565 
566     const NullabilityState *TrackedNullability =
567         State->get<NullabilityMap>(Region);
568 
569     if (TrackedNullability) {
570       if (Nullness == NullConstraint::IsNotNull ||
571           TrackedNullability->getValue() != Nullability::Nullable)
572         continue;
573 
574       if (Filter.CheckNullablePassedToNonnull &&
575           ParamNullability == Nullability::Nonnull) {
576         ExplodedNode *N = C.addTransition(State);
577         reportBugIfPreconditionHolds(ErrorKind::NullablePassedToNonnull, N,
578                                      Region, C, ArgExpr, /*SuppressPath=*/true);
579         return;
580       }
581       if (Filter.CheckNullableDereferenced &&
582           Param->getType()->isReferenceType()) {
583         ExplodedNode *N = C.addTransition(State);
584         reportBugIfPreconditionHolds(ErrorKind::NullableDereferenced, N, Region,
585                                      C, ArgExpr, /*SuppressPath=*/true);
586         return;
587       }
588       continue;
589     }
590     // No tracked nullability yet.
591     if (ArgStaticNullability != Nullability::Nullable)
592       continue;
593     State = State->set<NullabilityMap>(
594         Region, NullabilityState(ArgStaticNullability, ArgExpr));
595   }
596   if (State != OrigState)
597     C.addTransition(State);
598 }
599 
600 /// Suppress the nullability warnings for some functions.
601 void NullabilityChecker::checkPostCall(const CallEvent &Call,
602                                        CheckerContext &C) const {
603   auto Decl = Call.getDecl();
604   if (!Decl)
605     return;
606   // ObjC Messages handles in a different callback.
607   if (Call.getKind() == CE_ObjCMessage)
608     return;
609   const FunctionType *FuncType = Decl->getFunctionType();
610   if (!FuncType)
611     return;
612   QualType ReturnType = FuncType->getReturnType();
613   if (!ReturnType->isAnyPointerType())
614     return;
615   ProgramStateRef State = C.getState();
616   if (State->get<PreconditionViolated>())
617     return;
618 
619   const MemRegion *Region = getTrackRegion(Call.getReturnValue());
620   if (!Region)
621     return;
622 
623   // CG headers are misannotated. Do not warn for symbols that are the results
624   // of CG calls.
625   const SourceManager &SM = C.getSourceManager();
626   StringRef FilePath = SM.getFilename(SM.getSpellingLoc(Decl->getLocStart()));
627   if (llvm::sys::path::filename(FilePath).startswith("CG")) {
628     State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
629     C.addTransition(State);
630     return;
631   }
632 
633   const NullabilityState *TrackedNullability =
634       State->get<NullabilityMap>(Region);
635 
636   if (!TrackedNullability &&
637       getNullabilityAnnotation(ReturnType) == Nullability::Nullable) {
638     State = State->set<NullabilityMap>(Region, Nullability::Nullable);
639     C.addTransition(State);
640   }
641 }
642 
643 static Nullability getReceiverNullability(const ObjCMethodCall &M,
644                                           ProgramStateRef State) {
645   if (M.isReceiverSelfOrSuper()) {
646     // For super and super class receivers we assume that the receiver is
647     // nonnull.
648     return Nullability::Nonnull;
649   }
650   // Otherwise look up nullability in the state.
651   SVal Receiver = M.getReceiverSVal();
652   if (auto DefOrUnknown = Receiver.getAs<DefinedOrUnknownSVal>()) {
653     // If the receiver is constrained to be nonnull, assume that it is nonnull
654     // regardless of its type.
655     NullConstraint Nullness = getNullConstraint(*DefOrUnknown, State);
656     if (Nullness == NullConstraint::IsNotNull)
657       return Nullability::Nonnull;
658   }
659   auto ValueRegionSVal = Receiver.getAs<loc::MemRegionVal>();
660   if (ValueRegionSVal) {
661     const MemRegion *SelfRegion = ValueRegionSVal->getRegion();
662     assert(SelfRegion);
663 
664     const NullabilityState *TrackedSelfNullability =
665         State->get<NullabilityMap>(SelfRegion);
666     if (TrackedSelfNullability)
667       return TrackedSelfNullability->getValue();
668   }
669   return Nullability::Unspecified;
670 }
671 
672 /// Calculate the nullability of the result of a message expr based on the
673 /// nullability of the receiver, the nullability of the return value, and the
674 /// constraints.
675 void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M,
676                                               CheckerContext &C) const {
677   auto Decl = M.getDecl();
678   if (!Decl)
679     return;
680   QualType RetType = Decl->getReturnType();
681   if (!RetType->isAnyPointerType())
682     return;
683 
684   ProgramStateRef State = C.getState();
685   if (State->get<PreconditionViolated>())
686     return;
687 
688   const MemRegion *ReturnRegion = getTrackRegion(M.getReturnValue());
689   if (!ReturnRegion)
690     return;
691 
692   auto Interface = Decl->getClassInterface();
693   auto Name = Interface ? Interface->getName() : "";
694   // In order to reduce the noise in the diagnostics generated by this checker,
695   // some framework and programming style based heuristics are used. These
696   // heuristics are for Cocoa APIs which have NS prefix.
697   if (Name.startswith("NS")) {
698     // Developers rely on dynamic invariants such as an item should be available
699     // in a collection, or a collection is not empty often. Those invariants can
700     // not be inferred by any static analysis tool. To not to bother the users
701     // with too many false positives, every item retrieval function should be
702     // ignored for collections. The instance methods of dictionaries in Cocoa
703     // are either item retrieval related or not interesting nullability wise.
704     // Using this fact, to keep the code easier to read just ignore the return
705     // value of every instance method of dictionaries.
706     if (M.isInstanceMessage() && Name.find("Dictionary") != StringRef::npos) {
707       State =
708           State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
709       C.addTransition(State);
710       return;
711     }
712     // For similar reasons ignore some methods of Cocoa arrays.
713     StringRef FirstSelectorSlot = M.getSelector().getNameForSlot(0);
714     if (Name.find("Array") != StringRef::npos &&
715         (FirstSelectorSlot == "firstObject" ||
716          FirstSelectorSlot == "lastObject")) {
717       State =
718           State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
719       C.addTransition(State);
720       return;
721     }
722 
723     // Encoding related methods of string should not fail when lossless
724     // encodings are used. Using lossless encodings is so frequent that ignoring
725     // this class of methods reduced the emitted diagnostics by about 30% on
726     // some projects (and all of that was false positives).
727     if (Name.find("String") != StringRef::npos) {
728       for (auto Param : M.parameters()) {
729         if (Param->getName() == "encoding") {
730           State = State->set<NullabilityMap>(ReturnRegion,
731                                              Nullability::Contradicted);
732           C.addTransition(State);
733           return;
734         }
735       }
736     }
737   }
738 
739   const ObjCMessageExpr *Message = M.getOriginExpr();
740   Nullability SelfNullability = getReceiverNullability(M, State);
741 
742   const NullabilityState *NullabilityOfReturn =
743       State->get<NullabilityMap>(ReturnRegion);
744 
745   if (NullabilityOfReturn) {
746     // When we have a nullability tracked for the return value, the nullability
747     // of the expression will be the most nullable of the receiver and the
748     // return value.
749     Nullability RetValTracked = NullabilityOfReturn->getValue();
750     Nullability ComputedNullab =
751         getMostNullable(RetValTracked, SelfNullability);
752     if (ComputedNullab != RetValTracked &&
753         ComputedNullab != Nullability::Unspecified) {
754       const Stmt *NullabilitySource =
755           ComputedNullab == RetValTracked
756               ? NullabilityOfReturn->getNullabilitySource()
757               : Message->getInstanceReceiver();
758       State = State->set<NullabilityMap>(
759           ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
760       C.addTransition(State);
761     }
762     return;
763   }
764 
765   // No tracked information. Use static type information for return value.
766   Nullability RetNullability = getNullabilityAnnotation(RetType);
767 
768   // Properties might be computed. For this reason the static analyzer creates a
769   // new symbol each time an unknown property  is read. To avoid false pozitives
770   // do not treat unknown properties as nullable, even when they explicitly
771   // marked nullable.
772   if (M.getMessageKind() == OCM_PropertyAccess && !C.wasInlined)
773     RetNullability = Nullability::Nonnull;
774 
775   Nullability ComputedNullab = getMostNullable(RetNullability, SelfNullability);
776   if (ComputedNullab == Nullability::Nullable) {
777     const Stmt *NullabilitySource = ComputedNullab == RetNullability
778                                         ? Message
779                                         : Message->getInstanceReceiver();
780     State = State->set<NullabilityMap>(
781         ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
782     C.addTransition(State);
783   }
784 }
785 
786 /// Explicit casts are trusted. If there is a disagreement in the nullability
787 /// annotations in the destination and the source or '0' is casted to nonnull
788 /// track the value as having contraditory nullability. This will allow users to
789 /// suppress warnings.
790 void NullabilityChecker::checkPostStmt(const ExplicitCastExpr *CE,
791                                        CheckerContext &C) const {
792   QualType OriginType = CE->getSubExpr()->getType();
793   QualType DestType = CE->getType();
794   if (!OriginType->isAnyPointerType())
795     return;
796   if (!DestType->isAnyPointerType())
797     return;
798 
799   ProgramStateRef State = C.getState();
800   if (State->get<PreconditionViolated>())
801     return;
802 
803   Nullability DestNullability = getNullabilityAnnotation(DestType);
804 
805   // No explicit nullability in the destination type, so this cast does not
806   // change the nullability.
807   if (DestNullability == Nullability::Unspecified)
808     return;
809 
810   auto RegionSVal =
811       State->getSVal(CE, C.getLocationContext()).getAs<DefinedOrUnknownSVal>();
812   const MemRegion *Region = getTrackRegion(*RegionSVal);
813   if (!Region)
814     return;
815 
816   // When 0 is converted to nonnull mark it as contradicted.
817   if (DestNullability == Nullability::Nonnull) {
818     NullConstraint Nullness = getNullConstraint(*RegionSVal, State);
819     if (Nullness == NullConstraint::IsNull) {
820       State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
821       C.addTransition(State);
822       return;
823     }
824   }
825 
826   const NullabilityState *TrackedNullability =
827       State->get<NullabilityMap>(Region);
828 
829   if (!TrackedNullability) {
830     if (DestNullability != Nullability::Nullable)
831       return;
832     State = State->set<NullabilityMap>(Region,
833                                        NullabilityState(DestNullability, CE));
834     C.addTransition(State);
835     return;
836   }
837 
838   if (TrackedNullability->getValue() != DestNullability &&
839       TrackedNullability->getValue() != Nullability::Contradicted) {
840     State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
841     C.addTransition(State);
842   }
843 }
844 
845 /// Propagate the nullability information through binds and warn when nullable
846 /// pointer or null symbol is assigned to a pointer with a nonnull type.
847 void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S,
848                                    CheckerContext &C) const {
849   const TypedValueRegion *TVR =
850       dyn_cast_or_null<TypedValueRegion>(L.getAsRegion());
851   if (!TVR)
852     return;
853 
854   QualType LocType = TVR->getValueType();
855   if (!LocType->isAnyPointerType())
856     return;
857 
858   ProgramStateRef State = C.getState();
859   if (State->get<PreconditionViolated>())
860     return;
861 
862   auto ValDefOrUnknown = V.getAs<DefinedOrUnknownSVal>();
863   if (!ValDefOrUnknown)
864     return;
865 
866   NullConstraint RhsNullness = getNullConstraint(*ValDefOrUnknown, State);
867 
868   Nullability ValNullability = Nullability::Unspecified;
869   if (SymbolRef Sym = ValDefOrUnknown->getAsSymbol())
870     ValNullability = getNullabilityAnnotation(Sym->getType());
871 
872   Nullability LocNullability = getNullabilityAnnotation(LocType);
873   if (Filter.CheckNullPassedToNonnull &&
874       RhsNullness == NullConstraint::IsNull &&
875       ValNullability != Nullability::Nonnull &&
876       LocNullability == Nullability::Nonnull) {
877     static CheckerProgramPointTag Tag(this, "NullPassedToNonnull");
878     ExplodedNode *N = C.generateSink(State, C.getPredecessor(), &Tag);
879     reportBugIfPreconditionHolds(ErrorKind::NilAssignedToNonnull, N, nullptr, C,
880                                  S);
881     return;
882   }
883   // Intentionally missing case: '0' is bound to a reference. It is handled by
884   // the DereferenceChecker.
885 
886   const MemRegion *ValueRegion = getTrackRegion(*ValDefOrUnknown);
887   if (!ValueRegion)
888     return;
889 
890   const NullabilityState *TrackedNullability =
891       State->get<NullabilityMap>(ValueRegion);
892 
893   if (TrackedNullability) {
894     if (RhsNullness == NullConstraint::IsNotNull ||
895         TrackedNullability->getValue() != Nullability::Nullable)
896       return;
897     if (Filter.CheckNullablePassedToNonnull &&
898         LocNullability == Nullability::Nonnull) {
899       static CheckerProgramPointTag Tag(this, "NullablePassedToNonnull");
900       ExplodedNode *N = C.addTransition(State, C.getPredecessor(), &Tag);
901       reportBugIfPreconditionHolds(ErrorKind::NullableAssignedToNonnull, N,
902                                    ValueRegion, C);
903     }
904     return;
905   }
906 
907   const auto *BinOp = dyn_cast<BinaryOperator>(S);
908 
909   if (ValNullability == Nullability::Nullable) {
910     // Trust the static information of the value more than the static
911     // information on the location.
912     const Stmt *NullabilitySource = BinOp ? BinOp->getRHS() : S;
913     State = State->set<NullabilityMap>(
914         ValueRegion, NullabilityState(ValNullability, NullabilitySource));
915     C.addTransition(State);
916     return;
917   }
918 
919   if (LocNullability == Nullability::Nullable) {
920     const Stmt *NullabilitySource = BinOp ? BinOp->getLHS() : S;
921     State = State->set<NullabilityMap>(
922         ValueRegion, NullabilityState(LocNullability, NullabilitySource));
923     C.addTransition(State);
924   }
925 }
926 
927 void NullabilityChecker::printState(raw_ostream &Out, ProgramStateRef State,
928                                     const char *NL, const char *Sep) const {
929 
930   NullabilityMapTy B = State->get<NullabilityMap>();
931 
932   if (B.isEmpty())
933     return;
934 
935   Out << Sep << NL;
936 
937   for (NullabilityMapTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
938     Out << I->first << " : ";
939     I->second.print(Out);
940     Out << NL;
941   }
942 }
943 
944 #define REGISTER_CHECKER(name)                                                 \
945   void ento::register##name##Checker(CheckerManager &mgr) {                    \
946     NullabilityChecker *checker = mgr.registerChecker<NullabilityChecker>();   \
947     checker->Filter.Check##name = true;                                        \
948     checker->Filter.CheckName##name = mgr.getCurrentCheckName();               \
949   }
950 
951 REGISTER_CHECKER(NullPassedToNonnull)
952 REGISTER_CHECKER(NullReturnedFromNonnull)
953 REGISTER_CHECKER(NullableDereferenced)
954 REGISTER_CHECKER(NullablePassedToNonnull)
955 REGISTER_CHECKER(NullableReturnedFromNonnull)
956