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