| // RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14 -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; |
| } |
| |
| 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; |
| } |