1 // RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14 -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s 2 3 template <typename T> void clang_analyzer_dump(T); 4 5 struct X { 6 int *p; 7 int zero; 8 void foo () { 9 reset(p - 1); 10 } 11 void reset(int *in) { 12 while (in != p) // Loop must be entered. 13 zero = 1; 14 } 15 }; 16 17 int test (int *in) { 18 X littleX; 19 littleX.zero = 0; 20 littleX.p = in; 21 littleX.foo(); 22 return 5/littleX.zero; // no-warning 23 } 24 25 26 class Base {}; 27 class Derived : public Base {}; 28 29 void checkPolymorphicUse() { 30 Derived d[10]; 31 32 Base *p = d; 33 ++p; // expected-warning{{Pointer arithmetic on a pointer to base class is dangerous}} 34 } 35 36 void checkBitCasts() { 37 long l; 38 char *p = (char*)&l; 39 p = p+2; 40 } 41 42 void checkBasicarithmetic(int i) { 43 int t[10]; 44 int *p = t; 45 ++p; 46 int a = 5; 47 p = &a; 48 ++p; // expected-warning{{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous}} 49 p = p + 2; // expected-warning{{}} 50 p = 2 + p; // expected-warning{{}} 51 p += 2; // expected-warning{{}} 52 a += p[2]; // expected-warning{{}} 53 p = i*0 + p; 54 p = p + i*0; 55 p += i*0; 56 } 57 58 void checkArithOnSymbolic(int*p) { 59 ++p; 60 p = p + 2; 61 p = 2 + p; 62 p += 2; 63 (void)p[2]; 64 } 65 66 struct S { 67 int t[10]; 68 }; 69 70 void arrayInStruct() { 71 S s; 72 int * p = s.t; 73 ++p; 74 S *sp = new S; 75 p = sp->t; 76 ++p; 77 delete sp; 78 } 79 80 void checkNew() { 81 int *p = new int; 82 p[1] = 1; // expected-warning{{}} 83 } 84 85 void InitState(int* state) { 86 state[1] = 1; // expected-warning{{}} 87 } 88 89 int* getArray(int size) { 90 if (size == 0) 91 return new int; 92 return new int[5]; 93 } 94 95 void checkConditionalArray() { 96 int* maybeArray = getArray(0); 97 InitState(maybeArray); 98 } 99 100 void checkMultiDimansionalArray() { 101 int a[5][5]; 102 *(*(a+1)+2) = 2; 103 } 104 105 unsigned ptrSubtractionNoCrash(char *Begin, char *End) { 106 auto N = End - Begin; 107 if (Begin) 108 return 0; 109 return N; 110 } 111 112 // Bug 34309 113 bool ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x, char *p) { 114 __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1; 115 return y == x; 116 } 117 118 // Bug 34374 119 bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) { 120 auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1); 121 return n == m; 122 } 123 124 namespace Bug_55934 { 125 struct header { 126 unsigned a : 1; 127 unsigned b : 1; 128 }; 129 struct parse_t { 130 unsigned bits0 : 1; 131 unsigned bits2 : 2; // <-- header 132 unsigned bits4 : 4; 133 }; 134 int parse(parse_t *p) { 135 unsigned copy = p->bits2; 136 clang_analyzer_dump(copy); 137 // expected-warning@-1 {{reg_$1<unsigned int SymRegion{reg_$0<struct Bug_55934::parse_t * p>}.bits2>}} 138 header *bits = (header *)© 139 clang_analyzer_dump(bits->b); 140 // 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}}} 141 return bits->b; // no-warning 142 } 143 } // namespace Bug_55934 144