false-positive-suppression.c revision 6a329ee7567cf3267ffab2bc755ea8c773d967e7
1// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s 2// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s 3// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s 4 5int opaquePropertyCheck(void *object); 6int coin(); 7 8int *getNull() { 9 return 0; 10} 11 12int *dynCastToInt(void *ptr) { 13 if (opaquePropertyCheck(ptr)) 14 return (int *)ptr; 15 return 0; 16} 17 18int *dynCastOrNull(void *ptr) { 19 if (!ptr) 20 return 0; 21 if (opaquePropertyCheck(ptr)) 22 return (int *)ptr; 23 return 0; 24} 25 26 27void testDynCast(void *p) { 28 int *casted = dynCastToInt(p); 29 *casted = 1; 30#ifndef SUPPRESSED 31 // expected-warning@-2 {{Dereference of null pointer}} 32#endif 33} 34 35void testDynCastOrNull(void *p) { 36 int *casted = dynCastOrNull(p); 37 *casted = 1; 38#ifndef SUPPRESSED 39 // expected-warning@-2 {{Dereference of null pointer}} 40#endif 41} 42 43 44void testBranch(void *p) { 45 int *casted; 46 47 // Although the report will be suppressed on one branch, it should still be 48 // valid on the other. 49 if (coin()) { 50 casted = dynCastToInt(p); 51 } else { 52 if (p) 53 return; 54 casted = (int *)p; 55 } 56 57 *casted = 1; // expected-warning {{Dereference of null pointer}} 58} 59 60void testBranchReversed(void *p) { 61 int *casted; 62 63 // Although the report will be suppressed on one branch, it should still be 64 // valid on the other. 65 if (coin()) { 66 if (p) 67 return; 68 casted = (int *)p; 69 } else { 70 casted = dynCastToInt(p); 71 } 72 73 *casted = 1; // expected-warning {{Dereference of null pointer}} 74} 75 76 77// -------------------------- 78// "Suppression suppression" 79// -------------------------- 80 81void testDynCastOrNullOfNull() { 82 // Don't suppress when one of the arguments is NULL. 83 int *casted = dynCastOrNull(0); 84 *casted = 1; 85#if !SUPPRESSED || NULL_ARGS 86 // expected-warning@-2 {{Dereference of null pointer}} 87#endif 88} 89 90void testDynCastOfNull() { 91 // Don't suppress when one of the arguments is NULL. 92 int *casted = dynCastToInt(0); 93 *casted = 1; 94#if !SUPPRESSED || NULL_ARGS 95 // expected-warning@-2 {{Dereference of null pointer}} 96#endif 97} 98 99int *lookUpInt(int unused) { 100 if (coin()) 101 return 0; 102 static int x; 103 return &x; 104} 105 106void testZeroIsNotNull() { 107 // /Do/ suppress when the argument is 0 (an integer). 108 int *casted = lookUpInt(0); 109 *casted = 1; 110#ifndef SUPPRESSED 111 // expected-warning@-2 {{Dereference of null pointer}} 112#endif 113} 114 115void testTrackNull() { 116 // /Do/ suppress if the null argument came from another call returning null. 117 int *casted = dynCastOrNull(getNull()); 118 *casted = 1; 119#ifndef SUPPRESSED 120 // expected-warning@-2 {{Dereference of null pointer}} 121#endif 122} 123 124void testTrackNullVariable() { 125 // /Do/ suppress if the null argument came from another call returning null. 126 int *ptr; 127 ptr = getNull(); 128 int *casted = dynCastOrNull(ptr); 129 *casted = 1; 130#ifndef SUPPRESSED 131 // expected-warning@-2 {{Dereference of null pointer}} 132#endif 133} 134 135 136// --------------------------------------- 137// FALSE NEGATIVES (over-suppression) 138// --------------------------------------- 139 140void testNoArguments() { 141 // In this case the function has no branches, and MUST return null. 142 int *casted = getNull(); 143 *casted = 1; 144#ifndef SUPPRESSED 145 // expected-warning@-2 {{Dereference of null pointer}} 146#endif 147} 148 149int *getNullIfNonNull(void *input) { 150 if (input) 151 return 0; 152 static int x; 153 return &x; 154} 155 156void testKnownPath(void *input) { 157 if (!input) 158 return; 159 160 // In this case we have a known value for the argument, and thus the path 161 // through the function doesn't ever split. 162 int *casted = getNullIfNonNull(input); 163 *casted = 1; 164#ifndef SUPPRESSED 165 // expected-warning@-2 {{Dereference of null pointer}} 166#endif 167} 168 169int *alwaysReturnNull(void *input) { 170 if (opaquePropertyCheck(input)) 171 return 0; 172 return 0; 173} 174 175void testAlwaysReturnNull(void *input) { 176 // In this case all paths out of the function return 0, but they are all 177 // dominated by a branch whose condition we don't know! 178 int *casted = alwaysReturnNull(input); 179 *casted = 1; 180#ifndef SUPPRESSED 181 // expected-warning@-2 {{Dereference of null pointer}} 182#endif 183} 184 185