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