Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -verify %s
      2 
      3 int getRandom();
      4 
      5 typedef struct Dummy { int val; } Dummy;
      6 
      7 void takesNullable(Dummy *_Nullable);
      8 void takesNonnull(Dummy *_Nonnull);
      9 Dummy *_Nullable returnsNullable();
     10 
     11 void 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 
     22 Dummy *_Nonnull testNullReturn() {
     23   Dummy *p = 0;
     24   return p; // expected-warning {{}}
     25 }
     26 
     27 void 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 
     37 Dummy *_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 
     51 Dummy *_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 
     64 void testPreconditionViolationInInlinedFunction(Dummy *p) {
     65   doNotWarnWhenPreconditionIsViolated(p);
     66 }
     67 
     68 void inlinedNullable(Dummy *_Nullable p) {
     69   if (p) return;
     70 }
     71 void inlinedNonnull(Dummy *_Nonnull p) {
     72   if (p) return;
     73 }
     74 void inlinedUnspecified(Dummy *p) {
     75   if (p) return;
     76 }
     77 
     78 Dummy *_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