1184c6242SDominic Chen // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
28d7c8a4dSAnna Zaks
38d7c8a4dSAnna Zaks // Perform inline defensive checks.
idc(void * p)437de8888SArtem Dergachev void idc(void *p) {
58d7c8a4dSAnna Zaks if (p)
68d7c8a4dSAnna Zaks ;
78d7c8a4dSAnna Zaks }
88d7c8a4dSAnna Zaks
test01(int * p)98d7c8a4dSAnna Zaks int test01(int *p) {
108d7c8a4dSAnna Zaks if (p)
118d7c8a4dSAnna Zaks ;
128d7c8a4dSAnna Zaks return *p; // expected-warning {{Dereference of null pointer}}
138d7c8a4dSAnna Zaks }
148d7c8a4dSAnna Zaks
test02(int * p,int * x)158d7c8a4dSAnna Zaks int test02(int *p, int *x) {
168d7c8a4dSAnna Zaks if (p)
178d7c8a4dSAnna Zaks ;
188d7c8a4dSAnna Zaks idc(p);
198d7c8a4dSAnna Zaks if (x)
208d7c8a4dSAnna Zaks ;
218d7c8a4dSAnna Zaks return *p; // expected-warning {{Dereference of null pointer}}
228d7c8a4dSAnna Zaks }
238d7c8a4dSAnna Zaks
test03(int * p,int * x)248d7c8a4dSAnna Zaks int test03(int *p, int *x) {
258d7c8a4dSAnna Zaks idc(p);
268d7c8a4dSAnna Zaks if (p)
278d7c8a4dSAnna Zaks ;
288d7c8a4dSAnna Zaks return *p; // False negative
298d7c8a4dSAnna Zaks }
308d7c8a4dSAnna Zaks
deref04(int * p)318d7c8a4dSAnna Zaks int deref04(int *p) {
328d7c8a4dSAnna Zaks return *p; // expected-warning {{Dereference of null pointer}}
338d7c8a4dSAnna Zaks }
348d7c8a4dSAnna Zaks
test04(int * p)358d7c8a4dSAnna Zaks int test04(int *p) {
368d7c8a4dSAnna Zaks if (p)
378d7c8a4dSAnna Zaks ;
388d7c8a4dSAnna Zaks idc(p);
398d7c8a4dSAnna Zaks return deref04(p);
408d7c8a4dSAnna Zaks }
418d7c8a4dSAnna Zaks
test11(int * q,int * x)428d7c8a4dSAnna Zaks int test11(int *q, int *x) {
438d7c8a4dSAnna Zaks int *p = q;
448d7c8a4dSAnna Zaks if (q)
458d7c8a4dSAnna Zaks ;
468d7c8a4dSAnna Zaks if (x)
478d7c8a4dSAnna Zaks ;
488d7c8a4dSAnna Zaks return *p; // expected-warning{{Dereference of null pointer}}
498d7c8a4dSAnna Zaks }
508d7c8a4dSAnna Zaks
test12(int * q)518d7c8a4dSAnna Zaks int test12(int *q) {
528d7c8a4dSAnna Zaks int *p = q;
538d7c8a4dSAnna Zaks idc(q);
548d7c8a4dSAnna Zaks return *p;
558d7c8a4dSAnna Zaks }
568d7c8a4dSAnna Zaks
test13(int * q)578d7c8a4dSAnna Zaks int test13(int *q) {
588d7c8a4dSAnna Zaks int *p = q;
598d7c8a4dSAnna Zaks idc(p);
608d7c8a4dSAnna Zaks return *p;
618d7c8a4dSAnna Zaks }
628d7c8a4dSAnna Zaks
test21(int * q,int * x)638d7c8a4dSAnna Zaks int test21(int *q, int *x) {
648d7c8a4dSAnna Zaks if (q)
658d7c8a4dSAnna Zaks ;
668d7c8a4dSAnna Zaks if (x)
678d7c8a4dSAnna Zaks ;
688d7c8a4dSAnna Zaks int *p = q;
698d7c8a4dSAnna Zaks return *p; // expected-warning{{Dereference of null pointer}}
708d7c8a4dSAnna Zaks }
718d7c8a4dSAnna Zaks
test22(int * q,int * x)728d7c8a4dSAnna Zaks int test22(int *q, int *x) {
738d7c8a4dSAnna Zaks idc(q);
748d7c8a4dSAnna Zaks if (x)
758d7c8a4dSAnna Zaks ;
768d7c8a4dSAnna Zaks int *p = q;
778d7c8a4dSAnna Zaks return *p;
788d7c8a4dSAnna Zaks }
798d7c8a4dSAnna Zaks
test23(int * q,int * x)808d7c8a4dSAnna Zaks int test23(int *q, int *x) {
818d7c8a4dSAnna Zaks idc(q);
828d7c8a4dSAnna Zaks if (x)
838d7c8a4dSAnna Zaks ;
848d7c8a4dSAnna Zaks int *p = q;
858d7c8a4dSAnna Zaks if (!p)
868d7c8a4dSAnna Zaks ;
878d7c8a4dSAnna Zaks return *p; // False negative
888d7c8a4dSAnna Zaks }
898d7c8a4dSAnna Zaks
use(char * p)908d7c8a4dSAnna Zaks void use(char *p) {
918d7c8a4dSAnna Zaks if (!p)
928d7c8a4dSAnna Zaks return;
938d7c8a4dSAnna Zaks p[0] = 'a';
948d7c8a4dSAnna Zaks }
958d7c8a4dSAnna Zaks
test24(char * buffer)968d7c8a4dSAnna Zaks void test24(char *buffer) {
978d7c8a4dSAnna Zaks use(buffer);
988d7c8a4dSAnna Zaks buffer[1] = 'b';
998d7c8a4dSAnna Zaks }
1006c0c47edSAnna Zaks
1016c0c47edSAnna Zaks // Ensure idc works on pointers with constant offset.
idcchar(const char * s2)1026c0c47edSAnna Zaks void idcchar(const char *s2) {
1036c0c47edSAnna Zaks if(s2)
1046c0c47edSAnna Zaks ;
1056c0c47edSAnna Zaks }
testConstantOffset(char * value)1066c0c47edSAnna Zaks void testConstantOffset(char *value) {
1076c0c47edSAnna Zaks char *cursor = value + 5;
1086c0c47edSAnna Zaks idcchar(cursor);
1096c0c47edSAnna Zaks if (*cursor) {
1106c0c47edSAnna Zaks cursor++;
1116c0c47edSAnna Zaks }
1126c0c47edSAnna Zaks }
1135673b656SAnna Zaks
1145673b656SAnna Zaks // Ensure idc works for integer zero values (ex: suppressed div by zero).
idcZero(int assume)1155673b656SAnna Zaks void idcZero(int assume) {
1165673b656SAnna Zaks if (assume)
1175673b656SAnna Zaks ;
1185673b656SAnna Zaks }
1195673b656SAnna Zaks
idcTriggerZeroValue(int m)1205673b656SAnna Zaks int idcTriggerZeroValue(int m) {
1215673b656SAnna Zaks idcZero(m);
1225673b656SAnna Zaks return 5/m; // no-warning
1235673b656SAnna Zaks }
1245673b656SAnna Zaks
idcTriggerZeroValueThroughCall(int i)1255673b656SAnna Zaks int idcTriggerZeroValueThroughCall(int i) {
1265673b656SAnna Zaks return 5/i; // no-warning
1275673b656SAnna Zaks }
idcTrackZeroValueThroughCall(int x)1285673b656SAnna Zaks void idcTrackZeroValueThroughCall(int x) {
1295673b656SAnna Zaks idcZero(x);
1305673b656SAnna Zaks idcTriggerZeroValueThroughCall(x);
1315673b656SAnna Zaks }
1325673b656SAnna Zaks
idcTriggerZeroThroughDoubleAssignemnt(int i)1335673b656SAnna Zaks int idcTriggerZeroThroughDoubleAssignemnt(int i) {
1345673b656SAnna Zaks return 5/i; // no-warning
1355673b656SAnna Zaks }
idcTrackZeroThroughDoubleAssignemnt(int x)1365673b656SAnna Zaks void idcTrackZeroThroughDoubleAssignemnt(int x) {
1375673b656SAnna Zaks idcZero(x);
1385673b656SAnna Zaks int y = x;
1395673b656SAnna Zaks int z = y;
1405673b656SAnna Zaks idcTriggerZeroValueThroughCall(z);
1415673b656SAnna Zaks }
14237de8888SArtem Dergachev
14337de8888SArtem Dergachev struct S {
14437de8888SArtem Dergachev int f1;
14537de8888SArtem Dergachev int f2;
14637de8888SArtem Dergachev };
14737de8888SArtem Dergachev
idcTrackZeroValueThroughUnaryPointerOperators(struct S * s)14837de8888SArtem Dergachev void idcTrackZeroValueThroughUnaryPointerOperators(struct S *s) {
14937de8888SArtem Dergachev idc(s);
15037de8888SArtem Dergachev *(&(s->f1)) = 7; // no-warning
15137de8888SArtem Dergachev }
15237de8888SArtem Dergachev
idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset1(struct S * s)15337de8888SArtem Dergachev void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset1(struct S *s) {
15437de8888SArtem Dergachev idc(s);
15537de8888SArtem Dergachev int *x = &(s->f2);
15637de8888SArtem Dergachev *x = 7; // no-warning
15737de8888SArtem Dergachev }
15837de8888SArtem Dergachev
idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset2(struct S * s)15937de8888SArtem Dergachev void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset2(struct S *s) {
16037de8888SArtem Dergachev idc(s);
16137de8888SArtem Dergachev int *x = &(s->f2) - 1;
162*95f9a68bSArtem Dergachev *x = 7; // no-warning
16337de8888SArtem Dergachev }
16437de8888SArtem Dergachev
idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S * s)16537de8888SArtem Dergachev void idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S *s) {
16637de8888SArtem Dergachev idc(s);
16737de8888SArtem Dergachev int *x = &(s->f1);
16837de8888SArtem Dergachev *x = 7; // no-warning
16937de8888SArtem Dergachev }
17037de8888SArtem Dergachev
idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignment(struct S * s)1718c800615SArtem Dergachev void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignment(struct S *s) {
1728c800615SArtem Dergachev idc(s);
1738c800615SArtem Dergachev int *x = &*&(s->f1);
1748c800615SArtem Dergachev *x = 7; // no-warning
1758c800615SArtem Dergachev }
1768c800615SArtem Dergachev
idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S * s)1778c800615SArtem Dergachev void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S *s) {
1788c800615SArtem Dergachev idc(s);
1798c800615SArtem Dergachev int *x = &*&((++s)->f1);
1808c800615SArtem Dergachev *x = 7; // no-warning
1818c800615SArtem Dergachev }
1828c800615SArtem Dergachev
18337de8888SArtem Dergachev
18437de8888SArtem Dergachev struct S2 {
18537de8888SArtem Dergachev int a[1];
18637de8888SArtem Dergachev };
18737de8888SArtem Dergachev
idcTrackZeroValueThroughUnaryPointerOperatorsWithArrayField(struct S2 * s)18837de8888SArtem Dergachev void idcTrackZeroValueThroughUnaryPointerOperatorsWithArrayField(struct S2 *s) {
18937de8888SArtem Dergachev idc(s);
19037de8888SArtem Dergachev *(&(s->a[0])) = 7; // no-warning
19137de8888SArtem Dergachev }
192fcad574cSArtem Dergachev
idcTrackConstraintThroughSymbolicRegion(int ** x)193fcad574cSArtem Dergachev void idcTrackConstraintThroughSymbolicRegion(int **x) {
194fcad574cSArtem Dergachev idc(*x);
195fcad574cSArtem Dergachev // FIXME: Should not warn.
196fcad574cSArtem Dergachev **x = 7; // expected-warning{{Dereference of null pointer}}
197fcad574cSArtem Dergachev }
198fcad574cSArtem Dergachev
idcTrackConstraintThroughSymbolicRegionAndParens(int ** x)199fee10106SArtem Dergachev void idcTrackConstraintThroughSymbolicRegionAndParens(int **x) {
200fee10106SArtem Dergachev idc(*x);
201fee10106SArtem Dergachev // FIXME: Should not warn.
202fee10106SArtem Dergachev *(*x) = 7; // expected-warning{{Dereference of null pointer}}
203fee10106SArtem Dergachev }
204fee10106SArtem Dergachev
idcPlainNull(int coin)205fcad574cSArtem Dergachev int *idcPlainNull(int coin) {
206fcad574cSArtem Dergachev if (coin)
207fcad574cSArtem Dergachev return 0;
208fcad574cSArtem Dergachev static int X;
209fcad574cSArtem Dergachev return &X;
210fcad574cSArtem Dergachev }
211fcad574cSArtem Dergachev
idcTrackZeroValueThroughSymbolicRegion(int coin,int ** x)212fcad574cSArtem Dergachev void idcTrackZeroValueThroughSymbolicRegion(int coin, int **x) {
213fcad574cSArtem Dergachev *x = idcPlainNull(coin);
214fcad574cSArtem Dergachev **x = 7; // no-warning
215fcad574cSArtem Dergachev }
216fee10106SArtem Dergachev
idcTrackZeroValueThroughSymbolicRegionAndParens(int coin,int ** x)217fee10106SArtem Dergachev void idcTrackZeroValueThroughSymbolicRegionAndParens(int coin, int **x) {
218fee10106SArtem Dergachev *x = idcPlainNull(coin);
219fee10106SArtem Dergachev *(*x) = 7; // no-warning
220fee10106SArtem Dergachev }
221fee10106SArtem Dergachev
222fee10106SArtem Dergachev struct WithInt {
223fee10106SArtem Dergachev int i;
224fee10106SArtem Dergachev };
225fee10106SArtem Dergachev
226fee10106SArtem Dergachev struct WithArray {
227fee10106SArtem Dergachev struct WithInt arr[1];
228fee10106SArtem Dergachev };
229fee10106SArtem Dergachev
idcPlainNullWithArray(int coin)230fee10106SArtem Dergachev struct WithArray *idcPlainNullWithArray(int coin) {
231fee10106SArtem Dergachev if (coin)
232fee10106SArtem Dergachev return 0;
233fee10106SArtem Dergachev static struct WithArray S;
234fee10106SArtem Dergachev return &S;
235fee10106SArtem Dergachev }
236fee10106SArtem Dergachev
idcTrackZeroValueThroughSymbolicRegionWithArray(int coin,struct WithArray ** s)237fee10106SArtem Dergachev void idcTrackZeroValueThroughSymbolicRegionWithArray(int coin, struct WithArray **s) {
238fee10106SArtem Dergachev *s = idcPlainNullWithArray(coin);
239fee10106SArtem Dergachev (*s)->arr[0].i = 1; // no-warning
240fee10106SArtem Dergachev // Same thing.
241fee10106SArtem Dergachev (*s)->arr->i = 1; // no-warning
242fee10106SArtem Dergachev }
243