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; fooX5 void foo () { 6 reset(p - 1); 7 } resetX8 void reset(int *in) { 9 while (in != p) // Loop must be entered. 10 zero = 1; 11 } 12 }; 13 test(int * in)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 23 class Base {}; 24 class Derived : public Base {}; 25 checkPolymorphicUse()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 checkBitCasts()33void checkBitCasts() { 34 long l; 35 char *p = (char*)&l; 36 p = p+2; 37 } 38 checkBasicarithmetic(int i)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 checkArithOnSymbolic(int * p)55void 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 arrayInStruct()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 checkNew()77void checkNew() { 78 int *p = new int; 79 p[1] = 1; // expected-warning{{}} 80 } 81 InitState(int * state)82void InitState(int* state) { 83 state[1] = 1; // expected-warning{{}} 84 } 85 getArray(int size)86int* getArray(int size) { 87 if (size == 0) 88 return new int; 89 return new int[5]; 90 } 91 checkConditionalArray()92void checkConditionalArray() { 93 int* maybeArray = getArray(0); 94 InitState(maybeArray); 95 } 96 checkMultiDimansionalArray()97void checkMultiDimansionalArray() { 98 int a[5][5]; 99 *(*(a+1)+2) = 2; 100 } 101 ptrSubtractionNoCrash(char * Begin,char * End)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 ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x,char * p)110bool ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x, char *p) { 111 __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1; 112 return y == x; 113 } 114 115 // Bug 34374 integerAsPtrSubtractionNoCrash(char * p,__UINTPTR_TYPE__ m)116bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) { 117 auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1); 118 return n == m; 119 } 120