brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · dec1ed1 Raw
278 lines · cpp
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.PointerArithm3 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.PointerArithm7 8template <typename T> void clang_analyzer_dump(T);9 10struct 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 22int test (int *in) {23  X littleX;24  littleX.zero = 0;25  littleX.p = in;26  littleX.foo();27  return 5/littleX.zero; // no-warning28}29 30 31class Base {};32class Derived : public Base {};33 34void 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 41void checkBitCasts() {42  long l;43  char *p = (char*)&l;44  p = p+2;45}46 47void 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 63void checkArithOnSymbolic(int*p) {64  ++p;65  p = p + 2;66  p = 2 + p;67  p += 2;68  (void)p[2];69}70 71struct S {72  int t[10];73};74 75void 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 85void checkNew() {86  int *p = new int;87  p[1] = 1; // expected-warning{{}}88}89 90void InitState(int* state) {91    state[1] = 1; // expected-warning{{}}92}93 94int* getArray(int size) {95    if (size == 0)96      return new int;97    return new int[5];98}99 100void checkConditionalArray() {101    int* maybeArray = getArray(0);102    InitState(maybeArray);103}104 105void checkMultiDimansionalArray() {106  int a[5][5];107   *(*(a+1)+2) = 2;108}109 110unsigned ptrSubtractionNoCrash(char *Begin, char *End) {111  auto N = End - Begin;112  if (Begin)113    return 0;114  return N;115}116 117// Bug 34309118bool ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x, char *p) {119  __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;120  return y == x;121}122 123// Bug 34374124bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {125  auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1);126  return n == m;127}128 129namespace Bug_55934 {130struct header {131  unsigned a : 1;132  unsigned b : 1;133};134struct parse_t {135  unsigned bits0 : 1;136  unsigned bits2 : 2; // <-- header137  unsigned bits4 : 4;138};139int 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 *)&copy;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-warning147}148} // namespace Bug_55934149 150void 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 165unsigned long ptr_arithmetic(void *p) {166  return __builtin_bit_cast(unsigned long, p) + 1; // no-crash167}168 169struct AllocOpaqueFlag {};170 171void *operator new(unsigned long, void *ptr) noexcept { return ptr; }172void *operator new(unsigned long, void *ptr, AllocOpaqueFlag const &) noexcept;173 174void *operator new[](unsigned long, void *ptr) noexcept { return ptr; }175void *operator new[](unsigned long, void *ptr,176                     AllocOpaqueFlag const &) noexcept;177 178struct Buffer {179  char buf[100];180  int padding;181};182 183void checkPlacementNewArryInObject() {184  Buffer buffer;185  int *array = new (&buffer) int[10];186  ++array; // no warning187  (void)*array;188}189 190void checkPlacementNewArrayInObjectOpaque() {191  Buffer buffer;192  int *array = new (&buffer, AllocOpaqueFlag{}) int[10];193  ++array; // no warning194  (void)*array;195}196 197void checkPlacementNewArrayInArray() {198  char buffer[100];199  int *array = new (buffer) int[10];200  ++array; // no warning201  (void)*array;202}203 204void checkPlacementNewArrayInArrayOpaque() {205  char buffer[100];206  int *array = new (buffer, AllocOpaqueFlag{}) int;207  ++array; // no warning208  (void)*array;209}210 211void checkPlacementNewObjectInObject() {212  Buffer buffer;213  int *array = new (&buffer) int;214  ++array; // expected-warning{{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous}}215  (void)*array;216}217 218void checkPlacementNewObjectInObjectOpaque() {219  Buffer buffer;220  int *array = new (&buffer, AllocOpaqueFlag{}) int;221  ++array; // no warning (allocator is opaque)222  (void)*array;223}224 225void checkPlacementNewObjectInArray() {226  char buffer[sizeof(int)];227  int *array = new (buffer) int;228  ++array; // no warning (FN)229  (void)*array;230}231 232void checkPlacementNewObjectInArrayOpaque() {233  char buffer[sizeof(int)];234  int *array = new (buffer, AllocOpaqueFlag{}) int;235  ++array; // no warning (FN)236  (void)*array;237}238 239void checkPlacementNewSlices() {240  const int N = 10;241  char buffer[sizeof(int) * N] = {0};242  int *start = new (buffer) int{0};243  for (int i = 1; i < N; i++) {244    auto *ptr = new int(buffer[i * sizeof(int)]);245    *ptr = i;246  }247  ++start; // no warning248  (void *)start;249}250 251class BumpAlloc {252  char *buffer;253  char *offset;254 255public:256  BumpAlloc(int n) : buffer(new char[n]), offset{buffer} {}257  ~BumpAlloc() { delete[] buffer; }258 259  void *alloc(unsigned long size) {260    auto *ptr = offset;261    offset += size;262    return ptr;263  }264};265 266void *operator new(unsigned long size, BumpAlloc &ba) { return ba.alloc(size); }267 268void checkPlacementSlab() {269  BumpAlloc bump{10};270 271  int *ptr = new (bump) int{0};272  ++ptr; // no warning273  (void)*ptr;274 275  BumpAlloc *why = &bump;276  ++why; // expected-warning {{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous [alpha.core.PointerArithm]}}277}278