xref: /aosp_15_r20/external/clang/test/Analysis/ptr-arith.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -Wno-unused-value -std=c++14 -analyze -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
2*67e74705SXin Li struct X {
3*67e74705SXin Li   int *p;
4*67e74705SXin Li   int zero;
fooX5*67e74705SXin Li   void foo () {
6*67e74705SXin Li     reset(p - 1);
7*67e74705SXin Li   }
resetX8*67e74705SXin Li   void reset(int *in) {
9*67e74705SXin Li     while (in != p) // Loop must be entered.
10*67e74705SXin Li       zero = 1;
11*67e74705SXin Li   }
12*67e74705SXin Li };
13*67e74705SXin Li 
test(int * in)14*67e74705SXin Li int test (int *in) {
15*67e74705SXin Li   X littleX;
16*67e74705SXin Li   littleX.zero = 0;
17*67e74705SXin Li   littleX.p = in;
18*67e74705SXin Li   littleX.foo();
19*67e74705SXin Li   return 5/littleX.zero; // no-warning
20*67e74705SXin Li }
21*67e74705SXin Li 
22*67e74705SXin Li 
23*67e74705SXin Li class Base {};
24*67e74705SXin Li class Derived : public Base {};
25*67e74705SXin Li 
checkPolymorphicUse()26*67e74705SXin Li void checkPolymorphicUse() {
27*67e74705SXin Li   Derived d[10];
28*67e74705SXin Li 
29*67e74705SXin Li   Base *p = d;
30*67e74705SXin Li   ++p; // expected-warning{{Pointer arithmetic on a pointer to base class is dangerous}}
31*67e74705SXin Li }
32*67e74705SXin Li 
checkBitCasts()33*67e74705SXin Li void checkBitCasts() {
34*67e74705SXin Li   long l;
35*67e74705SXin Li   char *p = (char*)&l;
36*67e74705SXin Li   p = p+2;
37*67e74705SXin Li }
38*67e74705SXin Li 
checkBasicarithmetic(int i)39*67e74705SXin Li void checkBasicarithmetic(int i) {
40*67e74705SXin Li   int t[10];
41*67e74705SXin Li   int *p = t;
42*67e74705SXin Li   ++p;
43*67e74705SXin Li   int a = 5;
44*67e74705SXin Li   p = &a;
45*67e74705SXin Li   ++p; // expected-warning{{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous}}
46*67e74705SXin Li   p = p + 2; // expected-warning{{}}
47*67e74705SXin Li   p = 2 + p; // expected-warning{{}}
48*67e74705SXin Li   p += 2; // expected-warning{{}}
49*67e74705SXin Li   a += p[2]; // expected-warning{{}}
50*67e74705SXin Li   p = i*0 + p;
51*67e74705SXin Li   p = p + i*0;
52*67e74705SXin Li   p += i*0;
53*67e74705SXin Li }
54*67e74705SXin Li 
checkArithOnSymbolic(int * p)55*67e74705SXin Li void checkArithOnSymbolic(int*p) {
56*67e74705SXin Li   ++p;
57*67e74705SXin Li   p = p + 2;
58*67e74705SXin Li   p = 2 + p;
59*67e74705SXin Li   p += 2;
60*67e74705SXin Li   (void)p[2];
61*67e74705SXin Li }
62*67e74705SXin Li 
63*67e74705SXin Li struct S {
64*67e74705SXin Li   int t[10];
65*67e74705SXin Li };
66*67e74705SXin Li 
arrayInStruct()67*67e74705SXin Li void arrayInStruct() {
68*67e74705SXin Li   S s;
69*67e74705SXin Li   int * p = s.t;
70*67e74705SXin Li   ++p;
71*67e74705SXin Li   S *sp = new S;
72*67e74705SXin Li   p = sp->t;
73*67e74705SXin Li   ++p;
74*67e74705SXin Li   delete sp;
75*67e74705SXin Li }
76*67e74705SXin Li 
checkNew()77*67e74705SXin Li void checkNew() {
78*67e74705SXin Li   int *p = new int;
79*67e74705SXin Li   p[1] = 1; // expected-warning{{}}
80*67e74705SXin Li }
81*67e74705SXin Li 
InitState(int * state)82*67e74705SXin Li void InitState(int* state) {
83*67e74705SXin Li     state[1] = 1; // expected-warning{{}}
84*67e74705SXin Li }
85*67e74705SXin Li 
getArray(int size)86*67e74705SXin Li int* getArray(int size) {
87*67e74705SXin Li     if (size == 0)
88*67e74705SXin Li       return new int;
89*67e74705SXin Li     return new int[5];
90*67e74705SXin Li }
91*67e74705SXin Li 
checkConditionalArray()92*67e74705SXin Li void checkConditionalArray() {
93*67e74705SXin Li     int* maybeArray = getArray(0);
94*67e74705SXin Li     InitState(maybeArray);
95*67e74705SXin Li }
96*67e74705SXin Li 
checkMultiDimansionalArray()97*67e74705SXin Li void checkMultiDimansionalArray() {
98*67e74705SXin Li   int a[5][5];
99*67e74705SXin Li    *(*(a+1)+2) = 2;
100*67e74705SXin Li }
101