File: ptr-arith.cpp

package info (click to toggle)
llvm-toolchain-15 1%3A15.0.6-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,554,644 kB
  • sloc: cpp: 5,922,452; ansic: 1,012,136; asm: 674,362; python: 191,568; objc: 73,855; f90: 42,327; lisp: 31,913; pascal: 11,973; javascript: 10,144; sh: 9,421; perl: 7,447; ml: 5,527; awk: 3,523; makefile: 2,520; xml: 885; cs: 573; fortran: 567
file content (143 lines) | stat: -rw-r--r-- 2,884 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14 -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s

template <typename T> void clang_analyzer_dump(T);

struct X {
  int *p;
  int zero;
  void foo () {
    reset(p - 1);
  }
  void reset(int *in) {
    while (in != p) // Loop must be entered.
      zero = 1;
  }
};

int test (int *in) {
  X littleX;
  littleX.zero = 0;
  littleX.p = in;
  littleX.foo();
  return 5/littleX.zero; // no-warning
}


class Base {};
class Derived : public Base {};

void checkPolymorphicUse() {
  Derived d[10];

  Base *p = d;
  ++p; // expected-warning{{Pointer arithmetic on a pointer to base class is dangerous}}
}

void checkBitCasts() {
  long l;
  char *p = (char*)&l;
  p = p+2;
}

void checkBasicarithmetic(int i) {
  int t[10];
  int *p = t;
  ++p;
  int a = 5;
  p = &a;
  ++p; // expected-warning{{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous}}
  p = p + 2; // expected-warning{{}}
  p = 2 + p; // expected-warning{{}}
  p += 2; // expected-warning{{}}
  a += p[2]; // expected-warning{{}}
  p = i*0 + p;
  p = p + i*0;
  p += i*0;
}

void checkArithOnSymbolic(int*p) {
  ++p;
  p = p + 2;
  p = 2 + p;
  p += 2;
  (void)p[2];
}

struct S {
  int t[10];
};

void arrayInStruct() {
  S s;
  int * p = s.t;
  ++p;
  S *sp = new S;
  p = sp->t;
  ++p;
  delete sp;
}

void checkNew() {
  int *p = new int;
  p[1] = 1; // expected-warning{{}}
}

void InitState(int* state) {
    state[1] = 1; // expected-warning{{}}
}

int* getArray(int size) {
    if (size == 0)
      return new int;
    return new int[5];
}

void checkConditionalArray() {
    int* maybeArray = getArray(0);
    InitState(maybeArray);
}

void checkMultiDimansionalArray() {
  int a[5][5];
   *(*(a+1)+2) = 2;
}

unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
  auto N = End - Begin;
  if (Begin)
    return 0;
  return N;
}

// Bug 34309
bool ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x, char *p) {
  __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
  return y == x;
}

// Bug 34374
bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
  auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1);
  return n == m;
}

namespace Bug_55934 {
struct header {
  unsigned a : 1;
  unsigned b : 1;
};
struct parse_t {
  unsigned bits0 : 1;
  unsigned bits2 : 2; // <-- header
  unsigned bits4 : 4;
};
int parse(parse_t *p) {
  unsigned copy = p->bits2;
  clang_analyzer_dump(copy);
  // expected-warning@-1 {{reg_$1<unsigned int SymRegion{reg_$0<struct Bug_55934::parse_t * p>}.bits2>}}
  header *bits = (header *)&copy;
  clang_analyzer_dump(bits->b);
  // expected-warning@-1 {{derived_$2{reg_$1<unsigned int SymRegion{reg_$0<struct Bug_55934::parse_t * p>}.bits2>,Element{copy,0 S64b,struct Bug_55934::header}.b}}}
  return bits->b; // no-warning
}
} // namespace Bug_55934