clang  3.9.0
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 agressively 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 [reciever 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  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", "Memory error"));
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 PathDiagnosticPiece *NullabilityChecker::NullabilityBugVisitor::VisitNode(
310  const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
311  BugReport &BR) {
313  ProgramStateRef StatePrev = PrevN->getState();
314 
315  const NullabilityState *TrackedNullab = State->get<NullabilityMap>(Region);
316  const NullabilityState *TrackedNullabPrev =
317  StatePrev->get<NullabilityMap>(Region);
318  if (!TrackedNullab)
319  return nullptr;
320 
321  if (TrackedNullabPrev &&
322  TrackedNullabPrev->getValue() == TrackedNullab->getValue())
323  return nullptr;
324 
325  // Retrieve the associated statement.
326  const Stmt *S = TrackedNullab->getNullabilitySource();
327  if (!S) {
328  ProgramPoint ProgLoc = N->getLocation();
329  if (Optional<StmtPoint> SP = ProgLoc.getAs<StmtPoint>()) {
330  S = SP->getStmt();
331  }
332  }
333 
334  if (!S)
335  return nullptr;
336 
337  std::string InfoText =
338  (llvm::Twine("Nullability '") +
339  getNullabilityString(TrackedNullab->getValue()) + "' is infered")
340  .str();
341 
342  // Generate the extra diagnostic.
344  N->getLocationContext());
345  return new PathDiagnosticEventPiece(Pos, InfoText, true, 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
383  ProgramStateRef State,
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 
479  ProgramStateRef State = C.getState();
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 
511  ProgramStateRef State = Event.SinkNode->getState();
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 
559  ProgramStateRef State = C.getState();
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 << "Null is returned from a " << C.getDeclDescription(D) <<
617  " that is expected to return a non-null value";
618 
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 
674  ProgramStateRef State = C.getState();
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  const Expr *ArgExpr = nullptr;
686  if (Idx < Call.getNumArgs())
687  ArgExpr = Call.getArgExpr(Idx);
688  auto ArgSVal = Call.getArgSVal(Idx++).getAs<DefinedOrUnknownSVal>();
689  if (!ArgSVal)
690  continue;
691 
692  if (!Param->getType()->isAnyPointerType() &&
693  !Param->getType()->isReferenceType())
694  continue;
695 
696  NullConstraint Nullness = getNullConstraint(*ArgSVal, State);
697 
698  Nullability RequiredNullability =
699  getNullabilityAnnotation(Param->getType());
700  Nullability ArgExprTypeLevelNullability =
701  getNullabilityAnnotation(ArgExpr->getType());
702 
703  unsigned ParamIdx = Param->getFunctionScopeIndex() + 1;
704 
705  if (Filter.CheckNullPassedToNonnull && Nullness == NullConstraint::IsNull &&
706  ArgExprTypeLevelNullability != Nullability::Nonnull &&
707  RequiredNullability == Nullability::Nonnull &&
708  isDiagnosableCall(Call)) {
709  ExplodedNode *N = C.generateErrorNode(State);
710  if (!N)
711  return;
712  SmallString<256> SBuf;
713  llvm::raw_svector_ostream OS(SBuf);
714  OS << "Null passed to a callee that requires a non-null " << ParamIdx
715  << llvm::getOrdinalSuffix(ParamIdx) << " parameter";
716  reportBugIfInvariantHolds(OS.str(), ErrorKind::NilPassedToNonnull, N,
717  nullptr, C,
718  ArgExpr, /*SuppressPath=*/false);
719  return;
720  }
721 
722  const MemRegion *Region = getTrackRegion(*ArgSVal);
723  if (!Region)
724  continue;
725 
726  const NullabilityState *TrackedNullability =
727  State->get<NullabilityMap>(Region);
728 
729  if (TrackedNullability) {
730  if (Nullness == NullConstraint::IsNotNull ||
731  TrackedNullability->getValue() != Nullability::Nullable)
732  continue;
733 
734  if (Filter.CheckNullablePassedToNonnull &&
735  RequiredNullability == Nullability::Nonnull &&
736  isDiagnosableCall(Call)) {
737  ExplodedNode *N = C.addTransition(State);
738  SmallString<256> SBuf;
739  llvm::raw_svector_ostream OS(SBuf);
740  OS << "Nullable pointer is passed to a callee that requires a non-null "
741  << ParamIdx << llvm::getOrdinalSuffix(ParamIdx) << " parameter";
742  reportBugIfInvariantHolds(OS.str(),
743  ErrorKind::NullablePassedToNonnull, N,
744  Region, C, ArgExpr, /*SuppressPath=*/true);
745  return;
746  }
747  if (Filter.CheckNullableDereferenced &&
748  Param->getType()->isReferenceType()) {
749  ExplodedNode *N = C.addTransition(State);
750  reportBugIfInvariantHolds("Nullable pointer is dereferenced",
751  ErrorKind::NullableDereferenced, N, Region,
752  C, ArgExpr, /*SuppressPath=*/true);
753  return;
754  }
755  continue;
756  }
757  // No tracked nullability yet.
758  if (ArgExprTypeLevelNullability != Nullability::Nullable)
759  continue;
760  State = State->set<NullabilityMap>(
761  Region, NullabilityState(ArgExprTypeLevelNullability, ArgExpr));
762  }
763  if (State != OrigState)
764  C.addTransition(State);
765 }
766 
767 /// Suppress the nullability warnings for some functions.
768 void NullabilityChecker::checkPostCall(const CallEvent &Call,
769  CheckerContext &C) const {
770  auto Decl = Call.getDecl();
771  if (!Decl)
772  return;
773  // ObjC Messages handles in a different callback.
774  if (Call.getKind() == CE_ObjCMessage)
775  return;
776  const FunctionType *FuncType = Decl->getFunctionType();
777  if (!FuncType)
778  return;
779  QualType ReturnType = FuncType->getReturnType();
780  if (!ReturnType->isAnyPointerType())
781  return;
782  ProgramStateRef State = C.getState();
783  if (State->get<InvariantViolated>())
784  return;
785 
786  const MemRegion *Region = getTrackRegion(Call.getReturnValue());
787  if (!Region)
788  return;
789 
790  // CG headers are misannotated. Do not warn for symbols that are the results
791  // of CG calls.
792  const SourceManager &SM = C.getSourceManager();
793  StringRef FilePath = SM.getFilename(SM.getSpellingLoc(Decl->getLocStart()));
794  if (llvm::sys::path::filename(FilePath).startswith("CG")) {
795  State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
796  C.addTransition(State);
797  return;
798  }
799 
800  const NullabilityState *TrackedNullability =
801  State->get<NullabilityMap>(Region);
802 
803  if (!TrackedNullability &&
805  State = State->set<NullabilityMap>(Region, Nullability::Nullable);
806  C.addTransition(State);
807  }
808 }
809 
811  ProgramStateRef State) {
812  if (M.isReceiverSelfOrSuper()) {
813  // For super and super class receivers we assume that the receiver is
814  // nonnull.
815  return Nullability::Nonnull;
816  }
817  // Otherwise look up nullability in the state.
818  SVal Receiver = M.getReceiverSVal();
819  if (auto DefOrUnknown = Receiver.getAs<DefinedOrUnknownSVal>()) {
820  // If the receiver is constrained to be nonnull, assume that it is nonnull
821  // regardless of its type.
822  NullConstraint Nullness = getNullConstraint(*DefOrUnknown, State);
823  if (Nullness == NullConstraint::IsNotNull)
824  return Nullability::Nonnull;
825  }
826  auto ValueRegionSVal = Receiver.getAs<loc::MemRegionVal>();
827  if (ValueRegionSVal) {
828  const MemRegion *SelfRegion = ValueRegionSVal->getRegion();
829  assert(SelfRegion);
830 
831  const NullabilityState *TrackedSelfNullability =
832  State->get<NullabilityMap>(SelfRegion);
833  if (TrackedSelfNullability)
834  return TrackedSelfNullability->getValue();
835  }
837 }
838 
839 /// Calculate the nullability of the result of a message expr based on the
840 /// nullability of the receiver, the nullability of the return value, and the
841 /// constraints.
842 void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M,
843  CheckerContext &C) const {
844  auto Decl = M.getDecl();
845  if (!Decl)
846  return;
847  QualType RetType = Decl->getReturnType();
848  if (!RetType->isAnyPointerType())
849  return;
850 
851  ProgramStateRef State = C.getState();
852  if (State->get<InvariantViolated>())
853  return;
854 
855  const MemRegion *ReturnRegion = getTrackRegion(M.getReturnValue());
856  if (!ReturnRegion)
857  return;
858 
859  auto Interface = Decl->getClassInterface();
860  auto Name = Interface ? Interface->getName() : "";
861  // In order to reduce the noise in the diagnostics generated by this checker,
862  // some framework and programming style based heuristics are used. These
863  // heuristics are for Cocoa APIs which have NS prefix.
864  if (Name.startswith("NS")) {
865  // Developers rely on dynamic invariants such as an item should be available
866  // in a collection, or a collection is not empty often. Those invariants can
867  // not be inferred by any static analysis tool. To not to bother the users
868  // with too many false positives, every item retrieval function should be
869  // ignored for collections. The instance methods of dictionaries in Cocoa
870  // are either item retrieval related or not interesting nullability wise.
871  // Using this fact, to keep the code easier to read just ignore the return
872  // value of every instance method of dictionaries.
873  if (M.isInstanceMessage() && Name.find("Dictionary") != StringRef::npos) {
874  State =
875  State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
876  C.addTransition(State);
877  return;
878  }
879  // For similar reasons ignore some methods of Cocoa arrays.
880  StringRef FirstSelectorSlot = M.getSelector().getNameForSlot(0);
881  if (Name.find("Array") != StringRef::npos &&
882  (FirstSelectorSlot == "firstObject" ||
883  FirstSelectorSlot == "lastObject")) {
884  State =
885  State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
886  C.addTransition(State);
887  return;
888  }
889 
890  // Encoding related methods of string should not fail when lossless
891  // encodings are used. Using lossless encodings is so frequent that ignoring
892  // this class of methods reduced the emitted diagnostics by about 30% on
893  // some projects (and all of that was false positives).
894  if (Name.find("String") != StringRef::npos) {
895  for (auto Param : M.parameters()) {
896  if (Param->getName() == "encoding") {
897  State = State->set<NullabilityMap>(ReturnRegion,
898  Nullability::Contradicted);
899  C.addTransition(State);
900  return;
901  }
902  }
903  }
904  }
905 
906  const ObjCMessageExpr *Message = M.getOriginExpr();
907  Nullability SelfNullability = getReceiverNullability(M, State);
908 
909  const NullabilityState *NullabilityOfReturn =
910  State->get<NullabilityMap>(ReturnRegion);
911 
912  if (NullabilityOfReturn) {
913  // When we have a nullability tracked for the return value, the nullability
914  // of the expression will be the most nullable of the receiver and the
915  // return value.
916  Nullability RetValTracked = NullabilityOfReturn->getValue();
917  Nullability ComputedNullab =
918  getMostNullable(RetValTracked, SelfNullability);
919  if (ComputedNullab != RetValTracked &&
920  ComputedNullab != Nullability::Unspecified) {
921  const Stmt *NullabilitySource =
922  ComputedNullab == RetValTracked
923  ? NullabilityOfReturn->getNullabilitySource()
924  : Message->getInstanceReceiver();
925  State = State->set<NullabilityMap>(
926  ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
927  C.addTransition(State);
928  }
929  return;
930  }
931 
932  // No tracked information. Use static type information for return value.
933  Nullability RetNullability = getNullabilityAnnotation(RetType);
934 
935  // Properties might be computed. For this reason the static analyzer creates a
936  // new symbol each time an unknown property is read. To avoid false pozitives
937  // do not treat unknown properties as nullable, even when they explicitly
938  // marked nullable.
940  RetNullability = Nullability::Nonnull;
941 
942  Nullability ComputedNullab = getMostNullable(RetNullability, SelfNullability);
943  if (ComputedNullab == Nullability::Nullable) {
944  const Stmt *NullabilitySource = ComputedNullab == RetNullability
945  ? Message
946  : Message->getInstanceReceiver();
947  State = State->set<NullabilityMap>(
948  ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
949  C.addTransition(State);
950  }
951 }
952 
953 /// Explicit casts are trusted. If there is a disagreement in the nullability
954 /// annotations in the destination and the source or '0' is casted to nonnull
955 /// track the value as having contraditory nullability. This will allow users to
956 /// suppress warnings.
957 void NullabilityChecker::checkPostStmt(const ExplicitCastExpr *CE,
958  CheckerContext &C) const {
959  QualType OriginType = CE->getSubExpr()->getType();
960  QualType DestType = CE->getType();
961  if (!OriginType->isAnyPointerType())
962  return;
963  if (!DestType->isAnyPointerType())
964  return;
965 
966  ProgramStateRef State = C.getState();
967  if (State->get<InvariantViolated>())
968  return;
969 
970  Nullability DestNullability = getNullabilityAnnotation(DestType);
971 
972  // No explicit nullability in the destination type, so this cast does not
973  // change the nullability.
974  if (DestNullability == Nullability::Unspecified)
975  return;
976 
977  auto RegionSVal =
978  State->getSVal(CE, C.getLocationContext()).getAs<DefinedOrUnknownSVal>();
979  const MemRegion *Region = getTrackRegion(*RegionSVal);
980  if (!Region)
981  return;
982 
983  // When 0 is converted to nonnull mark it as contradicted.
984  if (DestNullability == Nullability::Nonnull) {
985  NullConstraint Nullness = getNullConstraint(*RegionSVal, State);
986  if (Nullness == NullConstraint::IsNull) {
987  State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
988  C.addTransition(State);
989  return;
990  }
991  }
992 
993  const NullabilityState *TrackedNullability =
994  State->get<NullabilityMap>(Region);
995 
996  if (!TrackedNullability) {
997  if (DestNullability != Nullability::Nullable)
998  return;
999  State = State->set<NullabilityMap>(Region,
1000  NullabilityState(DestNullability, CE));
1001  C.addTransition(State);
1002  return;
1003  }
1004 
1005  if (TrackedNullability->getValue() != DestNullability &&
1006  TrackedNullability->getValue() != Nullability::Contradicted) {
1007  State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
1008  C.addTransition(State);
1009  }
1010 }
1011 
1012 /// For a given statement performing a bind, attempt to syntactically
1013 /// match the expression resulting in the bound value.
1014 static const Expr * matchValueExprForBind(const Stmt *S) {
1015  // For `x = e` the value expression is the right-hand side.
1016  if (auto *BinOp = dyn_cast<BinaryOperator>(S)) {
1017  if (BinOp->getOpcode() == BO_Assign)
1018  return BinOp->getRHS();
1019  }
1020 
1021  // For `int x = e` the value expression is the initializer.
1022  if (auto *DS = dyn_cast<DeclStmt>(S)) {
1023  if (DS->isSingleDecl()) {
1024  auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
1025  if (!VD)
1026  return nullptr;
1027 
1028  if (const Expr *Init = VD->getInit())
1029  return Init;
1030  }
1031  }
1032 
1033  return nullptr;
1034 }
1035 
1036 /// Returns true if \param S is a DeclStmt for a local variable that
1037 /// ObjC automated reference counting initialized with zero.
1038 static bool isARCNilInitializedLocal(CheckerContext &C, const Stmt *S) {
1039  // We suppress diagnostics for ARC zero-initialized _Nonnull locals. This
1040  // prevents false positives when a _Nonnull local variable cannot be
1041  // initialized with an initialization expression:
1042  // NSString * _Nonnull s; // no-warning
1043  // @autoreleasepool {
1044  // s = ...
1045  // }
1046  //
1047  // FIXME: We should treat implicitly zero-initialized _Nonnull locals as
1048  // uninitialized in Sema's UninitializedValues analysis to warn when a use of
1049  // the zero-initialized definition will unexpectedly yield nil.
1050 
1051  // Locals are only zero-initialized when automated reference counting
1052  // is turned on.
1053  if (!C.getASTContext().getLangOpts().ObjCAutoRefCount)
1054  return false;
1055 
1056  auto *DS = dyn_cast<DeclStmt>(S);
1057  if (!DS || !DS->isSingleDecl())
1058  return false;
1059 
1060  auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
1061  if (!VD)
1062  return false;
1063 
1064  // Sema only zero-initializes locals with ObjCLifetimes.
1065  if(!VD->getType().getQualifiers().hasObjCLifetime())
1066  return false;
1067 
1068  const Expr *Init = VD->getInit();
1069  assert(Init && "ObjC local under ARC without initializer");
1070 
1071  // Return false if the local is explicitly initialized (e.g., with '= nil').
1072  if (!isa<ImplicitValueInitExpr>(Init))
1073  return false;
1074 
1075  return true;
1076 }
1077 
1078 /// Propagate the nullability information through binds and warn when nullable
1079 /// pointer or null symbol is assigned to a pointer with a nonnull type.
1080 void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S,
1081  CheckerContext &C) const {
1082  const TypedValueRegion *TVR =
1083  dyn_cast_or_null<TypedValueRegion>(L.getAsRegion());
1084  if (!TVR)
1085  return;
1086 
1087  QualType LocType = TVR->getValueType();
1088  if (!LocType->isAnyPointerType())
1089  return;
1090 
1091  ProgramStateRef State = C.getState();
1092  if (State->get<InvariantViolated>())
1093  return;
1094 
1095  auto ValDefOrUnknown = V.getAs<DefinedOrUnknownSVal>();
1096  if (!ValDefOrUnknown)
1097  return;
1098 
1099  NullConstraint RhsNullness = getNullConstraint(*ValDefOrUnknown, State);
1100 
1101  Nullability ValNullability = Nullability::Unspecified;
1102  if (SymbolRef Sym = ValDefOrUnknown->getAsSymbol())
1103  ValNullability = getNullabilityAnnotation(Sym->getType());
1104 
1105  Nullability LocNullability = getNullabilityAnnotation(LocType);
1106 
1107  // If the type of the RHS expression is nonnull, don't warn. This
1108  // enables explicit suppression with a cast to nonnull.
1109  Nullability ValueExprTypeLevelNullability = Nullability::Unspecified;
1110  const Expr *ValueExpr = matchValueExprForBind(S);
1111  if (ValueExpr) {
1112  ValueExprTypeLevelNullability =
1113  getNullabilityAnnotation(lookThroughImplicitCasts(ValueExpr)->getType());
1114  }
1115 
1116  bool NullAssignedToNonNull = (LocNullability == Nullability::Nonnull &&
1117  RhsNullness == NullConstraint::IsNull);
1118  if (Filter.CheckNullPassedToNonnull &&
1119  NullAssignedToNonNull &&
1120  ValNullability != Nullability::Nonnull &&
1121  ValueExprTypeLevelNullability != Nullability::Nonnull &&
1122  !isARCNilInitializedLocal(C, S)) {
1123  static CheckerProgramPointTag Tag(this, "NullPassedToNonnull");
1124  ExplodedNode *N = C.generateErrorNode(State, &Tag);
1125  if (!N)
1126  return;
1127 
1128 
1129  const Stmt *ValueStmt = S;
1130  if (ValueExpr)
1131  ValueStmt = ValueExpr;
1132 
1133  reportBugIfInvariantHolds("Null is assigned to a pointer which is "
1134  "expected to have non-null value",
1135  ErrorKind::NilAssignedToNonnull, N, nullptr, C,
1136  ValueStmt);
1137  return;
1138  }
1139 
1140  // If null was returned from a non-null function, mark the nullability
1141  // invariant as violated even if the diagnostic was suppressed.
1142  if (NullAssignedToNonNull) {
1143  State = State->set<InvariantViolated>(true);
1144  C.addTransition(State);
1145  return;
1146  }
1147 
1148  // Intentionally missing case: '0' is bound to a reference. It is handled by
1149  // the DereferenceChecker.
1150 
1151  const MemRegion *ValueRegion = getTrackRegion(*ValDefOrUnknown);
1152  if (!ValueRegion)
1153  return;
1154 
1155  const NullabilityState *TrackedNullability =
1156  State->get<NullabilityMap>(ValueRegion);
1157 
1158  if (TrackedNullability) {
1159  if (RhsNullness == NullConstraint::IsNotNull ||
1160  TrackedNullability->getValue() != Nullability::Nullable)
1161  return;
1162  if (Filter.CheckNullablePassedToNonnull &&
1163  LocNullability == Nullability::Nonnull) {
1164  static CheckerProgramPointTag Tag(this, "NullablePassedToNonnull");
1165  ExplodedNode *N = C.addTransition(State, C.getPredecessor(), &Tag);
1166  reportBugIfInvariantHolds("Nullable pointer is assigned to a pointer "
1167  "which is expected to have non-null value",
1168  ErrorKind::NullableAssignedToNonnull, N,
1169  ValueRegion, C);
1170  }
1171  return;
1172  }
1173 
1174  const auto *BinOp = dyn_cast<BinaryOperator>(S);
1175 
1176  if (ValNullability == Nullability::Nullable) {
1177  // Trust the static information of the value more than the static
1178  // information on the location.
1179  const Stmt *NullabilitySource = BinOp ? BinOp->getRHS() : S;
1180  State = State->set<NullabilityMap>(
1181  ValueRegion, NullabilityState(ValNullability, NullabilitySource));
1182  C.addTransition(State);
1183  return;
1184  }
1185 
1186  if (LocNullability == Nullability::Nullable) {
1187  const Stmt *NullabilitySource = BinOp ? BinOp->getLHS() : S;
1188  State = State->set<NullabilityMap>(
1189  ValueRegion, NullabilityState(LocNullability, NullabilitySource));
1190  C.addTransition(State);
1191  }
1192 }
1193 
1194 void NullabilityChecker::printState(raw_ostream &Out, ProgramStateRef State,
1195  const char *NL, const char *Sep) const {
1196 
1197  NullabilityMapTy B = State->get<NullabilityMap>();
1198 
1199  if (B.isEmpty())
1200  return;
1201 
1202  Out << Sep << NL;
1203 
1204  for (NullabilityMapTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1205  Out << I->first << " : ";
1206  I->second.print(Out);
1207  Out << NL;
1208  }
1209 }
1210 
1211 #define REGISTER_CHECKER(name, trackingRequired) \
1212  void ento::register##name##Checker(CheckerManager &mgr) { \
1213  NullabilityChecker *checker = mgr.registerChecker<NullabilityChecker>(); \
1214  checker->Filter.Check##name = true; \
1215  checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \
1216  checker->NeedTracking = checker->NeedTracking || trackingRequired; \
1217  checker->NoDiagnoseCallsToSystemHeaders = \
1218  checker->NoDiagnoseCallsToSystemHeaders || \
1219  mgr.getAnalyzerOptions().getBooleanOption( \
1220  "NoDiagnoseCallsToSystemHeaders", false, checker, true); \
1221  }
1222 
1223 // The checks are likely to be turned on by default and it is possible to do
1224 // them without tracking any nullability related information. As an optimization
1225 // no nullability information will be tracked when only these two checks are
1226 // enables.
1227 REGISTER_CHECKER(NullPassedToNonnull, false)
1228 REGISTER_CHECKER(NullReturnedFromNonnull, false)
1229 
1230 REGISTER_CHECKER(NullableDereferenced, true)
1231 REGISTER_CHECKER(NullablePassedToNonnull, true)
1232 REGISTER_CHECKER(NullableReturnedFromNonnull, true)
static bool checkParamsForPreconditionViolation(ArrayRef< ParmVarDecl * > Params, ProgramStateRef State, const LocationContext *LocCtxt)
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
Definition: CallEvent.cpp:223
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:494
bool isConstrainedFalse() const
Return true if the constraint is perfectly constrained to 'false'.
A (possibly-)qualified type.
Definition: Type.h:598
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 isInSystemHeader() const
Returns true if the callee is known to be from a system header.
Definition: CallEvent.h:235
bool hasDeadSymbols() const
bool isInstanceMessage() const
Definition: CallEvent.h:917
bool operator==(CanQual< T > x, CanQual< U > y)
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:2879
A helper class which wraps a boolean value set to false by default.
Definition: Checker.h:556
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
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...
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
virtual QualType getValueType() const =0
const RegionTy * getAs() const
Definition: MemRegion.h:1106
The base class of the type hierarchy.
Definition: Type.h:1281
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)
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:768
bool isReceiverSelfOrSuper() const
Checks if the receiver refers to 'self' or 'super'.
Definition: CallEvent.cpp:728
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:113
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
ParmVarDecl - Represents a parameter to a function.
Definition: Decl.h:1377
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)
const StringRef FilePath
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4549
LineState State
ObjCMethodFamily
A family of Objective-C methods.
AnalysisDeclContext contains the context data for the function or method under analysis.
bool isAnyPointerType() const
Definition: Type.h:5485
This class provides a convenience implementation for clone() using the Curiously-Recurring Template P...
AnalysisDeclContext * getAnalysisDeclContext() const
Expr * getSubExpr()
Definition: Expr.h:2684
BugReporter & getBugReporter()
Values of this type can be null.
Represents any expression that calls an Objective-C method.
Definition: CallEvent.h:881
virtual Kind getKind() const =0
Returns the kind of call this is.
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
Definition: CallEvent.cpp:712
const LangOptions & getLangOpts() const
Definition: ASTContext.h:604
QualType getReturnType() const
Definition: Type.h:3009
Whether values of this type can be null is (explicitly) unspecified.
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2897
const Decl * getDecl() const
Represents an ObjC class declaration.
Definition: DeclObjC.h:1091
detail::InMemoryDirectory::const_iterator I
QualType getType() const
Definition: Decl.h:599
We dereferenced a location that may be null.
Definition: Checker.h:541
const LocationContext * getLocationContext() const
ArrayRef< ParmVarDecl * > parameters() const override
Definition: CallEvent.cpp:674
StringRef getFilename(SourceLocation SpellingLoc) const
Return the filename of the file containing a SourceLocation.
ivar_range ivars() const
Definition: DeclObjC.h:1365
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:707
bool isDead(SymbolRef sym) const
Returns whether or not a symbol has been confirmed dead.
virtual const Expr * getArgExpr(unsigned Index) const
Returns the expression associated with a given argument.
Definition: CallEvent.h:273
Expr - This represents one expression.
Definition: Expr.h:105
const ProgramStateRef & getState() const
StringRef getName() const
Return the actual identifier string.
virtual ArrayRef< ParmVarDecl * > parameters() const =0
Return call's formal parameters.
const ProgramStateRef & getState() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:86
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
static SVal getValue(SVal val, SValBuilder &svalBuilder)
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:1366
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:860
#define REGISTER_CHECKER(name, trackingRequired)
const SourceManager & SM
Definition: Format.cpp:1184
REGISTER_MAP_WITH_PROGRAMSTATE(NullabilityMap, const MemRegion *, NullabilityState) enum class NullConstraint
BugReporter is a utility class for generating PathDiagnostics for analysis.
Definition: BugReporter.h:388
#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...
const TemplateArgument * iterator
Definition: Type.h:4233
static bool isARCNilInitializedLocal(CheckerContext &C, const Stmt *S)
Returns true if.
const std::string ID
void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:443
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:46
Selector getSelector() const
Definition: CallEvent.h:923
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
Definition: Type.h:4262
static bool checkInvariantViolation(ProgramStateRef State, ExplodedNode *N, CheckerContext &C)
const Decl * getDecl() const
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:907
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called.
Definition: CallEvent.h:203
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1155
QualType getType() const
Definition: Expr.h:126
detail::InMemoryDirectory::const_iterator E
const MemRegion * getAsRegion() const
Definition: SVals.cpp:135
const Expr * getRetValue() const
Definition: Stmt.cpp:899
bool isConstrainedTrue() const
Return true if the constraint is perfectly constrained to 'true'.
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:138
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:2800
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
Definition: ProgramPoint.h:150
ObjCMessageKind getMessageKind() const
Returns how the message was written in the source (property access, subscript, or explicit message se...
Definition: CallEvent.cpp:772
Represents a pointer to an Objective C object.
Definition: Type.h:4991
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:5818
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface...
Definition: Type.h:5046
const ImplicitParamDecl * getSelfDecl() 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:12171
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:3761
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:1004
#define true
Definition: stdbool.h:32
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
Definition: Checker.h:498
This class provides an interface through which checkers can create individual bug reports...
Definition: BugReporter.h:55
virtual const ObjCMessageExpr * getOriginExpr() const
Definition: CallEvent.h:904
SVal getReturnValue() const
Returns the return value of the call.
Definition: CallEvent.cpp:237
This class handles loading and caching of source files into memory.
SourceManager & getSourceManager()
Definition: BugReporter.h:550
const LocationContext * getLocationContext() const