forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			120 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
| // 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;
 | |
| }
 |