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; |
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 | |
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 | |
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 | |
33 | void checkBitCasts() { |
34 | long l; |
35 | char *p = (char*)&l; |
36 | p = p+2; |
37 | } |
38 | |
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 | |
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 | |
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 | |
77 | void checkNew() { |
78 | int *p = new int; |
79 | p[1] = 1; // expected-warning{{}} |
80 | } |
81 | |
82 | void InitState(int* state) { |
83 | state[1] = 1; // expected-warning{{}} |
84 | } |
85 | |
86 | int* getArray(int size) { |
87 | if (size == 0) |
88 | return new int; |
89 | return new int[5]; |
90 | } |
91 | |
92 | void checkConditionalArray() { |
93 | int* maybeArray = getArray(0); |
94 | InitState(maybeArray); |
95 | } |
96 | |
97 | void checkMultiDimansionalArray() { |
98 | int a[5][5]; |
99 | *(*(a+1)+2) = 2; |
100 | } |
101 | |
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 |
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 |
116 | bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) { |
117 | auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1); |
118 | return n == m; |
119 | } |
120 | |