NullabilityChecker.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  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. CheckerNameRef CheckNameNullPassedToNonnull;
  102. CheckerNameRef CheckNameNullReturnedFromNonnull;
  103. CheckerNameRef CheckNameNullableDereferenced;
  104. CheckerNameRef CheckNameNullablePassedToNonnull;
  105. CheckerNameRef 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. PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
  123. BugReporterContext &BRC,
  124. PathSensitiveBugReport &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 = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
  145. if (Region) {
  146. R->markInteresting(Region);
  147. R->addVisitor(std::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. PathDiagnosticPieceRef NullabilityChecker::NullabilityBugVisitor::VisitNode(
  251. const ExplodedNode *N, BugReporterContext &BRC,
  252. PathSensitiveBugReport &BR) {
  253. ProgramStateRef State = N->getState();
  254. ProgramStateRef StatePrev = N->getFirstPred()->getState();
  255. const NullabilityState *TrackedNullab = State->get<NullabilityMap>(Region);
  256. const NullabilityState *TrackedNullabPrev =
  257. StatePrev->get<NullabilityMap>(Region);
  258. if (!TrackedNullab)
  259. return nullptr;
  260. if (TrackedNullabPrev &&
  261. TrackedNullabPrev->getValue() == TrackedNullab->getValue())
  262. return nullptr;
  263. // Retrieve the associated statement.
  264. const Stmt *S = TrackedNullab->getNullabilitySource();
  265. if (!S || S->getBeginLoc().isInvalid()) {
  266. S = N->getStmtForDiagnostics();
  267. }
  268. if (!S)
  269. return nullptr;
  270. std::string InfoText =
  271. (llvm::Twine("Nullability '") +
  272. getNullabilityString(TrackedNullab->getValue()) + "' is inferred")
  273. .str();
  274. // Generate the extra diagnostic.
  275. PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
  276. N->getLocationContext());
  277. return std::make_shared<PathDiagnosticEventPiece>(Pos, InfoText, true);
  278. }
  279. /// Returns true when the value stored at the given location has been
  280. /// constrained to null after being passed through an object of nonnnull type.
  281. static bool checkValueAtLValForInvariantViolation(ProgramStateRef State,
  282. SVal LV, QualType T) {
  283. if (getNullabilityAnnotation(T) != Nullability::Nonnull)
  284. return false;
  285. auto RegionVal = LV.getAs<loc::MemRegionVal>();
  286. if (!RegionVal)
  287. return false;
  288. // If the value was constrained to null *after* it was passed through that
  289. // location, it could not have been a concrete pointer *when* it was passed.
  290. // In that case we would have handled the situation when the value was
  291. // bound to that location, by emitting (or not emitting) a report.
  292. // Therefore we are only interested in symbolic regions that can be either
  293. // null or non-null depending on the value of their respective symbol.
  294. auto StoredVal = State->getSVal(*RegionVal).getAs<loc::MemRegionVal>();
  295. if (!StoredVal || !isa<SymbolicRegion>(StoredVal->getRegion()))
  296. return false;
  297. if (getNullConstraint(*StoredVal, State) == NullConstraint::IsNull)
  298. return true;
  299. return false;
  300. }
  301. static bool
  302. checkParamsForPreconditionViolation(ArrayRef<ParmVarDecl *> Params,
  303. ProgramStateRef State,
  304. const LocationContext *LocCtxt) {
  305. for (const auto *ParamDecl : Params) {
  306. if (ParamDecl->isParameterPack())
  307. break;
  308. SVal LV = State->getLValue(ParamDecl, LocCtxt);
  309. if (checkValueAtLValForInvariantViolation(State, LV,
  310. ParamDecl->getType())) {
  311. return true;
  312. }
  313. }
  314. return false;
  315. }
  316. static bool
  317. checkSelfIvarsForInvariantViolation(ProgramStateRef State,
  318. const LocationContext *LocCtxt) {
  319. auto *MD = dyn_cast<ObjCMethodDecl>(LocCtxt->getDecl());
  320. if (!MD || !MD->isInstanceMethod())
  321. return false;
  322. const ImplicitParamDecl *SelfDecl = LocCtxt->getSelfDecl();
  323. if (!SelfDecl)
  324. return false;
  325. SVal SelfVal = State->getSVal(State->getRegion(SelfDecl, LocCtxt));
  326. const ObjCObjectPointerType *SelfType =
  327. dyn_cast<ObjCObjectPointerType>(SelfDecl->getType());
  328. if (!SelfType)
  329. return false;
  330. const ObjCInterfaceDecl *ID = SelfType->getInterfaceDecl();
  331. if (!ID)
  332. return false;
  333. for (const auto *IvarDecl : ID->ivars()) {
  334. SVal LV = State->getLValue(IvarDecl, SelfVal);
  335. if (checkValueAtLValForInvariantViolation(State, LV, IvarDecl->getType())) {
  336. return true;
  337. }
  338. }
  339. return false;
  340. }
  341. static bool checkInvariantViolation(ProgramStateRef State, ExplodedNode *N,
  342. CheckerContext &C) {
  343. if (State->get<InvariantViolated>())
  344. return true;
  345. const LocationContext *LocCtxt = C.getLocationContext();
  346. const Decl *D = LocCtxt->getDecl();
  347. if (!D)
  348. return false;
  349. ArrayRef<ParmVarDecl*> Params;
  350. if (const auto *BD = dyn_cast<BlockDecl>(D))
  351. Params = BD->parameters();
  352. else if (const auto *FD = dyn_cast<FunctionDecl>(D))
  353. Params = FD->parameters();
  354. else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
  355. Params = MD->parameters();
  356. else
  357. return false;
  358. if (checkParamsForPreconditionViolation(Params, State, LocCtxt) ||
  359. checkSelfIvarsForInvariantViolation(State, LocCtxt)) {
  360. if (!N->isSink())
  361. C.addTransition(State->set<InvariantViolated>(true), N);
  362. return true;
  363. }
  364. return false;
  365. }
  366. void NullabilityChecker::reportBugIfInvariantHolds(StringRef Msg,
  367. ErrorKind Error, ExplodedNode *N, const MemRegion *Region,
  368. CheckerContext &C, const Stmt *ValueExpr, bool SuppressPath) const {
  369. ProgramStateRef OriginalState = N->getState();
  370. if (checkInvariantViolation(OriginalState, N, C))
  371. return;
  372. if (SuppressPath) {
  373. OriginalState = OriginalState->set<InvariantViolated>(true);
  374. N = C.addTransition(OriginalState, N);
  375. }
  376. reportBug(Msg, Error, N, Region, C.getBugReporter(), ValueExpr);
  377. }
  378. /// Cleaning up the program state.
  379. void NullabilityChecker::checkDeadSymbols(SymbolReaper &SR,
  380. CheckerContext &C) const {
  381. ProgramStateRef State = C.getState();
  382. NullabilityMapTy Nullabilities = State->get<NullabilityMap>();
  383. for (NullabilityMapTy::iterator I = Nullabilities.begin(),
  384. E = Nullabilities.end();
  385. I != E; ++I) {
  386. const auto *Region = I->first->getAs<SymbolicRegion>();
  387. assert(Region && "Non-symbolic region is tracked.");
  388. if (SR.isDead(Region->getSymbol())) {
  389. State = State->remove<NullabilityMap>(I->first);
  390. }
  391. }
  392. // When one of the nonnull arguments are constrained to be null, nullability
  393. // preconditions are violated. It is not enough to check this only when we
  394. // actually report an error, because at that time interesting symbols might be
  395. // reaped.
  396. if (checkInvariantViolation(State, C.getPredecessor(), C))
  397. return;
  398. C.addTransition(State);
  399. }
  400. /// This callback triggers when a pointer is dereferenced and the analyzer does
  401. /// not know anything about the value of that pointer. When that pointer is
  402. /// nullable, this code emits a warning.
  403. void NullabilityChecker::checkEvent(ImplicitNullDerefEvent Event) const {
  404. if (Event.SinkNode->getState()->get<InvariantViolated>())
  405. return;
  406. const MemRegion *Region =
  407. getTrackRegion(Event.Location, /*CheckSuperRegion=*/true);
  408. if (!Region)
  409. return;
  410. ProgramStateRef State = Event.SinkNode->getState();
  411. const NullabilityState *TrackedNullability =
  412. State->get<NullabilityMap>(Region);
  413. if (!TrackedNullability)
  414. return;
  415. if (Filter.CheckNullableDereferenced &&
  416. TrackedNullability->getValue() == Nullability::Nullable) {
  417. BugReporter &BR = *Event.BR;
  418. // Do not suppress errors on defensive code paths, because dereferencing
  419. // a nullable pointer is always an error.
  420. if (Event.IsDirectDereference)
  421. reportBug("Nullable pointer is dereferenced",
  422. ErrorKind::NullableDereferenced, Event.SinkNode, Region, BR);
  423. else {
  424. reportBug("Nullable pointer is passed to a callee that requires a "
  425. "non-null", ErrorKind::NullablePassedToNonnull,
  426. Event.SinkNode, Region, BR);
  427. }
  428. }
  429. }
  430. /// Find the outermost subexpression of E that is not an implicit cast.
  431. /// This looks through the implicit casts to _Nonnull that ARC adds to
  432. /// return expressions of ObjC types when the return type of the function or
  433. /// method is non-null but the express is not.
  434. static const Expr *lookThroughImplicitCasts(const Expr *E) {
  435. assert(E);
  436. while (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
  437. E = ICE->getSubExpr();
  438. }
  439. return E;
  440. }
  441. /// This method check when nullable pointer or null value is returned from a
  442. /// function that has nonnull return type.
  443. void NullabilityChecker::checkPreStmt(const ReturnStmt *S,
  444. CheckerContext &C) const {
  445. auto RetExpr = S->getRetValue();
  446. if (!RetExpr)
  447. return;
  448. if (!RetExpr->getType()->isAnyPointerType())
  449. return;
  450. ProgramStateRef State = C.getState();
  451. if (State->get<InvariantViolated>())
  452. return;
  453. auto RetSVal = C.getSVal(S).getAs<DefinedOrUnknownSVal>();
  454. if (!RetSVal)
  455. return;
  456. bool InSuppressedMethodFamily = false;
  457. QualType RequiredRetType;
  458. AnalysisDeclContext *DeclCtxt =
  459. C.getLocationContext()->getAnalysisDeclContext();
  460. const Decl *D = DeclCtxt->getDecl();
  461. if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
  462. // HACK: This is a big hammer to avoid warning when there are defensive
  463. // nil checks in -init and -copy methods. We should add more sophisticated
  464. // logic here to suppress on common defensive idioms but still
  465. // warn when there is a likely problem.
  466. ObjCMethodFamily Family = MD->getMethodFamily();
  467. if (OMF_init == Family || OMF_copy == Family || OMF_mutableCopy == Family)
  468. InSuppressedMethodFamily = true;
  469. RequiredRetType = MD->getReturnType();
  470. } else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
  471. RequiredRetType = FD->getReturnType();
  472. } else {
  473. return;
  474. }
  475. NullConstraint Nullness = getNullConstraint(*RetSVal, State);
  476. Nullability RequiredNullability = getNullabilityAnnotation(RequiredRetType);
  477. // If the returned value is null but the type of the expression
  478. // generating it is nonnull then we will suppress the diagnostic.
  479. // This enables explicit suppression when returning a nil literal in a
  480. // function with a _Nonnull return type:
  481. // return (NSString * _Nonnull)0;
  482. Nullability RetExprTypeLevelNullability =
  483. getNullabilityAnnotation(lookThroughImplicitCasts(RetExpr)->getType());
  484. bool NullReturnedFromNonNull = (RequiredNullability == Nullability::Nonnull &&
  485. Nullness == NullConstraint::IsNull);
  486. if (Filter.CheckNullReturnedFromNonnull &&
  487. NullReturnedFromNonNull &&
  488. RetExprTypeLevelNullability != Nullability::Nonnull &&
  489. !InSuppressedMethodFamily &&
  490. C.getLocationContext()->inTopFrame()) {
  491. static CheckerProgramPointTag Tag(this, "NullReturnedFromNonnull");
  492. ExplodedNode *N = C.generateErrorNode(State, &Tag);
  493. if (!N)
  494. return;
  495. SmallString<256> SBuf;
  496. llvm::raw_svector_ostream OS(SBuf);
  497. OS << (RetExpr->getType()->isObjCObjectPointerType() ? "nil" : "Null");
  498. OS << " returned from a " << C.getDeclDescription(D) <<
  499. " that is expected to return a non-null value";
  500. reportBugIfInvariantHolds(OS.str(),
  501. ErrorKind::NilReturnedToNonnull, N, nullptr, C,
  502. RetExpr);
  503. return;
  504. }
  505. // If null was returned from a non-null function, mark the nullability
  506. // invariant as violated even if the diagnostic was suppressed.
  507. if (NullReturnedFromNonNull) {
  508. State = State->set<InvariantViolated>(true);
  509. C.addTransition(State);
  510. return;
  511. }
  512. const MemRegion *Region = getTrackRegion(*RetSVal);
  513. if (!Region)
  514. return;
  515. const NullabilityState *TrackedNullability =
  516. State->get<NullabilityMap>(Region);
  517. if (TrackedNullability) {
  518. Nullability TrackedNullabValue = TrackedNullability->getValue();
  519. if (Filter.CheckNullableReturnedFromNonnull &&
  520. Nullness != NullConstraint::IsNotNull &&
  521. TrackedNullabValue == Nullability::Nullable &&
  522. RequiredNullability == Nullability::Nonnull) {
  523. static CheckerProgramPointTag Tag(this, "NullableReturnedFromNonnull");
  524. ExplodedNode *N = C.addTransition(State, C.getPredecessor(), &Tag);
  525. SmallString<256> SBuf;
  526. llvm::raw_svector_ostream OS(SBuf);
  527. OS << "Nullable pointer is returned from a " << C.getDeclDescription(D) <<
  528. " that is expected to return a non-null value";
  529. reportBugIfInvariantHolds(OS.str(),
  530. ErrorKind::NullableReturnedToNonnull, N,
  531. Region, C);
  532. }
  533. return;
  534. }
  535. if (RequiredNullability == Nullability::Nullable) {
  536. State = State->set<NullabilityMap>(Region,
  537. NullabilityState(RequiredNullability,
  538. S));
  539. C.addTransition(State);
  540. }
  541. }
  542. /// This callback warns when a nullable pointer or a null value is passed to a
  543. /// function that expects its argument to be nonnull.
  544. void NullabilityChecker::checkPreCall(const CallEvent &Call,
  545. CheckerContext &C) const {
  546. if (!Call.getDecl())
  547. return;
  548. ProgramStateRef State = C.getState();
  549. if (State->get<InvariantViolated>())
  550. return;
  551. ProgramStateRef OrigState = State;
  552. unsigned Idx = 0;
  553. for (const ParmVarDecl *Param : Call.parameters()) {
  554. if (Param->isParameterPack())
  555. break;
  556. if (Idx >= Call.getNumArgs())
  557. break;
  558. const Expr *ArgExpr = Call.getArgExpr(Idx);
  559. auto ArgSVal = Call.getArgSVal(Idx++).getAs<DefinedOrUnknownSVal>();
  560. if (!ArgSVal)
  561. continue;
  562. if (!Param->getType()->isAnyPointerType() &&
  563. !Param->getType()->isReferenceType())
  564. continue;
  565. NullConstraint Nullness = getNullConstraint(*ArgSVal, State);
  566. Nullability RequiredNullability =
  567. getNullabilityAnnotation(Param->getType());
  568. Nullability ArgExprTypeLevelNullability =
  569. getNullabilityAnnotation(ArgExpr->getType());
  570. unsigned ParamIdx = Param->getFunctionScopeIndex() + 1;
  571. if (Filter.CheckNullPassedToNonnull && Nullness == NullConstraint::IsNull &&
  572. ArgExprTypeLevelNullability != Nullability::Nonnull &&
  573. RequiredNullability == Nullability::Nonnull &&
  574. isDiagnosableCall(Call)) {
  575. ExplodedNode *N = C.generateErrorNode(State);
  576. if (!N)
  577. return;
  578. SmallString<256> SBuf;
  579. llvm::raw_svector_ostream OS(SBuf);
  580. OS << (Param->getType()->isObjCObjectPointerType() ? "nil" : "Null");
  581. OS << " passed to a callee that requires a non-null " << ParamIdx
  582. << llvm::getOrdinalSuffix(ParamIdx) << " parameter";
  583. reportBugIfInvariantHolds(OS.str(), ErrorKind::NilPassedToNonnull, N,
  584. nullptr, C,
  585. ArgExpr, /*SuppressPath=*/false);
  586. return;
  587. }
  588. const MemRegion *Region = getTrackRegion(*ArgSVal);
  589. if (!Region)
  590. continue;
  591. const NullabilityState *TrackedNullability =
  592. State->get<NullabilityMap>(Region);
  593. if (TrackedNullability) {
  594. if (Nullness == NullConstraint::IsNotNull ||
  595. TrackedNullability->getValue() != Nullability::Nullable)
  596. continue;
  597. if (Filter.CheckNullablePassedToNonnull &&
  598. RequiredNullability == Nullability::Nonnull &&
  599. isDiagnosableCall(Call)) {
  600. ExplodedNode *N = C.addTransition(State);
  601. SmallString<256> SBuf;
  602. llvm::raw_svector_ostream OS(SBuf);
  603. OS << "Nullable pointer is passed to a callee that requires a non-null "
  604. << ParamIdx << llvm::getOrdinalSuffix(ParamIdx) << " parameter";
  605. reportBugIfInvariantHolds(OS.str(),
  606. ErrorKind::NullablePassedToNonnull, N,
  607. Region, C, ArgExpr, /*SuppressPath=*/true);
  608. return;
  609. }
  610. if (Filter.CheckNullableDereferenced &&
  611. Param->getType()->isReferenceType()) {
  612. ExplodedNode *N = C.addTransition(State);
  613. reportBugIfInvariantHolds("Nullable pointer is dereferenced",
  614. ErrorKind::NullableDereferenced, N, Region,
  615. C, ArgExpr, /*SuppressPath=*/true);
  616. return;
  617. }
  618. continue;
  619. }
  620. // No tracked nullability yet.
  621. if (ArgExprTypeLevelNullability != Nullability::Nullable)
  622. continue;
  623. State = State->set<NullabilityMap>(
  624. Region, NullabilityState(ArgExprTypeLevelNullability, ArgExpr));
  625. }
  626. if (State != OrigState)
  627. C.addTransition(State);
  628. }
  629. /// Suppress the nullability warnings for some functions.
  630. void NullabilityChecker::checkPostCall(const CallEvent &Call,
  631. CheckerContext &C) const {
  632. auto Decl = Call.getDecl();
  633. if (!Decl)
  634. return;
  635. // ObjC Messages handles in a different callback.
  636. if (Call.getKind() == CE_ObjCMessage)
  637. return;
  638. const FunctionType *FuncType = Decl->getFunctionType();
  639. if (!FuncType)
  640. return;
  641. QualType ReturnType = FuncType->getReturnType();
  642. if (!ReturnType->isAnyPointerType())
  643. return;
  644. ProgramStateRef State = C.getState();
  645. if (State->get<InvariantViolated>())
  646. return;
  647. const MemRegion *Region = getTrackRegion(Call.getReturnValue());
  648. if (!Region)
  649. return;
  650. // CG headers are misannotated. Do not warn for symbols that are the results
  651. // of CG calls.
  652. const SourceManager &SM = C.getSourceManager();
  653. StringRef FilePath = SM.getFilename(SM.getSpellingLoc(Decl->getBeginLoc()));
  654. if (llvm::sys::path::filename(FilePath).startswith("CG")) {
  655. State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
  656. C.addTransition(State);
  657. return;
  658. }
  659. const NullabilityState *TrackedNullability =
  660. State->get<NullabilityMap>(Region);
  661. if (!TrackedNullability &&
  662. getNullabilityAnnotation(ReturnType) == Nullability::Nullable) {
  663. State = State->set<NullabilityMap>(Region, Nullability::Nullable);
  664. C.addTransition(State);
  665. }
  666. }
  667. static Nullability getReceiverNullability(const ObjCMethodCall &M,
  668. ProgramStateRef State) {
  669. if (M.isReceiverSelfOrSuper()) {
  670. // For super and super class receivers we assume that the receiver is
  671. // nonnull.
  672. return Nullability::Nonnull;
  673. }
  674. // Otherwise look up nullability in the state.
  675. SVal Receiver = M.getReceiverSVal();
  676. if (auto DefOrUnknown = Receiver.getAs<DefinedOrUnknownSVal>()) {
  677. // If the receiver is constrained to be nonnull, assume that it is nonnull
  678. // regardless of its type.
  679. NullConstraint Nullness = getNullConstraint(*DefOrUnknown, State);
  680. if (Nullness == NullConstraint::IsNotNull)
  681. return Nullability::Nonnull;
  682. }
  683. auto ValueRegionSVal = Receiver.getAs<loc::MemRegionVal>();
  684. if (ValueRegionSVal) {
  685. const MemRegion *SelfRegion = ValueRegionSVal->getRegion();
  686. assert(SelfRegion);
  687. const NullabilityState *TrackedSelfNullability =
  688. State->get<NullabilityMap>(SelfRegion);
  689. if (TrackedSelfNullability)
  690. return TrackedSelfNullability->getValue();
  691. }
  692. return Nullability::Unspecified;
  693. }
  694. /// Calculate the nullability of the result of a message expr based on the
  695. /// nullability of the receiver, the nullability of the return value, and the
  696. /// constraints.
  697. void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M,
  698. CheckerContext &C) const {
  699. auto Decl = M.getDecl();
  700. if (!Decl)
  701. return;
  702. QualType RetType = Decl->getReturnType();
  703. if (!RetType->isAnyPointerType())
  704. return;
  705. ProgramStateRef State = C.getState();
  706. if (State->get<InvariantViolated>())
  707. return;
  708. const MemRegion *ReturnRegion = getTrackRegion(M.getReturnValue());
  709. if (!ReturnRegion)
  710. return;
  711. auto Interface = Decl->getClassInterface();
  712. auto Name = Interface ? Interface->getName() : "";
  713. // In order to reduce the noise in the diagnostics generated by this checker,
  714. // some framework and programming style based heuristics are used. These
  715. // heuristics are for Cocoa APIs which have NS prefix.
  716. if (Name.startswith("NS")) {
  717. // Developers rely on dynamic invariants such as an item should be available
  718. // in a collection, or a collection is not empty often. Those invariants can
  719. // not be inferred by any static analysis tool. To not to bother the users
  720. // with too many false positives, every item retrieval function should be
  721. // ignored for collections. The instance methods of dictionaries in Cocoa
  722. // are either item retrieval related or not interesting nullability wise.
  723. // Using this fact, to keep the code easier to read just ignore the return
  724. // value of every instance method of dictionaries.
  725. if (M.isInstanceMessage() && Name.contains("Dictionary")) {
  726. State =
  727. State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
  728. C.addTransition(State);
  729. return;
  730. }
  731. // For similar reasons ignore some methods of Cocoa arrays.
  732. StringRef FirstSelectorSlot = M.getSelector().getNameForSlot(0);
  733. if (Name.contains("Array") &&
  734. (FirstSelectorSlot == "firstObject" ||
  735. FirstSelectorSlot == "lastObject")) {
  736. State =
  737. State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
  738. C.addTransition(State);
  739. return;
  740. }
  741. // Encoding related methods of string should not fail when lossless
  742. // encodings are used. Using lossless encodings is so frequent that ignoring
  743. // this class of methods reduced the emitted diagnostics by about 30% on
  744. // some projects (and all of that was false positives).
  745. if (Name.contains("String")) {
  746. for (auto Param : M.parameters()) {
  747. if (Param->getName() == "encoding") {
  748. State = State->set<NullabilityMap>(ReturnRegion,
  749. Nullability::Contradicted);
  750. C.addTransition(State);
  751. return;
  752. }
  753. }
  754. }
  755. }
  756. const ObjCMessageExpr *Message = M.getOriginExpr();
  757. Nullability SelfNullability = getReceiverNullability(M, State);
  758. const NullabilityState *NullabilityOfReturn =
  759. State->get<NullabilityMap>(ReturnRegion);
  760. if (NullabilityOfReturn) {
  761. // When we have a nullability tracked for the return value, the nullability
  762. // of the expression will be the most nullable of the receiver and the
  763. // return value.
  764. Nullability RetValTracked = NullabilityOfReturn->getValue();
  765. Nullability ComputedNullab =
  766. getMostNullable(RetValTracked, SelfNullability);
  767. if (ComputedNullab != RetValTracked &&
  768. ComputedNullab != Nullability::Unspecified) {
  769. const Stmt *NullabilitySource =
  770. ComputedNullab == RetValTracked
  771. ? NullabilityOfReturn->getNullabilitySource()
  772. : Message->getInstanceReceiver();
  773. State = State->set<NullabilityMap>(
  774. ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
  775. C.addTransition(State);
  776. }
  777. return;
  778. }
  779. // No tracked information. Use static type information for return value.
  780. Nullability RetNullability = getNullabilityAnnotation(RetType);
  781. // Properties might be computed. For this reason the static analyzer creates a
  782. // new symbol each time an unknown property is read. To avoid false pozitives
  783. // do not treat unknown properties as nullable, even when they explicitly
  784. // marked nullable.
  785. if (M.getMessageKind() == OCM_PropertyAccess && !C.wasInlined)
  786. RetNullability = Nullability::Nonnull;
  787. Nullability ComputedNullab = getMostNullable(RetNullability, SelfNullability);
  788. if (ComputedNullab == Nullability::Nullable) {
  789. const Stmt *NullabilitySource = ComputedNullab == RetNullability
  790. ? Message
  791. : Message->getInstanceReceiver();
  792. State = State->set<NullabilityMap>(
  793. ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
  794. C.addTransition(State);
  795. }
  796. }
  797. /// Explicit casts are trusted. If there is a disagreement in the nullability
  798. /// annotations in the destination and the source or '0' is casted to nonnull
  799. /// track the value as having contraditory nullability. This will allow users to
  800. /// suppress warnings.
  801. void NullabilityChecker::checkPostStmt(const ExplicitCastExpr *CE,
  802. CheckerContext &C) const {
  803. QualType OriginType = CE->getSubExpr()->getType();
  804. QualType DestType = CE->getType();
  805. if (!OriginType->isAnyPointerType())
  806. return;
  807. if (!DestType->isAnyPointerType())
  808. return;
  809. ProgramStateRef State = C.getState();
  810. if (State->get<InvariantViolated>())
  811. return;
  812. Nullability DestNullability = getNullabilityAnnotation(DestType);
  813. // No explicit nullability in the destination type, so this cast does not
  814. // change the nullability.
  815. if (DestNullability == Nullability::Unspecified)
  816. return;
  817. auto RegionSVal = C.getSVal(CE).getAs<DefinedOrUnknownSVal>();
  818. const MemRegion *Region = getTrackRegion(*RegionSVal);
  819. if (!Region)
  820. return;
  821. // When 0 is converted to nonnull mark it as contradicted.
  822. if (DestNullability == Nullability::Nonnull) {
  823. NullConstraint Nullness = getNullConstraint(*RegionSVal, State);
  824. if (Nullness == NullConstraint::IsNull) {
  825. State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
  826. C.addTransition(State);
  827. return;
  828. }
  829. }
  830. const NullabilityState *TrackedNullability =
  831. State->get<NullabilityMap>(Region);
  832. if (!TrackedNullability) {
  833. if (DestNullability != Nullability::Nullable)
  834. return;
  835. State = State->set<NullabilityMap>(Region,
  836. NullabilityState(DestNullability, CE));
  837. C.addTransition(State);
  838. return;
  839. }
  840. if (TrackedNullability->getValue() != DestNullability &&
  841. TrackedNullability->getValue() != Nullability::Contradicted) {
  842. State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
  843. C.addTransition(State);
  844. }
  845. }
  846. /// For a given statement performing a bind, attempt to syntactically
  847. /// match the expression resulting in the bound value.
  848. static const Expr * matchValueExprForBind(const Stmt *S) {
  849. // For `x = e` the value expression is the right-hand side.
  850. if (auto *BinOp = dyn_cast<BinaryOperator>(S)) {
  851. if (BinOp->getOpcode() == BO_Assign)
  852. return BinOp->getRHS();
  853. }
  854. // For `int x = e` the value expression is the initializer.
  855. if (auto *DS = dyn_cast<DeclStmt>(S)) {
  856. if (DS->isSingleDecl()) {
  857. auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
  858. if (!VD)
  859. return nullptr;
  860. if (const Expr *Init = VD->getInit())
  861. return Init;
  862. }
  863. }
  864. return nullptr;
  865. }
  866. /// Returns true if \param S is a DeclStmt for a local variable that
  867. /// ObjC automated reference counting initialized with zero.
  868. static bool isARCNilInitializedLocal(CheckerContext &C, const Stmt *S) {
  869. // We suppress diagnostics for ARC zero-initialized _Nonnull locals. This
  870. // prevents false positives when a _Nonnull local variable cannot be
  871. // initialized with an initialization expression:
  872. // NSString * _Nonnull s; // no-warning
  873. // @autoreleasepool {
  874. // s = ...
  875. // }
  876. //
  877. // FIXME: We should treat implicitly zero-initialized _Nonnull locals as
  878. // uninitialized in Sema's UninitializedValues analysis to warn when a use of
  879. // the zero-initialized definition will unexpectedly yield nil.
  880. // Locals are only zero-initialized when automated reference counting
  881. // is turned on.
  882. if (!C.getASTContext().getLangOpts().ObjCAutoRefCount)
  883. return false;
  884. auto *DS = dyn_cast<DeclStmt>(S);
  885. if (!DS || !DS->isSingleDecl())
  886. return false;
  887. auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
  888. if (!VD)
  889. return false;
  890. // Sema only zero-initializes locals with ObjCLifetimes.
  891. if(!VD->getType().getQualifiers().hasObjCLifetime())
  892. return false;
  893. const Expr *Init = VD->getInit();
  894. assert(Init && "ObjC local under ARC without initializer");
  895. // Return false if the local is explicitly initialized (e.g., with '= nil').
  896. if (!isa<ImplicitValueInitExpr>(Init))
  897. return false;
  898. return true;
  899. }
  900. /// Propagate the nullability information through binds and warn when nullable
  901. /// pointer or null symbol is assigned to a pointer with a nonnull type.
  902. void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S,
  903. CheckerContext &C) const {
  904. const TypedValueRegion *TVR =
  905. dyn_cast_or_null<TypedValueRegion>(L.getAsRegion());
  906. if (!TVR)
  907. return;
  908. QualType LocType = TVR->getValueType();
  909. if (!LocType->isAnyPointerType())
  910. return;
  911. ProgramStateRef State = C.getState();
  912. if (State->get<InvariantViolated>())
  913. return;
  914. auto ValDefOrUnknown = V.getAs<DefinedOrUnknownSVal>();
  915. if (!ValDefOrUnknown)
  916. return;
  917. NullConstraint RhsNullness = getNullConstraint(*ValDefOrUnknown, State);
  918. Nullability ValNullability = Nullability::Unspecified;
  919. if (SymbolRef Sym = ValDefOrUnknown->getAsSymbol())
  920. ValNullability = getNullabilityAnnotation(Sym->getType());
  921. Nullability LocNullability = getNullabilityAnnotation(LocType);
  922. // If the type of the RHS expression is nonnull, don't warn. This
  923. // enables explicit suppression with a cast to nonnull.
  924. Nullability ValueExprTypeLevelNullability = Nullability::Unspecified;
  925. const Expr *ValueExpr = matchValueExprForBind(S);
  926. if (ValueExpr) {
  927. ValueExprTypeLevelNullability =
  928. getNullabilityAnnotation(lookThroughImplicitCasts(ValueExpr)->getType());
  929. }
  930. bool NullAssignedToNonNull = (LocNullability == Nullability::Nonnull &&
  931. RhsNullness == NullConstraint::IsNull);
  932. if (Filter.CheckNullPassedToNonnull &&
  933. NullAssignedToNonNull &&
  934. ValNullability != Nullability::Nonnull &&
  935. ValueExprTypeLevelNullability != Nullability::Nonnull &&
  936. !isARCNilInitializedLocal(C, S)) {
  937. static CheckerProgramPointTag Tag(this, "NullPassedToNonnull");
  938. ExplodedNode *N = C.generateErrorNode(State, &Tag);
  939. if (!N)
  940. return;
  941. const Stmt *ValueStmt = S;
  942. if (ValueExpr)
  943. ValueStmt = ValueExpr;
  944. SmallString<256> SBuf;
  945. llvm::raw_svector_ostream OS(SBuf);
  946. OS << (LocType->isObjCObjectPointerType() ? "nil" : "Null");
  947. OS << " assigned to a pointer which is expected to have non-null value";
  948. reportBugIfInvariantHolds(OS.str(),
  949. ErrorKind::NilAssignedToNonnull, N, nullptr, C,
  950. ValueStmt);
  951. return;
  952. }
  953. // If null was returned from a non-null function, mark the nullability
  954. // invariant as violated even if the diagnostic was suppressed.
  955. if (NullAssignedToNonNull) {
  956. State = State->set<InvariantViolated>(true);
  957. C.addTransition(State);
  958. return;
  959. }
  960. // Intentionally missing case: '0' is bound to a reference. It is handled by
  961. // the DereferenceChecker.
  962. const MemRegion *ValueRegion = getTrackRegion(*ValDefOrUnknown);
  963. if (!ValueRegion)
  964. return;
  965. const NullabilityState *TrackedNullability =
  966. State->get<NullabilityMap>(ValueRegion);
  967. if (TrackedNullability) {
  968. if (RhsNullness == NullConstraint::IsNotNull ||
  969. TrackedNullability->getValue() != Nullability::Nullable)
  970. return;
  971. if (Filter.CheckNullablePassedToNonnull &&
  972. LocNullability == Nullability::Nonnull) {
  973. static CheckerProgramPointTag Tag(this, "NullablePassedToNonnull");
  974. ExplodedNode *N = C.addTransition(State, C.getPredecessor(), &Tag);
  975. reportBugIfInvariantHolds("Nullable pointer is assigned to a pointer "
  976. "which is expected to have non-null value",
  977. ErrorKind::NullableAssignedToNonnull, N,
  978. ValueRegion, C);
  979. }
  980. return;
  981. }
  982. const auto *BinOp = dyn_cast<BinaryOperator>(S);
  983. if (ValNullability == Nullability::Nullable) {
  984. // Trust the static information of the value more than the static
  985. // information on the location.
  986. const Stmt *NullabilitySource = BinOp ? BinOp->getRHS() : S;
  987. State = State->set<NullabilityMap>(
  988. ValueRegion, NullabilityState(ValNullability, NullabilitySource));
  989. C.addTransition(State);
  990. return;
  991. }
  992. if (LocNullability == Nullability::Nullable) {
  993. const Stmt *NullabilitySource = BinOp ? BinOp->getLHS() : S;
  994. State = State->set<NullabilityMap>(
  995. ValueRegion, NullabilityState(LocNullability, NullabilitySource));
  996. C.addTransition(State);
  997. }
  998. }
  999. void NullabilityChecker::printState(raw_ostream &Out, ProgramStateRef State,
  1000. const char *NL, const char *Sep) const {
  1001. NullabilityMapTy B = State->get<NullabilityMap>();
  1002. if (State->get<InvariantViolated>())
  1003. Out << Sep << NL
  1004. << "Nullability invariant was violated, warnings suppressed." << NL;
  1005. if (B.isEmpty())
  1006. return;
  1007. if (!State->get<InvariantViolated>())
  1008. Out << Sep << NL;
  1009. for (NullabilityMapTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
  1010. Out << I->first << " : ";
  1011. I->second.print(Out);
  1012. Out << NL;
  1013. }
  1014. }
  1015. void ento::registerNullabilityBase(CheckerManager &mgr) {
  1016. mgr.registerChecker<NullabilityChecker>();
  1017. }
  1018. bool ento::shouldRegisterNullabilityBase(const LangOptions &LO) {
  1019. return true;
  1020. }
  1021. #define REGISTER_CHECKER(name, trackingRequired) \
  1022. void ento::register##name##Checker(CheckerManager &mgr) { \
  1023. NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>(); \
  1024. checker->Filter.Check##name = true; \
  1025. checker->Filter.CheckName##name = mgr.getCurrentCheckerName(); \
  1026. checker->NeedTracking = checker->NeedTracking || trackingRequired; \
  1027. checker->NoDiagnoseCallsToSystemHeaders = \
  1028. checker->NoDiagnoseCallsToSystemHeaders || \
  1029. mgr.getAnalyzerOptions().getCheckerBooleanOption( \
  1030. checker, "NoDiagnoseCallsToSystemHeaders", true); \
  1031. } \
  1032. \
  1033. bool ento::shouldRegister##name##Checker(const LangOptions &LO) { \
  1034. return true; \
  1035. }
  1036. // The checks are likely to be turned on by default and it is possible to do
  1037. // them without tracking any nullability related information. As an optimization
  1038. // no nullability information will be tracked when only these two checks are
  1039. // enables.
  1040. REGISTER_CHECKER(NullPassedToNonnull, false)
  1041. REGISTER_CHECKER(NullReturnedFromNonnull, false)
  1042. REGISTER_CHECKER(NullableDereferenced, true)
  1043. REGISTER_CHECKER(NullablePassedToNonnull, true)
  1044. REGISTER_CHECKER(NullableReturnedFromNonnull, true)