1 // RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14 -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
2 struct X {
3   int *p;
4   int zero;
fooX5   void foo () {
6     reset(p - 1);
7   }
resetX8   void reset(int *in) {
9     while (in != p) // Loop must be entered.
10       zero = 1;
11   }
12 };
13 
test(int * in)14 int test (int *in) {
15   X littleX;
16   littleX.zero = 0;
17   littleX.p = in;
18   littleX.foo();
19   return 5/littleX.zero; // no-warning
20 }
21 
22 
23 class Base {};
24 class Derived : public Base {};
25 
checkPolymorphicUse()26 void checkPolymorphicUse() {
27   Derived d[10];
28 
29   Base *p = d;
30   ++p; // expected-warning{{Pointer arithmetic on a pointer to base class is dangerous}}
31 }
32 
checkBitCasts()33 void checkBitCasts() {
34   long l;
35   char *p = (char*)&l;
36   p = p+2;
37 }
38 
checkBasicarithmetic(int i)39 void checkBasicarithmetic(int i) {
40   int t[10];
41   int *p = t;
42   ++p;
43   int a = 5;
44   p = &a;
45   ++p; // expected-warning{{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous}}
46   p = p + 2; // expected-warning{{}}
47   p = 2 + p; // expected-warning{{}}
48   p += 2; // expected-warning{{}}
49   a += p[2]; // expected-warning{{}}
50   p = i*0 + p;
51   p = p + i*0;
52   p += i*0;
53 }
54 
checkArithOnSymbolic(int * p)55 void checkArithOnSymbolic(int*p) {
56   ++p;
57   p = p + 2;
58   p = 2 + p;
59   p += 2;
60   (void)p[2];
61 }
62 
63 struct S {
64   int t[10];
65 };
66 
arrayInStruct()67 void arrayInStruct() {
68   S s;
69   int * p = s.t;
70   ++p;
71   S *sp = new S;
72   p = sp->t;
73   ++p;
74   delete sp;
75 }
76 
checkNew()77 void checkNew() {
78   int *p = new int;
79   p[1] = 1; // expected-warning{{}}
80 }
81 
InitState(int * state)82 void InitState(int* state) {
83     state[1] = 1; // expected-warning{{}}
84 }
85 
getArray(int size)86 int* getArray(int size) {
87     if (size == 0)
88       return new int;
89     return new int[5];
90 }
91 
checkConditionalArray()92 void checkConditionalArray() {
93     int* maybeArray = getArray(0);
94     InitState(maybeArray);
95 }
96 
checkMultiDimansionalArray()97 void checkMultiDimansionalArray() {
98   int a[5][5];
99    *(*(a+1)+2) = 2;
100 }
101 
ptrSubtractionNoCrash(char * Begin,char * End)102 unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
103   auto N = End - Begin;
104   if (Begin)
105     return 0;
106   return N;
107 }
108 
109 // Bug 34309
ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x,char * p)110 bool ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x, char *p) {
111   __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
112   return y == x;
113 }
114 
115 // Bug 34374
integerAsPtrSubtractionNoCrash(char * p,__UINTPTR_TYPE__ m)116 bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
117   auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1);
118   return n == m;
119 }
120