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