This patch is intended to improve pointer arithmetic checker. From now on it only warns when the pointer arithmetic is likely to cause an error. For example when the pointer points to a single object, or an array of derived types. Differential Revision: http://reviews.llvm.org/D14203 llvm-svn: 261632
101 lines
1.7 KiB
C++
101 lines
1.7 KiB
C++
// RUN: %clang_cc1 -Wno-unused-value -std=c++14 -analyze -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
|
|
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;
|
|
}
|