1// RUN: %clang_cc1 -analyze -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -verify %s
2
3int getRandom();
4
5typedef struct Dummy { int val; } Dummy;
6
7void takesNullable(Dummy *_Nullable);
8void takesNonnull(Dummy *_Nonnull);
9Dummy *_Nullable returnsNullable();
10
11void testBasicRules() {
12  // The tracking of nullable values is turned off.
13  Dummy *p = returnsNullable();
14  takesNonnull(p); // no warning
15  Dummy *q = 0;
16  if (getRandom()) {
17    takesNullable(q);
18    takesNonnull(q); // expected-warning {{}}
19  }
20}
21
22Dummy *_Nonnull testNullReturn() {
23  Dummy *p = 0;
24  return p; // expected-warning {{}}
25}
26
27void onlyReportFirstPreconditionViolationOnPath() {
28  Dummy *p = 0;
29  takesNonnull(p); // expected-warning {{}}
30  takesNonnull(p); // No warning.
31  // Passing null to nonnull is a sink. Stop the analysis.
32  int i = 0;
33  i = 5 / i; // no warning
34  (void)i;
35}
36
37Dummy *_Nonnull doNotWarnWhenPreconditionIsViolatedInTopFunc(
38    Dummy *_Nonnull p) {
39  if (!p) {
40    Dummy *ret =
41        0; // avoid compiler warning (which is not generated by the analyzer)
42    if (getRandom())
43      return ret; // no warning
44    else
45      return p; // no warning
46  } else {
47    return p;
48  }
49}
50
51Dummy *_Nonnull doNotWarnWhenPreconditionIsViolated(Dummy *_Nonnull p) {
52  if (!p) {
53    Dummy *ret =
54        0; // avoid compiler warning (which is not generated by the analyzer)
55    if (getRandom())
56      return ret; // no warning
57    else
58      return p; // no warning
59  } else {
60    return p;
61  }
62}
63
64void testPreconditionViolationInInlinedFunction(Dummy *p) {
65  doNotWarnWhenPreconditionIsViolated(p);
66}
67
68void inlinedNullable(Dummy *_Nullable p) {
69  if (p) return;
70}
71void inlinedNonnull(Dummy *_Nonnull p) {
72  if (p) return;
73}
74void inlinedUnspecified(Dummy *p) {
75  if (p) return;
76}
77
78Dummy *_Nonnull testDefensiveInlineChecks(Dummy * p) {
79  switch (getRandom()) {
80  case 1: inlinedNullable(p); break;
81  case 2: inlinedNonnull(p); break;
82  case 3: inlinedUnspecified(p); break;
83  }
84  if (getRandom())
85    takesNonnull(p);
86  return p;
87}
88