Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- NullabilityChecker.cpp - Nullability checker ----------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This checker tries to find nullability violations. There are several kinds of
10
// possible violations:
11
// * Null pointer is passed to a pointer which has a _Nonnull type.
12
// * Null pointer is returned from a function which has a _Nonnull return type.
13
// * Nullable pointer is passed to a pointer which has a _Nonnull type.
14
// * Nullable pointer is returned from a function which has a _Nonnull return
15
//   type.
16
// * Nullable pointer is dereferenced.
17
//
18
// This checker propagates the nullability information of the pointers and looks
19
// for the patterns that are described above. Explicit casts are trusted and are
20
// considered a way to suppress false positives for this checker. The other way
21
// to suppress warnings would be to add asserts or guarding if statements to the
22
// code. In addition to the nullability propagation this checker also uses some
23
// heuristics to suppress potential false positives.
24
//
25
//===----------------------------------------------------------------------===//
26
27
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
28
29
#include "clang/Analysis/AnyCall.h"
30
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
31
#include "clang/StaticAnalyzer/Core/Checker.h"
32
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
33
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
34
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
35
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
36
37
#include "llvm/ADT/STLExtras.h"
38
#include "llvm/ADT/StringExtras.h"
39
#include "llvm/Support/Path.h"
40
41
using namespace clang;
42
using namespace ento;
43
44
namespace {
45
46
/// Returns the most nullable nullability. This is used for message expressions
47
/// like [receiver method], where the nullability of this expression is either
48
/// the nullability of the receiver or the nullability of the return type of the
49
/// method, depending on which is more nullable. Contradicted is considered to
50
/// be the most nullable, to avoid false positive results.
51
214
Nullability getMostNullable(Nullability Lhs, Nullability Rhs) {
52
214
  return static_cast<Nullability>(
53
214
      std::min(static_cast<char>(Lhs), static_cast<char>(Rhs)));
54
214
}
55
56
78
const char *getNullabilityString(Nullability Nullab) {
57
78
  switch (Nullab) {
58
0
  case Nullability::Contradicted:
59
0
    return "contradicted";
60
78
  case Nullability::Nullable:
61
78
    return "nullable";
62
0
  case Nullability::Unspecified:
63
0
    return "unspecified";
64
0
  case Nullability::Nonnull:
65
0
    return "nonnull";
66
78
  }
67
0
  llvm_unreachable("Unexpected enumeration.");
68
0
  return "";
69
78
}
70
71
// These enums are used as an index to ErrorMessages array.
72
enum class ErrorKind : int {
73
  NilAssignedToNonnull,
74
  NilPassedToNonnull,
75
  NilReturnedToNonnull,
76
  NullableAssignedToNonnull,
77
  NullableReturnedToNonnull,
78
  NullableDereferenced,
79
  NullablePassedToNonnull
80
};
81
82
class NullabilityChecker
83
    : public Checker<check::Bind, check::PreCall, check::PreStmt<ReturnStmt>,
84
                     check::PostCall, check::PostStmt<ExplicitCastExpr>,
85
                     check::PostObjCMessage, check::DeadSymbols, eval::Assume,
86
                     check::Location, check::Event<ImplicitNullDerefEvent>,
87
                     check::BeginFunction> {
88
89
public:
90
  // If true, the checker will not diagnose nullabilility issues for calls
91
  // to system headers. This option is motivated by the observation that large
92
  // projects may have many nullability warnings. These projects may
93
  // find warnings about nullability annotations that they have explicitly
94
  // added themselves higher priority to fix than warnings on calls to system
95
  // libraries.
96
  bool NoDiagnoseCallsToSystemHeaders = false;
97
98
  void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
99
  void checkPostStmt(const ExplicitCastExpr *CE, CheckerContext &C) const;
100
  void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
101
  void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
102
  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
103
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
104
  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
105
  void checkEvent(ImplicitNullDerefEvent Event) const;
106
  void checkLocation(SVal Location, bool IsLoad, const Stmt *S,
107
                     CheckerContext &C) const;
108
  void checkBeginFunction(CheckerContext &Ctx) const;
109
  ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond,
110
                             bool Assumption) const;
111
112
  void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
113
                  const char *Sep) const override;
114
115
  enum CheckKind {
116
    CK_NullPassedToNonnull,
117
    CK_NullReturnedFromNonnull,
118
    CK_NullableDereferenced,
119
    CK_NullablePassedToNonnull,
120
    CK_NullableReturnedFromNonnull,
121
    CK_NumCheckKinds
122
  };
123
124
  bool ChecksEnabled[CK_NumCheckKinds] = {false};
125
  CheckerNameRef CheckNames[CK_NumCheckKinds];
126
  mutable std::unique_ptr<BugType> BTs[CK_NumCheckKinds];
127
128
206
  const std::unique_ptr<BugType> &getBugType(CheckKind Kind) const {
129
206
    if (!BTs[Kind])
130
36
      BTs[Kind].reset(new BugType(CheckNames[Kind], "Nullability",
131
36
                                  categories::MemoryError));
132
206
    return BTs[Kind];
133
206
  }
134
135
  // When set to false no nullability information will be tracked in
136
  // NullabilityMap. It is possible to catch errors like passing a null pointer
137
  // to a callee that expects nonnull argument without the information that is
138
  // stored in the NullabilityMap. This is an optimization.
139
  bool NeedTracking = false;
140
141
private:
142
  class NullabilityBugVisitor : public BugReporterVisitor {
143
  public:
144
110
    NullabilityBugVisitor(const MemRegion *M) : Region(M) {}
145
146
110
    void Profile(llvm::FoldingSetNodeID &ID) const override {
147
110
      static int X = 0;
148
110
      ID.AddPointer(&X);
149
110
      ID.AddPointer(Region);
150
110
    }
151
152
    PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
153
                                     BugReporterContext &BRC,
154
                                     PathSensitiveBugReport &BR) override;
155
156
  private:
157
    // The tracked region.
158
    const MemRegion *Region;
159
  };
160
161
  /// When any of the nonnull arguments of the analyzed function is null, do not
162
  /// report anything and turn off the check.
163
  ///
164
  /// When \p SuppressPath is set to true, no more bugs will be reported on this
165
  /// path by this checker.
166
  void reportBugIfInvariantHolds(StringRef Msg, ErrorKind Error, CheckKind CK,
167
                                 ExplodedNode *N, const MemRegion *Region,
168
                                 CheckerContext &C,
169
                                 const Stmt *ValueExpr = nullptr,
170
                                 bool SuppressPath = false) const;
171
172
  void reportBug(StringRef Msg, ErrorKind Error, CheckKind CK, ExplodedNode *N,
173
                 const MemRegion *Region, BugReporter &BR,
174
206
                 const Stmt *ValueExpr = nullptr) const {
175
206
    const std::unique_ptr<BugType> &BT = getBugType(CK);
176
206
    auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
177
206
    if (Region) {
178
110
      R->markInteresting(Region);
179
110
      R->addVisitor<NullabilityBugVisitor>(Region);
180
110
    }
181
206
    if (ValueExpr) {
182
167
      R->addRange(ValueExpr->getSourceRange());
183
167
      if (Error == ErrorKind::NilAssignedToNonnull ||
184
167
          
Error == ErrorKind::NilPassedToNonnull151
||
185
167
          
Error == ErrorKind::NilReturnedToNonnull95
)
186
96
        if (const auto *Ex = dyn_cast<Expr>(ValueExpr))
187
96
          bugreporter::trackExpressionValue(N, Ex, *R);
188
167
    }
189
206
    BR.emitReport(std::move(R));
190
206
  }
191
192
  /// If an SVal wraps a region that should be tracked, it will return a pointer
193
  /// to the wrapped region. Otherwise it will return a nullptr.
194
  const SymbolicRegion *getTrackRegion(SVal Val,
195
                                       bool CheckSuperRegion = false) const;
196
197
  /// Returns true if the call is diagnosable in the current analyzer
198
  /// configuration.
199
133
  bool isDiagnosableCall(const CallEvent &Call) const {
200
133
    if (NoDiagnoseCallsToSystemHeaders && 
Call.isInSystemHeader()59
)
201
6
      return false;
202
203
127
    return true;
204
133
  }
205
};
206
207
class NullabilityState {
208
public:
209
  NullabilityState(Nullability Nullab, const Stmt *Source = nullptr)
210
155
      : Nullab(Nullab), Source(Source) {}
211
212
180
  const Stmt *getNullabilitySource() const { return Source; }
213
214
5.35k
  Nullability getValue() const { return Nullab; }
215
216
203
  void Profile(llvm::FoldingSetNodeID &ID) const {
217
203
    ID.AddInteger(static_cast<char>(Nullab));
218
203
    ID.AddPointer(Source);
219
203
  }
220
221
0
  void print(raw_ostream &Out) const {
222
0
    Out << getNullabilityString(Nullab) << "\n";
223
0
  }
224
225
private:
226
  Nullability Nullab;
227
  // Source is the expression which determined the nullability. For example in a
228
  // message like [nullable nonnull_returning] has nullable nullability, because
229
  // the receiver is nullable. Here the receiver will be the source of the
230
  // nullability. This is useful information when the diagnostics are generated.
231
  const Stmt *Source;
232
};
233
234
35
bool operator==(NullabilityState Lhs, NullabilityState Rhs) {
235
35
  return Lhs.getValue() == Rhs.getValue() &&
236
35
         Lhs.getNullabilitySource() == Rhs.getNullabilitySource();
237
35
}
238
239
// For the purpose of tracking historical property accesses, the key for lookup
240
// is an object pointer (could be an instance or a class) paired with the unique
241
// identifier for the property being invoked on that object.
242
using ObjectPropPair = std::pair<const MemRegion *, const IdentifierInfo *>;
243
244
// Metadata associated with the return value from a recorded property access.
245
struct ConstrainedPropertyVal {
246
  // This will reference the conjured return SVal for some call
247
  // of the form [object property]
248
  DefinedOrUnknownSVal Value;
249
250
  // If the SVal has been determined to be nonnull, that is recorded here
251
  bool isConstrainedNonnull;
252
253
  ConstrainedPropertyVal(DefinedOrUnknownSVal SV)
254
44
      : Value(SV), isConstrainedNonnull(false) {}
255
256
76
  void Profile(llvm::FoldingSetNodeID &ID) const {
257
76
    Value.Profile(ID);
258
76
    ID.AddInteger(isConstrainedNonnull ? 
132
:
044
);
259
76
  }
260
};
261
262
bool operator==(const ConstrainedPropertyVal &Lhs,
263
4
                const ConstrainedPropertyVal &Rhs) {
264
4
  return Lhs.Value == Rhs.Value &&
265
4
         Lhs.isConstrainedNonnull == Rhs.isConstrainedNonnull;
266
4
}
267
268
} // end anonymous namespace
269
270
REGISTER_MAP_WITH_PROGRAMSTATE(NullabilityMap, const MemRegion *,
271
                               NullabilityState)
272
REGISTER_MAP_WITH_PROGRAMSTATE(PropertyAccessesMap, ObjectPropPair,
273
                               ConstrainedPropertyVal)
274
275
// We say "the nullability type invariant is violated" when a location with a
276
// non-null type contains NULL or a function with a non-null return type returns
277
// NULL. Violations of the nullability type invariant can be detected either
278
// directly (for example, when NULL is passed as an argument to a nonnull
279
// parameter) or indirectly (for example, when, inside a function, the
280
// programmer defensively checks whether a nonnull parameter contains NULL and
281
// finds that it does).
282
//
283
// As a matter of policy, the nullability checker typically warns on direct
284
// violations of the nullability invariant (although it uses various
285
// heuristics to suppress warnings in some cases) but will not warn if the
286
// invariant has already been violated along the path (either directly or
287
// indirectly). As a practical matter, this prevents the analyzer from
288
// (1) warning on defensive code paths where a nullability precondition is
289
// determined to have been violated, (2) warning additional times after an
290
// initial direct violation has been discovered, and (3) warning after a direct
291
// violation that has been implicitly or explicitly suppressed (for
292
// example, with a cast of NULL to _Nonnull). In essence, once an invariant
293
// violation is detected on a path, this checker will be essentially turned off
294
// for the rest of the analysis
295
//
296
// The analyzer takes this approach (rather than generating a sink node) to
297
// ensure coverage of defensive paths, which may be important for backwards
298
// compatibility in codebases that were developed without nullability in mind.
299
REGISTER_TRAIT_WITH_PROGRAMSTATE(InvariantViolated, bool)
300
301
enum class NullConstraint { IsNull, IsNotNull, Unknown };
302
303
static NullConstraint getNullConstraint(DefinedOrUnknownSVal Val,
304
1.85k
                                        ProgramStateRef State) {
305
1.85k
  ConditionTruthVal Nullness = State->isNull(Val);
306
1.85k
  if (Nullness.isConstrainedFalse())
307
713
    return NullConstraint::IsNotNull;
308
1.14k
  if (Nullness.isConstrainedTrue())
309
331
    return NullConstraint::IsNull;
310
811
  return NullConstraint::Unknown;
311
1.14k
}
312
313
2.69k
static bool isValidPointerType(QualType T) {
314
2.69k
  return T->isAnyPointerType() || 
T->isBlockPointerType()741
;
315
2.69k
}
316
317
const SymbolicRegion *
318
1.55k
NullabilityChecker::getTrackRegion(SVal Val, bool CheckSuperRegion) const {
319
1.55k
  if (!NeedTracking)
320
83
    return nullptr;
321
322
1.47k
  auto RegionSVal = Val.getAs<loc::MemRegionVal>();
323
1.47k
  if (!RegionSVal)
324
191
    return nullptr;
325
326
1.28k
  const MemRegion *Region = RegionSVal->getRegion();
327
328
1.28k
  if (CheckSuperRegion) {
329
49
    if (const SubRegion *FieldReg = Region->getAs<FieldRegion>()) {
330
10
      if (const auto *ER = dyn_cast<ElementRegion>(FieldReg->getSuperRegion()))
331
10
        FieldReg = ER;
332
10
      return dyn_cast<SymbolicRegion>(FieldReg->getSuperRegion());
333
10
    }
334
39
    if (auto ElementReg = Region->getAs<ElementRegion>())
335
0
      return dyn_cast<SymbolicRegion>(ElementReg->getSuperRegion());
336
39
  }
337
338
1.27k
  return dyn_cast<SymbolicRegion>(Region);
339
1.28k
}
340
341
PathDiagnosticPieceRef NullabilityChecker::NullabilityBugVisitor::VisitNode(
342
    const ExplodedNode *N, BugReporterContext &BRC,
343
4.95k
    PathSensitiveBugReport &BR) {
344
4.95k
  ProgramStateRef State = N->getState();
345
4.95k
  ProgramStateRef StatePrev = N->getFirstPred()->getState();
346
347
4.95k
  const NullabilityState *TrackedNullab = State->get<NullabilityMap>(Region);
348
4.95k
  const NullabilityState *TrackedNullabPrev =
349
4.95k
      StatePrev->get<NullabilityMap>(Region);
350
4.95k
  if (!TrackedNullab)
351
2.38k
    return nullptr;
352
353
2.56k
  if (TrackedNullabPrev &&
354
2.56k
      
TrackedNullabPrev->getValue() == TrackedNullab->getValue()2.45k
)
355
2.45k
    return nullptr;
356
357
  // Retrieve the associated statement.
358
110
  const Stmt *S = TrackedNullab->getNullabilitySource();
359
110
  if (!S || 
S->getBeginLoc().isInvalid()34
) {
360
78
    S = N->getStmtForDiagnostics();
361
78
  }
362
363
110
  if (!S)
364
32
    return nullptr;
365
366
78
  std::string InfoText =
367
78
      (llvm::Twine("Nullability '") +
368
78
       getNullabilityString(TrackedNullab->getValue()) + "' is inferred")
369
78
          .str();
370
371
  // Generate the extra diagnostic.
372
78
  PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
373
78
                             N->getLocationContext());
374
78
  return std::make_shared<PathDiagnosticEventPiece>(Pos, InfoText, true);
375
110
}
376
377
/// Returns true when the value stored at the given location has been
378
/// constrained to null after being passed through an object of nonnnull type.
379
static bool checkValueAtLValForInvariantViolation(ProgramStateRef State,
380
2.33k
                                                  SVal LV, QualType T) {
381
2.33k
  if (getNullabilityAnnotation(T) != Nullability::Nonnull)
382
1.83k
    return false;
383
384
499
  auto RegionVal = LV.getAs<loc::MemRegionVal>();
385
499
  if (!RegionVal)
386
0
    return false;
387
388
  // If the value was constrained to null *after* it was passed through that
389
  // location, it could not have been a concrete pointer *when* it was passed.
390
  // In that case we would have handled the situation when the value was
391
  // bound to that location, by emitting (or not emitting) a report.
392
  // Therefore we are only interested in symbolic regions that can be either
393
  // null or non-null depending on the value of their respective symbol.
394
499
  auto StoredVal = State->getSVal(*RegionVal).getAs<loc::MemRegionVal>();
395
499
  if (!StoredVal || !isa<SymbolicRegion>(StoredVal->getRegion()))
396
0
    return false;
397
398
499
  if (getNullConstraint(*StoredVal, State) == NullConstraint::IsNull)
399
0
    return true;
400
401
499
  return false;
402
499
}
403
404
static bool
405
checkParamsForPreconditionViolation(ArrayRef<ParmVarDecl *> Params,
406
                                    ProgramStateRef State,
407
3.58k
                                    const LocationContext *LocCtxt) {
408
3.58k
  for (const auto *ParamDecl : Params) {
409
2.09k
    if (ParamDecl->isParameterPack())
410
0
      break;
411
412
2.09k
    SVal LV = State->getLValue(ParamDecl, LocCtxt);
413
2.09k
    if (checkValueAtLValForInvariantViolation(State, LV,
414
2.09k
                                              ParamDecl->getType())) {
415
0
      return true;
416
0
    }
417
2.09k
  }
418
3.58k
  return false;
419
3.58k
}
420
421
static bool
422
checkSelfIvarsForInvariantViolation(ProgramStateRef State,
423
3.58k
                                    const LocationContext *LocCtxt) {
424
3.58k
  auto *MD = dyn_cast<ObjCMethodDecl>(LocCtxt->getDecl());
425
3.58k
  if (!MD || 
!MD->isInstanceMethod()754
)
426
2.84k
    return false;
427
428
739
  const ImplicitParamDecl *SelfDecl = LocCtxt->getSelfDecl();
429
739
  if (!SelfDecl)
430
0
    return false;
431
432
739
  SVal SelfVal = State->getSVal(State->getRegion(SelfDecl, LocCtxt));
433
434
739
  const ObjCObjectPointerType *SelfType =
435
739
      dyn_cast<ObjCObjectPointerType>(SelfDecl->getType());
436
739
  if (!SelfType)
437
0
    return false;
438
439
739
  const ObjCInterfaceDecl *ID = SelfType->getInterfaceDecl();
440
739
  if (!ID)
441
0
    return false;
442
443
739
  for (const auto *IvarDecl : ID->ivars()) {
444
244
    SVal LV = State->getLValue(IvarDecl, SelfVal);
445
244
    if (checkValueAtLValForInvariantViolation(State, LV, IvarDecl->getType())) {
446
0
      return true;
447
0
    }
448
244
  }
449
739
  return false;
450
739
}
451
452
static bool checkInvariantViolation(ProgramStateRef State, ExplodedNode *N,
453
4.01k
                                    CheckerContext &C) {
454
4.01k
  if (State->get<InvariantViolated>())
455
432
    return true;
456
457
3.58k
  const LocationContext *LocCtxt = C.getLocationContext();
458
3.58k
  const Decl *D = LocCtxt->getDecl();
459
3.58k
  if (!D)
460
0
    return false;
461
462
3.58k
  ArrayRef<ParmVarDecl*> Params;
463
3.58k
  if (const auto *BD = dyn_cast<BlockDecl>(D))
464
18
    Params = BD->parameters();
465
3.56k
  else if (const auto *FD = dyn_cast<FunctionDecl>(D))
466
2.81k
    Params = FD->parameters();
467
754
  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
468
754
    Params = MD->parameters();
469
0
  else
470
0
    return false;
471
472
3.58k
  if (checkParamsForPreconditionViolation(Params, State, LocCtxt) ||
473
3.58k
      checkSelfIvarsForInvariantViolation(State, LocCtxt)) {
474
0
    if (!N->isSink())
475
0
      C.addTransition(State->set<InvariantViolated>(true), N);
476
0
    return true;
477
0
  }
478
3.58k
  return false;
479
3.58k
}
480
481
void NullabilityChecker::reportBugIfInvariantHolds(
482
    StringRef Msg, ErrorKind Error, CheckKind CK, ExplodedNode *N,
483
    const MemRegion *Region, CheckerContext &C, const Stmt *ValueExpr,
484
179
    bool SuppressPath) const {
485
179
  ProgramStateRef OriginalState = N->getState();
486
487
179
  if (checkInvariantViolation(OriginalState, N, C))
488
0
    return;
489
179
  if (SuppressPath) {
490
71
    OriginalState = OriginalState->set<InvariantViolated>(true);
491
71
    N = C.addTransition(OriginalState, N);
492
71
  }
493
494
179
  reportBug(Msg, Error, CK, N, Region, C.getBugReporter(), ValueExpr);
495
179
}
496
497
/// Cleaning up the program state.
498
void NullabilityChecker::checkDeadSymbols(SymbolReaper &SR,
499
3.83k
                                          CheckerContext &C) const {
500
3.83k
  ProgramStateRef State = C.getState();
501
3.83k
  NullabilityMapTy Nullabilities = State->get<NullabilityMap>();
502
3.83k
  for (const MemRegion *Reg : llvm::make_first_range(Nullabilities)) {
503
1.13k
    const auto *Region = Reg->getAs<SymbolicRegion>();
504
1.13k
    assert(Region && "Non-symbolic region is tracked.");
505
1.13k
    if (SR.isDead(Region->getSymbol())) {
506
384
      State = State->remove<NullabilityMap>(Reg);
507
384
    }
508
1.13k
  }
509
510
  // When an object goes out of scope, we can free the history associated
511
  // with any property accesses on that object
512
3.83k
  PropertyAccessesMapTy PropertyAccesses = State->get<PropertyAccessesMap>();
513
3.83k
  for (ObjectPropPair PropKey : llvm::make_first_range(PropertyAccesses)) {
514
124
    const MemRegion *ReceiverRegion = PropKey.first;
515
124
    if (!SR.isLiveRegion(ReceiverRegion)) {
516
40
      State = State->remove<PropertyAccessesMap>(PropKey);
517
40
    }
518
124
  }
519
520
  // When one of the nonnull arguments are constrained to be null, nullability
521
  // preconditions are violated. It is not enough to check this only when we
522
  // actually report an error, because at that time interesting symbols might be
523
  // reaped.
524
3.83k
  if (checkInvariantViolation(State, C.getPredecessor(), C))
525
432
    return;
526
3.40k
  C.addTransition(State);
527
3.40k
}
528
529
/// This callback triggers when a pointer is dereferenced and the analyzer does
530
/// not know anything about the value of that pointer. When that pointer is
531
/// nullable, this code emits a warning.
532
49
void NullabilityChecker::checkEvent(ImplicitNullDerefEvent Event) const {
533
49
  if (Event.SinkNode->getState()->get<InvariantViolated>())
534
0
    return;
535
536
49
  const MemRegion *Region =
537
49
      getTrackRegion(Event.Location, /*CheckSuperRegion=*/true);
538
49
  if (!Region)
539
2
    return;
540
541
47
  ProgramStateRef State = Event.SinkNode->getState();
542
47
  const NullabilityState *TrackedNullability =
543
47
      State->get<NullabilityMap>(Region);
544
545
47
  if (!TrackedNullability)
546
20
    return;
547
548
27
  if (ChecksEnabled[CK_NullableDereferenced] &&
549
27
      TrackedNullability->getValue() == Nullability::Nullable) {
550
27
    BugReporter &BR = *Event.BR;
551
    // Do not suppress errors on defensive code paths, because dereferencing
552
    // a nullable pointer is always an error.
553
27
    if (Event.IsDirectDereference)
554
20
      reportBug("Nullable pointer is dereferenced",
555
20
                ErrorKind::NullableDereferenced, CK_NullableDereferenced,
556
20
                Event.SinkNode, Region, BR);
557
7
    else {
558
7
      reportBug("Nullable pointer is passed to a callee that requires a "
559
7
                "non-null",
560
7
                ErrorKind::NullablePassedToNonnull, CK_NullableDereferenced,
561
7
                Event.SinkNode, Region, BR);
562
7
    }
563
27
  }
564
27
}
565
566
486
void NullabilityChecker::checkBeginFunction(CheckerContext &C) const {
567
486
  if (!C.inTopFrame())
568
144
    return;
569
570
342
  const LocationContext *LCtx = C.getLocationContext();
571
342
  auto AbstractCall = AnyCall::forDecl(LCtx->getDecl());
572
342
  if (!AbstractCall || 
AbstractCall->parameters().empty()340
)
573
188
    return;
574
575
154
  ProgramStateRef State = C.getState();
576
181
  for (const ParmVarDecl *Param : AbstractCall->parameters()) {
577
181
    if (!isValidPointerType(Param->getType()))
578
18
      continue;
579
580
163
    Nullability RequiredNullability =
581
163
        getNullabilityAnnotation(Param->getType());
582
163
    if (RequiredNullability != Nullability::Nullable)
583
139
      continue;
584
585
24
    const VarRegion *ParamRegion = State->getRegion(Param, LCtx);
586
24
    const MemRegion *ParamPointeeRegion =
587
24
        State->getSVal(ParamRegion).getAsRegion();
588
24
    if (!ParamPointeeRegion)
589
0
      continue;
590
591
24
    State = State->set<NullabilityMap>(ParamPointeeRegion,
592
24
                                       NullabilityState(RequiredNullability));
593
24
  }
594
154
  C.addTransition(State);
595
154
}
596
597
// Whenever we see a load from a typed memory region that's been annotated as
598
// 'nonnull', we want to trust the user on that and assume that it is is indeed
599
// non-null.
600
//
601
// We do so even if the value is known to have been assigned to null.
602
// The user should be warned on assigning the null value to a non-null pointer
603
// as opposed to warning on the later dereference of this pointer.
604
//
605
// \code
606
//   int * _Nonnull var = 0; // we want to warn the user here...
607
//   // . . .
608
//   *var = 42;              // ...and not here
609
// \endcode
610
void NullabilityChecker::checkLocation(SVal Location, bool IsLoad,
611
                                       const Stmt *S,
612
1.74k
                                       CheckerContext &Context) const {
613
  // We should care only about loads.
614
  // The main idea is to add a constraint whenever we're loading a value from
615
  // an annotated pointer type.
616
1.74k
  if (!IsLoad)
617
219
    return;
618
619
  // Annotations that we want to consider make sense only for types.
620
1.52k
  const auto *Region =
621
1.52k
      dyn_cast_or_null<TypedValueRegion>(Location.getAsRegion());
622
1.52k
  if (!Region)
623
5
    return;
624
625
1.51k
  ProgramStateRef State = Context.getState();
626
627
1.51k
  auto StoredVal = State->getSVal(Region).getAs<loc::MemRegionVal>();
628
1.51k
  if (!StoredVal)
629
191
    return;
630
631
1.32k
  Nullability NullabilityOfTheLoadedValue =
632
1.32k
      getNullabilityAnnotation(Region->getValueType());
633
634
1.32k
  if (NullabilityOfTheLoadedValue == Nullability::Nonnull) {
635
    // It doesn't matter what we think about this particular pointer, it should
636
    // be considered non-null as annotated by the developer.
637
186
    if (ProgramStateRef NewState = State->assume(*StoredVal, true)) {
638
186
      Context.addTransition(NewState);
639
186
    }
640
186
  }
641
1.32k
}
642
643
/// Find the outermost subexpression of E that is not an implicit cast.
644
/// This looks through the implicit casts to _Nonnull that ARC adds to
645
/// return expressions of ObjC types when the return type of the function or
646
/// method is non-null but the express is not.
647
1.16k
static const Expr *lookThroughImplicitCasts(const Expr *E) {
648
1.16k
  return E->IgnoreImpCasts();
649
1.16k
}
650
651
/// This method check when nullable pointer or null value is returned from a
652
/// function that has nonnull return type.
653
void NullabilityChecker::checkPreStmt(const ReturnStmt *S,
654
317
                                      CheckerContext &C) const {
655
317
  auto RetExpr = S->getRetValue();
656
317
  if (!RetExpr)
657
20
    return;
658
659
297
  if (!isValidPointerType(RetExpr->getType()))
660
18
    return;
661
662
279
  ProgramStateRef State = C.getState();
663
279
  if (State->get<InvariantViolated>())
664
20
    return;
665
666
259
  auto RetSVal = C.getSVal(S).getAs<DefinedOrUnknownSVal>();
667
259
  if (!RetSVal)
668
0
    return;
669
670
259
  bool InSuppressedMethodFamily = false;
671
672
259
  QualType RequiredRetType;
673
259
  AnalysisDeclContext *DeclCtxt =
674
259
      C.getLocationContext()->getAnalysisDeclContext();
675
259
  const Decl *D = DeclCtxt->getDecl();
676
259
  if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
677
    // HACK: This is a big hammer to avoid warning when there are defensive
678
    // nil checks in -init and -copy methods. We should add more sophisticated
679
    // logic here to suppress on common defensive idioms but still
680
    // warn when there is a likely problem.
681
129
    ObjCMethodFamily Family = MD->getMethodFamily();
682
129
    if (OMF_init == Family || 
OMF_copy == Family75
||
OMF_mutableCopy == Family67
)
683
70
      InSuppressedMethodFamily = true;
684
685
129
    RequiredRetType = MD->getReturnType();
686
130
  } else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
687
126
    RequiredRetType = FD->getReturnType();
688
126
  } else {
689
4
    return;
690
4
  }
691
692
255
  NullConstraint Nullness = getNullConstraint(*RetSVal, State);
693
694
255
  Nullability RequiredNullability = getNullabilityAnnotation(RequiredRetType);
695
696
  // If the returned value is null but the type of the expression
697
  // generating it is nonnull then we will suppress the diagnostic.
698
  // This enables explicit suppression when returning a nil literal in a
699
  // function with a _Nonnull return type:
700
  //    return (NSString * _Nonnull)0;
701
255
  Nullability RetExprTypeLevelNullability =
702
255
        getNullabilityAnnotation(lookThroughImplicitCasts(RetExpr)->getType());
703
704
255
  bool NullReturnedFromNonNull = (RequiredNullability == Nullability::Nonnull &&
705
255
                                  
Nullness == NullConstraint::IsNull185
);
706
255
  if (ChecksEnabled[CK_NullReturnedFromNonnull] && NullReturnedFromNonNull &&
707
255
      
RetExprTypeLevelNullability != Nullability::Nonnull72
&&
708
255
      
!InSuppressedMethodFamily56
&&
C.getLocationContext()->inTopFrame()28
) {
709
24
    static CheckerProgramPointTag Tag(this, "NullReturnedFromNonnull");
710
24
    ExplodedNode *N = C.generateErrorNode(State, &Tag);
711
24
    if (!N)
712
0
      return;
713
714
24
    SmallString<256> SBuf;
715
24
    llvm::raw_svector_ostream OS(SBuf);
716
24
    OS << (RetExpr->getType()->isObjCObjectPointerType() ? 
"nil"8
:
"Null"16
);
717
24
    OS << " returned from a " << C.getDeclDescription(D) <<
718
24
          " that is expected to return a non-null value";
719
24
    reportBugIfInvariantHolds(OS.str(), ErrorKind::NilReturnedToNonnull,
720
24
                              CK_NullReturnedFromNonnull, N, nullptr, C,
721
24
                              RetExpr);
722
24
    return;
723
24
  }
724
725
  // If null was returned from a non-null function, mark the nullability
726
  // invariant as violated even if the diagnostic was suppressed.
727
231
  if (NullReturnedFromNonNull) {
728
48
    State = State->set<InvariantViolated>(true);
729
48
    C.addTransition(State);
730
48
    return;
731
48
  }
732
733
183
  const MemRegion *Region = getTrackRegion(*RetSVal);
734
183
  if (!Region)
735
27
    return;
736
737
156
  const NullabilityState *TrackedNullability =
738
156
      State->get<NullabilityMap>(Region);
739
156
  if (TrackedNullability) {
740
36
    Nullability TrackedNullabValue = TrackedNullability->getValue();
741
36
    if (ChecksEnabled[CK_NullableReturnedFromNonnull] &&
742
36
        Nullness != NullConstraint::IsNotNull &&
743
36
        TrackedNullabValue == Nullability::Nullable &&
744
36
        
RequiredNullability == Nullability::Nonnull24
) {
745
8
      static CheckerProgramPointTag Tag(this, "NullableReturnedFromNonnull");
746
8
      ExplodedNode *N = C.addTransition(State, C.getPredecessor(), &Tag);
747
748
8
      SmallString<256> SBuf;
749
8
      llvm::raw_svector_ostream OS(SBuf);
750
8
      OS << "Nullable pointer is returned from a " << C.getDeclDescription(D) <<
751
8
            " that is expected to return a non-null value";
752
753
8
      reportBugIfInvariantHolds(OS.str(), ErrorKind::NullableReturnedToNonnull,
754
8
                                CK_NullableReturnedFromNonnull, N, Region, C);
755
8
    }
756
36
    return;
757
36
  }
758
120
  if (RequiredNullability == Nullability::Nullable) {
759
2
    State = State->set<NullabilityMap>(Region,
760
2
                                       NullabilityState(RequiredNullability,
761
2
                                                        S));
762
2
    C.addTransition(State);
763
2
  }
764
120
}
765
766
/// This callback warns when a nullable pointer or a null value is passed to a
767
/// function that expects its argument to be nonnull.
768
void NullabilityChecker::checkPreCall(const CallEvent &Call,
769
974
                                      CheckerContext &C) const {
770
974
  if (!Call.getDecl())
771
0
    return;
772
773
974
  ProgramStateRef State = C.getState();
774
974
  if (State->get<InvariantViolated>())
775
85
    return;
776
777
889
  ProgramStateRef OrigState = State;
778
779
889
  unsigned Idx = 0;
780
889
  for (const ParmVarDecl *Param : Call.parameters()) {
781
509
    if (Param->isParameterPack())
782
0
      break;
783
784
509
    if (Idx >= Call.getNumArgs())
785
0
      break;
786
787
509
    const Expr *ArgExpr = Call.getArgExpr(Idx);
788
509
    auto ArgSVal = Call.getArgSVal(Idx++).getAs<DefinedOrUnknownSVal>();
789
509
    if (!ArgSVal)
790
0
      continue;
791
792
509
    if (!isValidPointerType(Param->getType()) &&
793
509
        
!Param->getType()->isReferenceType()43
)
794
33
      continue;
795
796
476
    NullConstraint Nullness = getNullConstraint(*ArgSVal, State);
797
798
476
    Nullability RequiredNullability =
799
476
        getNullabilityAnnotation(Param->getType());
800
476
    Nullability ArgExprTypeLevelNullability =
801
476
        getNullabilityAnnotation(lookThroughImplicitCasts(ArgExpr)->getType());
802
803
476
    unsigned ParamIdx = Param->getFunctionScopeIndex() + 1;
804
805
476
    if (ChecksEnabled[CK_NullPassedToNonnull] &&
806
476
        Nullness == NullConstraint::IsNull &&
807
476
        
ArgExprTypeLevelNullability != Nullability::Nonnull90
&&
808
476
        
RequiredNullability == Nullability::Nonnull78
&&
809
476
        
isDiagnosableCall(Call)58
) {
810
56
      ExplodedNode *N = C.generateErrorNode(State);
811
56
      if (!N)
812
0
        return;
813
814
56
      SmallString<256> SBuf;
815
56
      llvm::raw_svector_ostream OS(SBuf);
816
56
      OS << (Param->getType()->isObjCObjectPointerType() ? 
"nil"20
:
"Null"36
);
817
56
      OS << " passed to a callee that requires a non-null " << ParamIdx
818
56
         << llvm::getOrdinalSuffix(ParamIdx) << " parameter";
819
56
      reportBugIfInvariantHolds(OS.str(), ErrorKind::NilPassedToNonnull,
820
56
                                CK_NullPassedToNonnull, N, nullptr, C, ArgExpr,
821
56
                                /*SuppressPath=*/false);
822
56
      return;
823
56
    }
824
825
420
    const MemRegion *Region = getTrackRegion(*ArgSVal);
826
420
    if (!Region)
827
86
      continue;
828
829
334
    const NullabilityState *TrackedNullability =
830
334
        State->get<NullabilityMap>(Region);
831
832
334
    if (TrackedNullability) {
833
153
      if (Nullness == NullConstraint::IsNotNull ||
834
153
          
TrackedNullability->getValue() != Nullability::Nullable123
)
835
38
        continue;
836
837
115
      if (ChecksEnabled[CK_NullablePassedToNonnull] &&
838
115
          RequiredNullability == Nullability::Nonnull &&
839
115
          
isDiagnosableCall(Call)75
) {
840
71
        ExplodedNode *N = C.addTransition(State);
841
71
        SmallString<256> SBuf;
842
71
        llvm::raw_svector_ostream OS(SBuf);
843
71
        OS << "Nullable pointer is passed to a callee that requires a non-null "
844
71
           << ParamIdx << llvm::getOrdinalSuffix(ParamIdx) << " parameter";
845
71
        reportBugIfInvariantHolds(OS.str(), ErrorKind::NullablePassedToNonnull,
846
71
                                  CK_NullablePassedToNonnull, N, Region, C,
847
71
                                  ArgExpr, /*SuppressPath=*/true);
848
71
        return;
849
71
      }
850
44
      if (ChecksEnabled[CK_NullableDereferenced] &&
851
44
          Param->getType()->isReferenceType()) {
852
0
        ExplodedNode *N = C.addTransition(State);
853
0
        reportBugIfInvariantHolds("Nullable pointer is dereferenced",
854
0
                                  ErrorKind::NullableDereferenced,
855
0
                                  CK_NullableDereferenced, N, Region, C,
856
0
                                  ArgExpr, /*SuppressPath=*/true);
857
0
        return;
858
0
      }
859
44
      continue;
860
44
    }
861
334
  }
862
762
  if (State != OrigState)
863
0
    C.addTransition(State);
864
762
}
865
866
/// Suppress the nullability warnings for some functions.
867
void NullabilityChecker::checkPostCall(const CallEvent &Call,
868
899
                                       CheckerContext &C) const {
869
899
  auto Decl = Call.getDecl();
870
899
  if (!Decl)
871
0
    return;
872
  // ObjC Messages handles in a different callback.
873
899
  if (Call.getKind() == CE_ObjCMessage)
874
347
    return;
875
552
  const FunctionType *FuncType = Decl->getFunctionType();
876
552
  if (!FuncType)
877
6
    return;
878
546
  QualType ReturnType = FuncType->getReturnType();
879
546
  if (!isValidPointerType(ReturnType))
880
401
    return;
881
145
  ProgramStateRef State = C.getState();
882
145
  if (State->get<InvariantViolated>())
883
6
    return;
884
885
139
  const MemRegion *Region = getTrackRegion(Call.getReturnValue());
886
139
  if (!Region)
887
8
    return;
888
889
  // CG headers are misannotated. Do not warn for symbols that are the results
890
  // of CG calls.
891
131
  const SourceManager &SM = C.getSourceManager();
892
131
  StringRef FilePath = SM.getFilename(SM.getSpellingLoc(Decl->getBeginLoc()));
893
131
  if (llvm::sys::path::filename(FilePath).startswith("CG")) {
894
0
    State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
895
0
    C.addTransition(State);
896
0
    return;
897
0
  }
898
899
131
  const NullabilityState *TrackedNullability =
900
131
      State->get<NullabilityMap>(Region);
901
902
131
  if (!TrackedNullability &&
903
131
      
getNullabilityAnnotation(ReturnType) == Nullability::Nullable115
) {
904
60
    State = State->set<NullabilityMap>(Region, Nullability::Nullable);
905
60
    C.addTransition(State);
906
60
  }
907
131
}
908
909
static Nullability getReceiverNullability(const ObjCMethodCall &M,
910
214
                                          ProgramStateRef State) {
911
214
  if (M.isReceiverSelfOrSuper()) {
912
    // For super and super class receivers we assume that the receiver is
913
    // nonnull.
914
44
    return Nullability::Nonnull;
915
44
  }
916
  // Otherwise look up nullability in the state.
917
170
  SVal Receiver = M.getReceiverSVal();
918
170
  if (auto DefOrUnknown = Receiver.getAs<DefinedOrUnknownSVal>()) {
919
    // If the receiver is constrained to be nonnull, assume that it is nonnull
920
    // regardless of its type.
921
170
    NullConstraint Nullness = getNullConstraint(*DefOrUnknown, State);
922
170
    if (Nullness == NullConstraint::IsNotNull)
923
145
      return Nullability::Nonnull;
924
170
  }
925
25
  auto ValueRegionSVal = Receiver.getAs<loc::MemRegionVal>();
926
25
  if (ValueRegionSVal) {
927
0
    const MemRegion *SelfRegion = ValueRegionSVal->getRegion();
928
0
    assert(SelfRegion);
929
930
0
    const NullabilityState *TrackedSelfNullability =
931
0
        State->get<NullabilityMap>(SelfRegion);
932
0
    if (TrackedSelfNullability)
933
0
      return TrackedSelfNullability->getValue();
934
0
  }
935
25
  return Nullability::Unspecified;
936
25
}
937
938
// The return value of a property access is typically a temporary value which
939
// will not be tracked in a persistent manner by the analyzer.  We use
940
// evalAssume() in order to immediately record constraints on those temporaries
941
// at the time they are imposed (e.g. by a nil-check conditional).
942
ProgramStateRef NullabilityChecker::evalAssume(ProgramStateRef State, SVal Cond,
943
4.23k
                                               bool Assumption) const {
944
4.23k
  PropertyAccessesMapTy PropertyAccesses = State->get<PropertyAccessesMap>();
945
4.23k
  for (auto [PropKey, PropVal] : PropertyAccesses) {
946
168
    if (!PropVal.isConstrainedNonnull) {
947
60
      ConditionTruthVal IsNonNull = State->isNonNull(PropVal.Value);
948
60
      if (IsNonNull.isConstrainedTrue()) {
949
24
        ConstrainedPropertyVal Replacement = PropVal;
950
24
        Replacement.isConstrainedNonnull = true;
951
24
        State = State->set<PropertyAccessesMap>(PropKey, Replacement);
952
36
      } else if (IsNonNull.isConstrainedFalse()) {
953
        // Space optimization: no point in tracking constrained-null cases
954
24
        State = State->remove<PropertyAccessesMap>(PropKey);
955
24
      }
956
60
    }
957
168
  }
958
959
4.23k
  return State;
960
4.23k
}
961
962
/// Calculate the nullability of the result of a message expr based on the
963
/// nullability of the receiver, the nullability of the return value, and the
964
/// constraints.
965
void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M,
966
347
                                              CheckerContext &C) const {
967
347
  auto Decl = M.getDecl();
968
347
  if (!Decl)
969
0
    return;
970
347
  QualType RetType = Decl->getReturnType();
971
347
  if (!isValidPointerType(RetType))
972
111
    return;
973
974
236
  ProgramStateRef State = C.getState();
975
236
  if (State->get<InvariantViolated>())
976
12
    return;
977
978
224
  const MemRegion *ReturnRegion = getTrackRegion(M.getReturnValue());
979
224
  if (!ReturnRegion)
980
9
    return;
981
982
215
  auto Interface = Decl->getClassInterface();
983
215
  auto Name = Interface ? 
Interface->getName()160
:
""55
;
984
  // In order to reduce the noise in the diagnostics generated by this checker,
985
  // some framework and programming style based heuristics are used. These
986
  // heuristics are for Cocoa APIs which have NS prefix.
987
215
  if (Name.startswith("NS")) {
988
    // Developers rely on dynamic invariants such as an item should be available
989
    // in a collection, or a collection is not empty often. Those invariants can
990
    // not be inferred by any static analysis tool. To not to bother the users
991
    // with too many false positives, every item retrieval function should be
992
    // ignored for collections. The instance methods of dictionaries in Cocoa
993
    // are either item retrieval related or not interesting nullability wise.
994
    // Using this fact, to keep the code easier to read just ignore the return
995
    // value of every instance method of dictionaries.
996
22
    if (M.isInstanceMessage() && 
Name.contains("Dictionary")9
) {
997
1
      State =
998
1
          State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
999
1
      C.addTransition(State);
1000
1
      return;
1001
1
    }
1002
    // For similar reasons ignore some methods of Cocoa arrays.
1003
21
    StringRef FirstSelectorSlot = M.getSelector().getNameForSlot(0);
1004
21
    if (Name.contains("Array") &&
1005
21
        
(0
FirstSelectorSlot == "firstObject"0
||
1006
0
         FirstSelectorSlot == "lastObject")) {
1007
0
      State =
1008
0
          State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
1009
0
      C.addTransition(State);
1010
0
      return;
1011
0
    }
1012
1013
    // Encoding related methods of string should not fail when lossless
1014
    // encodings are used. Using lossless encodings is so frequent that ignoring
1015
    // this class of methods reduced the emitted diagnostics by about 30% on
1016
    // some projects (and all of that was false positives).
1017
21
    if (Name.contains("String")) {
1018
0
      for (auto *Param : M.parameters()) {
1019
0
        if (Param->getName() == "encoding") {
1020
0
          State = State->set<NullabilityMap>(ReturnRegion,
1021
0
                                             Nullability::Contradicted);
1022
0
          C.addTransition(State);
1023
0
          return;
1024
0
        }
1025
0
      }
1026
0
    }
1027
21
  }
1028
1029
214
  const ObjCMessageExpr *Message = M.getOriginExpr();
1030
214
  Nullability SelfNullability = getReceiverNullability(M, State);
1031
1032
214
  const NullabilityState *NullabilityOfReturn =
1033
214
      State->get<NullabilityMap>(ReturnRegion);
1034
1035
214
  if (NullabilityOfReturn) {
1036
    // When we have a nullability tracked for the return value, the nullability
1037
    // of the expression will be the most nullable of the receiver and the
1038
    // return value.
1039
2
    Nullability RetValTracked = NullabilityOfReturn->getValue();
1040
2
    Nullability ComputedNullab =
1041
2
        getMostNullable(RetValTracked, SelfNullability);
1042
2
    if (ComputedNullab != RetValTracked &&
1043
2
        
ComputedNullab != Nullability::Unspecified0
) {
1044
0
      const Stmt *NullabilitySource =
1045
0
          ComputedNullab == RetValTracked
1046
0
              ? NullabilityOfReturn->getNullabilitySource()
1047
0
              : Message->getInstanceReceiver();
1048
0
      State = State->set<NullabilityMap>(
1049
0
          ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
1050
0
      C.addTransition(State);
1051
0
    }
1052
2
    return;
1053
2
  }
1054
1055
  // No tracked information. Use static type information for return value.
1056
212
  Nullability RetNullability = getNullabilityAnnotation(RetType);
1057
1058
  // Properties might be computed, which means the property value could
1059
  // theoretically change between calls even in commonly-observed cases like
1060
  // this:
1061
  //
1062
  //     if (foo.prop) {    // ok, it's nonnull here...
1063
  //         [bar doStuffWithNonnullVal:foo.prop];     // ...but what about
1064
  //         here?
1065
  //     }
1066
  //
1067
  // If the property is nullable-annotated, a naive analysis would lead to many
1068
  // false positives despite the presence of probably-correct nil-checks.  To
1069
  // reduce the false positive rate, we maintain a history of the most recently
1070
  // observed property value.  For each property access, if the prior value has
1071
  // been constrained to be not nil then we will conservatively assume that the
1072
  // next access can be inferred as nonnull.
1073
212
  if (RetNullability != Nullability::Nonnull &&
1074
212
      
M.getMessageKind() == OCM_PropertyAccess134
&&
!C.wasInlined74
) {
1075
64
    bool LookupResolved = false;
1076
64
    if (const MemRegion *ReceiverRegion = getTrackRegion(M.getReceiverSVal())) {
1077
64
      if (IdentifierInfo *Ident = M.getSelector().getIdentifierInfoForSlot(0)) {
1078
64
        LookupResolved = true;
1079
64
        ObjectPropPair Key = std::make_pair(ReceiverRegion, Ident);
1080
64
        const ConstrainedPropertyVal *PrevPropVal =
1081
64
            State->get<PropertyAccessesMap>(Key);
1082
64
        if (PrevPropVal && 
PrevPropVal->isConstrainedNonnull20
) {
1083
20
          RetNullability = Nullability::Nonnull;
1084
44
        } else {
1085
          // If a previous property access was constrained as nonnull, we hold
1086
          // on to that constraint (effectively inferring that all subsequent
1087
          // accesses on that code path can be inferred as nonnull).  If the
1088
          // previous property access was *not* constrained as nonnull, then
1089
          // let's throw it away in favor of keeping the SVal associated with
1090
          // this more recent access.
1091
44
          if (auto ReturnSVal =
1092
44
                  M.getReturnValue().getAs<DefinedOrUnknownSVal>()) {
1093
44
            State = State->set<PropertyAccessesMap>(
1094
44
                Key, ConstrainedPropertyVal(*ReturnSVal));
1095
44
          }
1096
44
        }
1097
64
      }
1098
64
    }
1099
1100
64
    if (!LookupResolved) {
1101
      // Fallback: err on the side of suppressing the false positive.
1102
0
      RetNullability = Nullability::Nonnull;
1103
0
    }
1104
64
  }
1105
1106
212
  Nullability ComputedNullab = getMostNullable(RetNullability, SelfNullability);
1107
212
  if (ComputedNullab == Nullability::Nullable) {
1108
56
    const Stmt *NullabilitySource = ComputedNullab == RetNullability
1109
56
                                        ? Message
1110
56
                                        : 
Message->getInstanceReceiver()0
;
1111
56
    State = State->set<NullabilityMap>(
1112
56
        ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
1113
56
    C.addTransition(State);
1114
56
  }
1115
212
}
1116
1117
/// Explicit casts are trusted. If there is a disagreement in the nullability
1118
/// annotations in the destination and the source or '0' is casted to nonnull
1119
/// track the value as having contraditory nullability. This will allow users to
1120
/// suppress warnings.
1121
void NullabilityChecker::checkPostStmt(const ExplicitCastExpr *CE,
1122
129
                                       CheckerContext &C) const {
1123
129
  QualType OriginType = CE->getSubExpr()->getType();
1124
129
  QualType DestType = CE->getType();
1125
129
  if (!isValidPointerType(OriginType))
1126
17
    return;
1127
112
  if (!isValidPointerType(DestType))
1128
22
    return;
1129
1130
90
  ProgramStateRef State = C.getState();
1131
90
  if (State->get<InvariantViolated>())
1132
16
    return;
1133
1134
74
  Nullability DestNullability = getNullabilityAnnotation(DestType);
1135
1136
  // No explicit nullability in the destination type, so this cast does not
1137
  // change the nullability.
1138
74
  if (DestNullability == Nullability::Unspecified)
1139
2
    return;
1140
1141
72
  auto RegionSVal = C.getSVal(CE).getAs<DefinedOrUnknownSVal>();
1142
72
  const MemRegion *Region = getTrackRegion(*RegionSVal);
1143
72
  if (!Region)
1144
56
    return;
1145
1146
  // When 0 is converted to nonnull mark it as contradicted.
1147
16
  if (DestNullability == Nullability::Nonnull) {
1148
16
    NullConstraint Nullness = getNullConstraint(*RegionSVal, State);
1149
16
    if (Nullness == NullConstraint::IsNull) {
1150
0
      State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
1151
0
      C.addTransition(State);
1152
0
      return;
1153
0
    }
1154
16
  }
1155
1156
16
  const NullabilityState *TrackedNullability =
1157
16
      State->get<NullabilityMap>(Region);
1158
1159
16
  if (!TrackedNullability) {
1160
0
    if (DestNullability != Nullability::Nullable)
1161
0
      return;
1162
0
    State = State->set<NullabilityMap>(Region,
1163
0
                                       NullabilityState(DestNullability, CE));
1164
0
    C.addTransition(State);
1165
0
    return;
1166
0
  }
1167
1168
16
  if (TrackedNullability->getValue() != DestNullability &&
1169
16
      TrackedNullability->getValue() != Nullability::Contradicted) {
1170
12
    State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
1171
12
    C.addTransition(State);
1172
12
  }
1173
16
}
1174
1175
/// For a given statement performing a bind, attempt to syntactically
1176
/// match the expression resulting in the bound value.
1177
439
static const Expr * matchValueExprForBind(const Stmt *S) {
1178
  // For `x = e` the value expression is the right-hand side.
1179
439
  if (auto *BinOp = dyn_cast<BinaryOperator>(S)) {
1180
143
    if (BinOp->getOpcode() == BO_Assign)
1181
143
      return BinOp->getRHS();
1182
143
  }
1183
1184
  // For `int x = e` the value expression is the initializer.
1185
296
  if (auto *DS = dyn_cast<DeclStmt>(S))  {
1186
295
    if (DS->isSingleDecl()) {
1187
295
      auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
1188
295
      if (!VD)
1189
0
        return nullptr;
1190
1191
295
      if (const Expr *Init = VD->getInit())
1192
295
        return Init;
1193
295
    }
1194
295
  }
1195
1196
1
  return nullptr;
1197
296
}
1198
1199
/// Returns true if \param S is a DeclStmt for a local variable that
1200
/// ObjC automated reference counting initialized with zero.
1201
16
static bool isARCNilInitializedLocal(CheckerContext &C, const Stmt *S) {
1202
  // We suppress diagnostics for ARC zero-initialized _Nonnull locals. This
1203
  // prevents false positives when a _Nonnull local variable cannot be
1204
  // initialized with an initialization expression:
1205
  //    NSString * _Nonnull s; // no-warning
1206
  //    @autoreleasepool {
1207
  //      s = ...
1208
  //    }
1209
  //
1210
  // FIXME: We should treat implicitly zero-initialized _Nonnull locals as
1211
  // uninitialized in Sema's UninitializedValues analysis to warn when a use of
1212
  // the zero-initialized definition will unexpectedly yield nil.
1213
1214
  // Locals are only zero-initialized when automated reference counting
1215
  // is turned on.
1216
16
  if (!C.getASTContext().getLangOpts().ObjCAutoRefCount)
1217
7
    return false;
1218
1219
9
  auto *DS = dyn_cast<DeclStmt>(S);
1220
9
  if (!DS || 
!DS->isSingleDecl()4
)
1221
5
    return false;
1222
1223
4
  auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
1224
4
  if (!VD)
1225
0
    return false;
1226
1227
  // Sema only zero-initializes locals with ObjCLifetimes.
1228
4
  if(!VD->getType().getQualifiers().hasObjCLifetime())
1229
2
    return false;
1230
1231
2
  const Expr *Init = VD->getInit();
1232
2
  assert(Init && "ObjC local under ARC without initializer");
1233
1234
  // Return false if the local is explicitly initialized (e.g., with '= nil').
1235
2
  if (!isa<ImplicitValueInitExpr>(Init))
1236
2
    return false;
1237
1238
0
  return true;
1239
2
}
1240
1241
/// Propagate the nullability information through binds and warn when nullable
1242
/// pointer or null symbol is assigned to a pointer with a nonnull type.
1243
void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S,
1244
599
                                   CheckerContext &C) const {
1245
599
  const TypedValueRegion *TVR =
1246
599
      dyn_cast_or_null<TypedValueRegion>(L.getAsRegion());
1247
599
  if (!TVR)
1248
24
    return;
1249
1250
575
  QualType LocType = TVR->getValueType();
1251
575
  if (!isValidPointerType(LocType))
1252
77
    return;
1253
1254
498
  ProgramStateRef State = C.getState();
1255
498
  if (State->get<InvariantViolated>())
1256
59
    return;
1257
1258
439
  auto ValDefOrUnknown = V.getAs<DefinedOrUnknownSVal>();
1259
439
  if (!ValDefOrUnknown)
1260
0
    return;
1261
1262
439
  NullConstraint RhsNullness = getNullConstraint(*ValDefOrUnknown, State);
1263
1264
439
  Nullability ValNullability = Nullability::Unspecified;
1265
439
  if (SymbolRef Sym = ValDefOrUnknown->getAsSymbol())
1266
261
    ValNullability = getNullabilityAnnotation(Sym->getType());
1267
1268
439
  Nullability LocNullability = getNullabilityAnnotation(LocType);
1269
1270
  // If the type of the RHS expression is nonnull, don't warn. This
1271
  // enables explicit suppression with a cast to nonnull.
1272
439
  Nullability ValueExprTypeLevelNullability = Nullability::Unspecified;
1273
439
  const Expr *ValueExpr = matchValueExprForBind(S);
1274
439
  if (ValueExpr) {
1275
438
    ValueExprTypeLevelNullability =
1276
438
      getNullabilityAnnotation(lookThroughImplicitCasts(ValueExpr)->getType());
1277
438
  }
1278
1279
439
  bool NullAssignedToNonNull = (LocNullability == Nullability::Nonnull &&
1280
439
                                
RhsNullness == NullConstraint::IsNull112
);
1281
439
  if (ChecksEnabled[CK_NullPassedToNonnull] && NullAssignedToNonNull &&
1282
439
      
ValNullability != Nullability::Nonnull34
&&
1283
439
      
ValueExprTypeLevelNullability != Nullability::Nonnull34
&&
1284
439
      
!isARCNilInitializedLocal(C, S)16
) {
1285
16
    static CheckerProgramPointTag Tag(this, "NullPassedToNonnull");
1286
16
    ExplodedNode *N = C.generateErrorNode(State, &Tag);
1287
16
    if (!N)
1288
0
      return;
1289
1290
1291
16
    const Stmt *ValueStmt = S;
1292
16
    if (ValueExpr)
1293
16
      ValueStmt = ValueExpr;
1294
1295
16
    SmallString<256> SBuf;
1296
16
    llvm::raw_svector_ostream OS(SBuf);
1297
16
    OS << (LocType->isObjCObjectPointerType() ? 
"nil"3
:
"Null"13
);
1298
16
    OS << " assigned to a pointer which is expected to have non-null value";
1299
16
    reportBugIfInvariantHolds(OS.str(), ErrorKind::NilAssignedToNonnull,
1300
16
                              CK_NullPassedToNonnull, N, nullptr, C, ValueStmt);
1301
16
    return;
1302
16
  }
1303
1304
  // If null was returned from a non-null function, mark the nullability
1305
  // invariant as violated even if the diagnostic was suppressed.
1306
423
  if (NullAssignedToNonNull) {
1307
18
    State = State->set<InvariantViolated>(true);
1308
18
    C.addTransition(State);
1309
18
    return;
1310
18
  }
1311
1312
  // Intentionally missing case: '0' is bound to a reference. It is handled by
1313
  // the DereferenceChecker.
1314
1315
405
  const MemRegion *ValueRegion = getTrackRegion(*ValDefOrUnknown);
1316
405
  if (!ValueRegion)
1317
148
    return;
1318
1319
257
  const NullabilityState *TrackedNullability =
1320
257
      State->get<NullabilityMap>(ValueRegion);
1321
1322
257
  if (TrackedNullability) {
1323
79
    if (RhsNullness == NullConstraint::IsNotNull ||
1324
79
        TrackedNullability->getValue() != Nullability::Nullable)
1325
5
      return;
1326
74
    if (ChecksEnabled[CK_NullablePassedToNonnull] &&
1327
74
        LocNullability == Nullability::Nonnull) {
1328
4
      static CheckerProgramPointTag Tag(this, "NullablePassedToNonnull");
1329
4
      ExplodedNode *N = C.addTransition(State, C.getPredecessor(), &Tag);
1330
4
      reportBugIfInvariantHolds("Nullable pointer is assigned to a pointer "
1331
4
                                "which is expected to have non-null value",
1332
4
                                ErrorKind::NullableAssignedToNonnull,
1333
4
                                CK_NullablePassedToNonnull, N, ValueRegion, C);
1334
4
    }
1335
74
    return;
1336
79
  }
1337
1338
178
  const auto *BinOp = dyn_cast<BinaryOperator>(S);
1339
1340
178
  if (ValNullability == Nullability::Nullable) {
1341
    // Trust the static information of the value more than the static
1342
    // information on the location.
1343
0
    const Stmt *NullabilitySource = BinOp ? BinOp->getRHS() : S;
1344
0
    State = State->set<NullabilityMap>(
1345
0
        ValueRegion, NullabilityState(ValNullability, NullabilitySource));
1346
0
    C.addTransition(State);
1347
0
    return;
1348
0
  }
1349
1350
178
  if (LocNullability == Nullability::Nullable) {
1351
0
    const Stmt *NullabilitySource = BinOp ? BinOp->getLHS() : S;
1352
0
    State = State->set<NullabilityMap>(
1353
0
        ValueRegion, NullabilityState(LocNullability, NullabilitySource));
1354
0
    C.addTransition(State);
1355
0
  }
1356
178
}
1357
1358
void NullabilityChecker::printState(raw_ostream &Out, ProgramStateRef State,
1359
0
                                    const char *NL, const char *Sep) const {
1360
1361
0
  NullabilityMapTy B = State->get<NullabilityMap>();
1362
1363
0
  if (State->get<InvariantViolated>())
1364
0
    Out << Sep << NL
1365
0
        << "Nullability invariant was violated, warnings suppressed." << NL;
1366
1367
0
  if (B.isEmpty())
1368
0
    return;
1369
1370
0
  if (!State->get<InvariantViolated>())
1371
0
    Out << Sep << NL;
1372
1373
0
  for (auto [Region, State] : B) {
1374
0
    Out << Region << " : ";
1375
0
    State.print(Out);
1376
0
    Out << NL;
1377
0
  }
1378
0
}
1379
1380
52
void ento::registerNullabilityBase(CheckerManager &mgr) {
1381
52
  mgr.registerChecker<NullabilityChecker>();
1382
52
}
1383
1384
346
bool ento::shouldRegisterNullabilityBase(const CheckerManager &mgr) {
1385
346
  return true;
1386
346
}
1387
1388
#define REGISTER_CHECKER(name, trackingRequired)                               \
1389
157
  void ento::register##name##Checker(CheckerManager &mgr) {                    \
1390
157
    NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>();        \
1391
157
    checker->ChecksEnabled[NullabilityChecker::CK_##name] = true;              \
1392
157
    checker->CheckNames[NullabilityChecker::CK_##name] =                       \
1393
157
        mgr.getCurrentCheckerName();                                           \
1394
157
    checker->NeedTracking = checker->NeedTracking || 
trackingRequired121
; \
1395
157
    checker->NoDiagnoseCallsToSystemHeaders =                                  \
1396
157
        checker->NoDiagnoseCallsToSystemHeaders ||                             \
1397
157
        mgr.getAnalyzerOptions().getCheckerBooleanOption(                      \
1398
148
            checker, "NoDiagnoseCallsToSystemHeaders", true);                  \
1399
157
  }                                                                            \
clang::ento::registerNullPassedToNonnullChecker(clang::ento::CheckerManager&)
Line
Count
Source
1389
51
  void ento::register##name##Checker(CheckerManager &mgr) {                    \
1390
51
    NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>();        \
1391
51
    checker->ChecksEnabled[NullabilityChecker::CK_##name] = true;              \
1392
51
    checker->CheckNames[NullabilityChecker::CK_##name] =                       \
1393
51
        mgr.getCurrentCheckerName();                                           \
1394
51
    checker->NeedTracking = checker->NeedTracking || trackingRequired;         \
1395
51
    checker->NoDiagnoseCallsToSystemHeaders =                                  \
1396
51
        checker->NoDiagnoseCallsToSystemHeaders ||                             \
1397
51
        mgr.getAnalyzerOptions().getCheckerBooleanOption(                      \
1398
51
            checker, "NoDiagnoseCallsToSystemHeaders", true);                  \
1399
51
  }                                                                            \
clang::ento::registerNullReturnedFromNonnullChecker(clang::ento::CheckerManager&)
Line
Count
Source
1389
52
  void ento::register##name##Checker(CheckerManager &mgr) {                    \
1390
52
    NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>();        \
1391
52
    checker->ChecksEnabled[NullabilityChecker::CK_##name] = true;              \
1392
52
    checker->CheckNames[NullabilityChecker::CK_##name] =                       \
1393
52
        mgr.getCurrentCheckerName();                                           \
1394
52
    checker->NeedTracking = checker->NeedTracking || trackingRequired;         \
1395
52
    checker->NoDiagnoseCallsToSystemHeaders =                                  \
1396
52
        checker->NoDiagnoseCallsToSystemHeaders ||                             \
1397
52
        mgr.getAnalyzerOptions().getCheckerBooleanOption(                      \
1398
49
            checker, "NoDiagnoseCallsToSystemHeaders", true);                  \
1399
52
  }                                                                            \
clang::ento::registerNullableDereferencedChecker(clang::ento::CheckerManager&)
Line
Count
Source
1389
18
  void ento::register##name##Checker(CheckerManager &mgr) {                    \
1390
18
    NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>();        \
1391
18
    checker->ChecksEnabled[NullabilityChecker::CK_##name] = true;              \
1392
18
    checker->CheckNames[NullabilityChecker::CK_##name] =                       \
1393
18
        mgr.getCurrentCheckerName();                                           \
1394
18
    checker->NeedTracking = checker->NeedTracking || trackingRequired;         \
1395
18
    checker->NoDiagnoseCallsToSystemHeaders =                                  \
1396
18
        checker->NoDiagnoseCallsToSystemHeaders ||                             \
1397
18
        mgr.getAnalyzerOptions().getCheckerBooleanOption(                      \
1398
16
            checker, "NoDiagnoseCallsToSystemHeaders", true);                  \
1399
18
  }                                                                            \
clang::ento::registerNullablePassedToNonnullChecker(clang::ento::CheckerManager&)
Line
Count
Source
1389
18
  void ento::register##name##Checker(CheckerManager &mgr) {                    \
1390
18
    NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>();        \
1391
18
    checker->ChecksEnabled[NullabilityChecker::CK_##name] = true;              \
1392
18
    checker->CheckNames[NullabilityChecker::CK_##name] =                       \
1393
18
        mgr.getCurrentCheckerName();                                           \
1394
18
    checker->NeedTracking = checker->NeedTracking || 
trackingRequired0
; \
1395
18
    checker->NoDiagnoseCallsToSystemHeaders =                                  \
1396
18
        checker->NoDiagnoseCallsToSystemHeaders ||                             \
1397
18
        mgr.getAnalyzerOptions().getCheckerBooleanOption(                      \
1398
16
            checker, "NoDiagnoseCallsToSystemHeaders", true);                  \
1399
18
  }                                                                            \
clang::ento::registerNullableReturnedFromNonnullChecker(clang::ento::CheckerManager&)
Line
Count
Source
1389
18
  void ento::register##name##Checker(CheckerManager &mgr) {                    \
1390
18
    NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>();        \
1391
18
    checker->ChecksEnabled[NullabilityChecker::CK_##name] = true;              \
1392
18
    checker->CheckNames[NullabilityChecker::CK_##name] =                       \
1393
18
        mgr.getCurrentCheckerName();                                           \
1394
18
    checker->NeedTracking = checker->NeedTracking || 
trackingRequired0
; \
1395
18
    checker->NoDiagnoseCallsToSystemHeaders =                                  \
1396
18
        checker->NoDiagnoseCallsToSystemHeaders ||                             \
1397
18
        mgr.getAnalyzerOptions().getCheckerBooleanOption(                      \
1398
16
            checker, "NoDiagnoseCallsToSystemHeaders", true);                  \
1399
18
  }                                                                            \
1400
                                                                               \
1401
322
  bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) {        \
1402
322
    return true;                                                               \
1403
322
  }
clang::ento::shouldRegisterNullPassedToNonnullChecker(clang::ento::CheckerManager const&)
Line
Count
Source
1401
106
  bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) {        \
1402
106
    return true;                                                               \
1403
106
  }
clang::ento::shouldRegisterNullReturnedFromNonnullChecker(clang::ento::CheckerManager const&)
Line
Count
Source
1401
108
  bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) {        \
1402
108
    return true;                                                               \
1403
108
  }
clang::ento::shouldRegisterNullableDereferencedChecker(clang::ento::CheckerManager const&)
Line
Count
Source
1401
36
  bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) {        \
1402
36
    return true;                                                               \
1403
36
  }
clang::ento::shouldRegisterNullablePassedToNonnullChecker(clang::ento::CheckerManager const&)
Line
Count
Source
1401
36
  bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) {        \
1402
36
    return true;                                                               \
1403
36
  }
clang::ento::shouldRegisterNullableReturnedFromNonnullChecker(clang::ento::CheckerManager const&)
Line
Count
Source
1401
36
  bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) {        \
1402
36
    return true;                                                               \
1403
36
  }
1404
1405
// The checks are likely to be turned on by default and it is possible to do
1406
// them without tracking any nullability related information. As an optimization
1407
// no nullability information will be tracked when only these two checks are
1408
// enables.
1409
REGISTER_CHECKER(NullPassedToNonnull, false)
1410
REGISTER_CHECKER(NullReturnedFromNonnull, false)
1411
1412
REGISTER_CHECKER(NullableDereferenced, true)
1413
REGISTER_CHECKER(NullablePassedToNonnull, true)
1414
REGISTER_CHECKER(NullableReturnedFromNonnull, true)