Clang Project

clang_source_code/test/Analysis/ptr-arith.cpp
1// RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14 -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
2struct X {
3  int *p;
4  int zero;
5  void foo () {
6    reset(p - 1);
7  }
8  void reset(int *in) {
9    while (in != p) // Loop must be entered.
10      zero = 1;
11  }
12};
13
14int 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
23class Base {};
24class Derived : public Base {};
25
26void 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
33void checkBitCasts() {
34  long l;
35  char *p = (char*)&l;
36  p = p+2;
37}
38
39void 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
55void checkArithOnSymbolic(int*p) {
56  ++p;
57  p = p + 2;
58  p = 2 + p;
59  p += 2;
60  (void)p[2];
61}
62
63struct S {
64  int t[10];
65};
66
67void 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
77void checkNew() {
78  int *p = new int;
79  p[1] = 1; // expected-warning{{}}
80}
81
82void InitState(int* state) {
83    state[1] = 1; // expected-warning{{}}
84}
85
86int* getArray(int size) {
87    if (size == 0)
88      return new int;
89    return new int[5];
90}
91
92void checkConditionalArray() {
93    int* maybeArray = getArray(0);
94    InitState(maybeArray);
95}
96
97void checkMultiDimansionalArray() {
98  int a[5][5];
99   *(*(a+1)+2) = 2;
100}
101
102unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
103  auto N = End - Begin;
104  if (Begin)
105    return 0;
106  return N;
107}
108
109// Bug 34309
110bool ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x, char *p) {
111  __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
112  return y == x;
113}
114
115// Bug 34374
116bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
117  auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1);
118  return n == m;
119}
120