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