243 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s2 3// Perform inline defensive checks.4void idc(void *p) {5 if (p)6 ;7}8 9int test01(int *p) {10 if (p)11 ;12 return *p; // expected-warning {{Dereference of null pointer}}13}14 15int test02(int *p, int *x) {16 if (p)17 ;18 idc(p);19 if (x)20 ;21 return *p; // expected-warning {{Dereference of null pointer}}22}23 24int test03(int *p, int *x) {25 idc(p);26 if (p)27 ;28 return *p; // False negative29}30 31int deref04(int *p) {32 return *p; // expected-warning {{Dereference of null pointer}}33}34 35int test04(int *p) {36 if (p)37 ;38 idc(p);39 return deref04(p);40}41 42int test11(int *q, int *x) {43 int *p = q;44 if (q)45 ;46 if (x)47 ;48 return *p; // expected-warning{{Dereference of null pointer}}49}50 51int test12(int *q) {52 int *p = q;53 idc(q);54 return *p;55}56 57int test13(int *q) {58 int *p = q;59 idc(p);60 return *p;61}62 63int test21(int *q, int *x) {64 if (q)65 ;66 if (x)67 ;68 int *p = q;69 return *p; // expected-warning{{Dereference of null pointer}}70}71 72int test22(int *q, int *x) {73 idc(q);74 if (x)75 ;76 int *p = q;77 return *p;78}79 80int test23(int *q, int *x) {81 idc(q);82 if (x)83 ;84 int *p = q;85 if (!p)86 ;87 return *p; // False negative88}89 90void use(char *p) {91 if (!p)92 return;93 p[0] = 'a';94}95 96void test24(char *buffer) {97 use(buffer);98 buffer[1] = 'b';99}100 101// Ensure idc works on pointers with constant offset.102void idcchar(const char *s2) {103 if(s2)104 ;105}106void testConstantOffset(char *value) {107 char *cursor = value + 5;108 idcchar(cursor);109 if (*cursor) {110 cursor++;111 }112}113 114// Ensure idc works for integer zero values (ex: suppressed div by zero).115void idcZero(int assume) {116 if (assume)117 ;118}119 120int idcTriggerZeroValue(int m) {121 idcZero(m);122 return 5/m; // no-warning123}124 125int idcTriggerZeroValueThroughCall(int i) {126 return 5/i; // no-warning127}128void idcTrackZeroValueThroughCall(int x) {129 idcZero(x);130 idcTriggerZeroValueThroughCall(x);131}132 133int idcTriggerZeroThroughDoubleAssignemnt(int i) {134 return 5/i; // no-warning135}136void idcTrackZeroThroughDoubleAssignemnt(int x) {137 idcZero(x);138 int y = x;139 int z = y;140 idcTriggerZeroValueThroughCall(z);141}142 143struct S {144 int f1;145 int f2;146};147 148void idcTrackZeroValueThroughUnaryPointerOperators(struct S *s) {149 idc(s);150 *(&(s->f1)) = 7; // no-warning151}152 153void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset1(struct S *s) {154 idc(s);155 int *x = &(s->f2);156 *x = 7; // no-warning157}158 159void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset2(struct S *s) {160 idc(s);161 int *x = &(s->f2) - 1;162 *x = 7; // no-warning163}164 165void idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S *s) {166 idc(s);167 int *x = &(s->f1);168 *x = 7; // no-warning169}170 171void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignment(struct S *s) {172 idc(s);173 int *x = &*&(s->f1);174 *x = 7; // no-warning175}176 177void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S *s) {178 idc(s);179 int *x = &*&((++s)->f1);180 *x = 7; // no-warning181}182 183 184struct S2 {185 int a[1];186};187 188void idcTrackZeroValueThroughUnaryPointerOperatorsWithArrayField(struct S2 *s) {189 idc(s);190 *(&(s->a[0])) = 7; // no-warning191}192 193void idcTrackConstraintThroughSymbolicRegion(int **x) {194 idc(*x);195 // FIXME: Should not warn.196 **x = 7; // expected-warning{{Dereference of null pointer}}197}198 199void idcTrackConstraintThroughSymbolicRegionAndParens(int **x) {200 idc(*x);201 // FIXME: Should not warn.202 *(*x) = 7; // expected-warning{{Dereference of null pointer}}203}204 205int *idcPlainNull(int coin) {206 if (coin)207 return 0;208 static int X;209 return &X;210}211 212void idcTrackZeroValueThroughSymbolicRegion(int coin, int **x) {213 *x = idcPlainNull(coin);214 **x = 7; // no-warning215}216 217void idcTrackZeroValueThroughSymbolicRegionAndParens(int coin, int **x) {218 *x = idcPlainNull(coin);219 *(*x) = 7; // no-warning220}221 222struct WithInt {223 int i;224};225 226struct WithArray {227 struct WithInt arr[1];228};229 230struct WithArray *idcPlainNullWithArray(int coin) {231 if (coin)232 return 0;233 static struct WithArray S;234 return &S;235}236 237void idcTrackZeroValueThroughSymbolicRegionWithArray(int coin, struct WithArray **s) {238 *s = idcPlainNullWithArray(coin);239 (*s)->arr[0].i = 1; // no-warning240 // Same thing.241 (*s)->arr->i = 1; // no-warning242}243