NullabilityChecker.cpp 45 KB

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