1 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config suppress-null-return-paths=false -verify %s 2 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false %s -o %t.plist 3 // RUN: %normalize_plist <%t.plist | diff -u %S/Inputs/expected-plists/path-notes.c.plist - 4 5 void zero(int **p) { 6 *p = 0; 7 // expected-note@-1 {{Null pointer value stored to 'a'}} 8 } 9 10 void testZero(int *a) { 11 zero(&a); 12 // expected-note@-1 {{Calling 'zero'}} 13 // expected-note@-2 {{Returning from 'zero'}} 14 *a = 1; // expected-warning{{Dereference of null pointer}} 15 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} 16 } 17 18 void testCheck(int *a) { 19 if (a) { 20 // expected-note@-1 + {{Assuming 'a' is null}} 21 // expected-note@-2 + {{Taking false branch}} 22 ; 23 } 24 *a = 1; // expected-warning{{Dereference of null pointer}} 25 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} 26 } 27 28 29 int *getPointer(); 30 31 void testInitCheck() { 32 int *a = getPointer(); 33 // expected-note@-1 {{'a' initialized here}} 34 if (a) { 35 // expected-note@-1 + {{Assuming 'a' is null}} 36 // expected-note@-2 + {{Taking false branch}} 37 ; 38 } 39 *a = 1; // expected-warning{{Dereference of null pointer}} 40 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} 41 } 42 43 void testStoreCheck(int *a) { 44 a = getPointer(); 45 // expected-note@-1 {{Value assigned to 'a'}} 46 if (a) { 47 // expected-note@-1 + {{Assuming 'a' is null}} 48 // expected-note@-2 + {{Taking false branch}} 49 ; 50 } 51 *a = 1; // expected-warning{{Dereference of null pointer}} 52 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} 53 } 54 55 56 int *getZero() { 57 int *p = 0; 58 // expected-note@-1 + {{'p' initialized to a null pointer value}} 59 // ^ This note checks that we add a second visitor for the return value. 60 return p; 61 // expected-note@-1 + {{Returning null pointer (loaded from 'p')}} 62 } 63 64 void testReturnZero() { 65 *getZero() = 1; // expected-warning{{Dereference of null pointer}} 66 // expected-note@-1 {{Calling 'getZero'}} 67 // expected-note@-2 {{Returning from 'getZero'}} 68 // expected-note@-3 {{Dereference of null pointer}} 69 } 70 71 int testReturnZero2() { 72 return *getZero(); // expected-warning{{Dereference of null pointer}} 73 // expected-note@-1 {{Calling 'getZero'}} 74 // expected-note@-2 {{Returning from 'getZero'}} 75 // expected-note@-3 {{Dereference of null pointer}} 76 } 77 78 void testInitZero() { 79 int *a = getZero(); 80 // expected-note@-1 {{Calling 'getZero'}} 81 // expected-note@-2 {{Returning from 'getZero'}} 82 // expected-note@-3 {{'a' initialized to a null pointer value}} 83 *a = 1; // expected-warning{{Dereference of null pointer}} 84 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} 85 } 86 87 void testStoreZero(int *a) { 88 a = getZero(); 89 // expected-note@-1 {{Calling 'getZero'}} 90 // expected-note@-2 {{Returning from 'getZero'}} 91 // expected-note@-3 {{Null pointer value stored to 'a'}} 92 *a = 1; // expected-warning{{Dereference of null pointer}} 93 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} 94 } 95 96 void usePointer(int *p) { 97 *p = 1; // expected-warning{{Dereference of null pointer}} 98 // expected-note@-1 {{Dereference of null pointer}} 99 } 100 101 void testUseOfNullPointer() { 102 // Test the case where an argument expression is itself a call. 103 usePointer(getZero()); 104 // expected-note@-1 {{Calling 'getZero'}} 105 // expected-note@-2 {{Returning from 'getZero'}} 106 // expected-note@-3 {{Passing null pointer value via 1st parameter 'p'}} 107 // expected-note@-4 {{Calling 'usePointer'}} 108 } 109 110 struct X { char *p; }; 111 112 void setFieldToNull(struct X *x) { 113 x->p = 0; // expected-note {{Null pointer value stored to field 'p'}} 114 } 115 116 int testSetFieldToNull(struct X *x) { 117 setFieldToNull(x); // expected-note {{Calling 'setFieldToNull'}} 118 // expected-note@-1{{Returning from 'setFieldToNull'}} 119 return *x->p; 120 // expected-warning@-1 {{Dereference of null pointer (loaded from field 'p')}} 121 // expected-note@-2 {{Dereference of null pointer (loaded from field 'p')}} 122 } 123 124 struct Outer { 125 struct Inner { 126 int *p; 127 } inner; 128 }; 129 130 void test(struct Outer *wrapperPtr) { 131 wrapperPtr->inner.p = 0; // expected-note {{Null pointer value stored to field 'p'}} 132 *wrapperPtr->inner.p = 1; //expected-warning {{Dereference of null pointer (loaded from field 'p')}} 133 // expected-note@-1 {{Dereference of null pointer (loaded from field 'p')}} 134 } 135 136 void test4(int **p) { 137 if (*p) return; // expected-note {{Taking false branch}} 138 // expected-note@-1 {{Assuming pointer value is null}} 139 **p = 1; // expected-warning {{Dereference of null pointer}} 140 // expected-note@-1 {{Dereference of null pointer}} 141 } 142 143 void boringCallee() { 144 } 145 146 void interestingCallee(int *x) { 147 *x = 0; // expected-note{{The value 0 is assigned to 'x'}} 148 boringCallee(); // no-note 149 } 150 151 int testBoringCalleeOfInterestingCallee() { 152 int x; 153 interestingCallee(&x); // expected-note{{Calling 'interestingCallee'}} 154 // expected-note@-1{{Returning from 'interestingCallee'}} 155 return 1 / x; // expected-warning{{Division by zero}} 156 // expected-note@-1{{Division by zero}} 157 } 158 159