forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			82 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.CastToStruct,core -verify %s
 | |
| 
 | |
| struct AB {
 | |
|   int A;
 | |
|   int B;
 | |
| };
 | |
| 
 | |
| struct ABC {
 | |
|   int A;
 | |
|   int B;
 | |
|   int C;
 | |
| };
 | |
| 
 | |
| struct Base {
 | |
|   Base() : A(0), B(0) {}
 | |
|   virtual ~Base() {}
 | |
| 
 | |
|   int A;
 | |
|   int B;
 | |
| };
 | |
| 
 | |
| struct Derived : public Base {
 | |
|   Derived() : Base(), C(0) {}
 | |
|   int C;
 | |
| };
 | |
| 
 | |
| void structToStruct(struct AB *P) {
 | |
|   struct AB Ab;
 | |
|   struct ABC *Abc;
 | |
|   Abc = (struct ABC *)&Ab; // expected-warning {{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}}
 | |
|   Abc = (struct ABC *)P; // No warning; It is not known what data P points at.
 | |
|   Abc = (struct ABC *)&*P;
 | |
| 
 | |
|   // Don't warn when the cast is not widening.
 | |
|   P = (struct AB *)&Ab; // struct AB * => struct AB *
 | |
|   struct ABC Abc2;
 | |
|   P = (struct AB *)&Abc2; // struct ABC * => struct AB *
 | |
| 
 | |
|   // True negatives when casting from Base to Derived.
 | |
|   Derived D1, *D2;
 | |
|   Base &B1 = D1;
 | |
|   D2 = (Derived *)&B1;
 | |
|   D2 = dynamic_cast<Derived *>(&B1);
 | |
|   D2 = static_cast<Derived *>(&B1);
 | |
| 
 | |
|   // True positives when casting from Base to Derived.
 | |
|   Base B2;
 | |
|   D2 = (Derived *)&B2;// expected-warning {{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}}
 | |
|   D2 = dynamic_cast<Derived *>(&B2);// expected-warning {{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}}
 | |
|   D2 = static_cast<Derived *>(&B2);// expected-warning {{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}}
 | |
| 
 | |
|   // False negatives, cast from Base to Derived. With path sensitive analysis
 | |
|   // these false negatives could be fixed.
 | |
|   Base *B3 = &B2;
 | |
|   D2 = (Derived *)B3;
 | |
|   D2 = dynamic_cast<Derived *>(B3);
 | |
|   D2 = static_cast<Derived *>(B3);
 | |
| }
 | |
| 
 | |
| void intToStruct(int *P) {
 | |
|   struct ABC *Abc;
 | |
|   Abc = (struct ABC *)P; // expected-warning {{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}}
 | |
| 
 | |
|   // Cast from void *.
 | |
|   void *VP = P;
 | |
|   Abc = (struct ABC *)VP;
 | |
| }
 | |
| 
 | |
| // https://llvm.org/bugs/show_bug.cgi?id=31173
 | |
| void dontCrash1(struct AB X) {
 | |
|   struct UndefS *S = (struct UndefS *)&X;
 | |
| }
 | |
| 
 | |
| struct S;
 | |
| struct T {
 | |
|   struct S *P;
 | |
| };
 | |
| extern struct S Var1, Var2;
 | |
| void dontCrash2() {
 | |
|   ((struct T *) &Var1)->P = &Var2;
 | |
| }
 |