forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			203 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			203 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
 | |
| 
 | |
| // Make sure that the C cases still work fine, even when compiled as C++.
 | |
| #include "padding_c.c"
 | |
| 
 | |
| struct BigCharArray2 { // no-warning
 | |
|   char c[129];
 | |
| };
 | |
| 
 | |
| // xxxexpected-warning@+1{{Excessive padding in 'struct LowAlignmentBase'}}
 | |
| struct LowAlignmentBase : public BigCharArray2 {
 | |
|   int i;
 | |
|   char c;
 | |
| };
 | |
| 
 | |
| struct CorrectLowAlignmentBase : public BigCharArray2 { // no-warning
 | |
|   char c;
 | |
|   int i;
 | |
| };
 | |
| 
 | |
| // xxxexpected-warning@+1{{Excessive padding in 'struct LowAlignmentBase2'}}
 | |
| struct LowAlignmentBase2 : public BigCharArray2 {
 | |
|   char c1;
 | |
|   int i;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| class PaddedA { // expected-warning{{Excessive padding in 'class PaddedA'}}
 | |
|   char c1;
 | |
|   int i;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| class VirtualPaddedA : public PaddedA { // no-warning
 | |
|   virtual void foo() {}
 | |
| };
 | |
| 
 | |
| class VirtualIntSandwich { // expected-warning{{Excessive padding in 'class VirtualIntSandwich'}}
 | |
|   virtual void foo() {}
 | |
|   char c1;
 | |
|   int i;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| // constructed so as not to have tail padding
 | |
| class InnerPaddedB { // expected-warning{{Excessive padding in 'class InnerPaddedB'}}
 | |
|   char c1;
 | |
|   int i1;
 | |
|   char c2;
 | |
|   int i2;
 | |
| };
 | |
| 
 | |
| class TailPaddedB { // expected-warning{{Excessive padding in 'class TailPaddedB'}}
 | |
|   char c1;
 | |
|   int i1;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| class SI : public PaddedA { // no-warning
 | |
|   char c;
 | |
| };
 | |
| 
 | |
| class SI2 : public PaddedA { // xxxexpected-warning{{Excessive padding in 'class SI2'}}
 | |
|   char c10;
 | |
|   int i10;
 | |
|   char c11;
 | |
| };
 | |
| 
 | |
| class VirtualSI : virtual public PaddedA { // no-warning
 | |
|   char c;
 | |
| };
 | |
| 
 | |
| // currently not checked for
 | |
| class VirtualSI2 : virtual public PaddedA { // no-warning
 | |
|   char c10;
 | |
|   int i10;
 | |
|   char c11;
 | |
| };
 | |
| 
 | |
| class VtblSI : public PaddedA { // no-warning
 | |
|   virtual void foo() {}
 | |
|   char c;
 | |
| };
 | |
| 
 | |
| class VtblSI2 : public PaddedA { // xxxexpected-warning{{Excessive padding in 'class VtblSI2'}}
 | |
|   virtual void foo() {}
 | |
|   char c10;
 | |
|   int i10;
 | |
|   char c11;
 | |
| };
 | |
| 
 | |
| class VtblSI3 : public VirtualPaddedA { // xxxexpected-warning{{Excessive padding in 'class VtblSI3'}}
 | |
|   char c10;
 | |
|   int i10;
 | |
|   char c11;
 | |
| };
 | |
| 
 | |
| class MI : public PaddedA, public InnerPaddedB { // no-warning
 | |
|   char c;
 | |
| };
 | |
| 
 | |
| class MI2 : public PaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class MI2'}}
 | |
|   char c10;
 | |
|   int i10;
 | |
|   char c11;
 | |
| };
 | |
| 
 | |
| class VtblMI : public PaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class VtblMI'}}
 | |
|   virtual void foo() {}
 | |
|   char c10;
 | |
|   int i10;
 | |
|   char c11;
 | |
| };
 | |
| 
 | |
| class VtblMI2 : public VirtualPaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class VtblMI2'}}
 | |
|   char c10;
 | |
|   int i10;
 | |
|   char c11;
 | |
| };
 | |
| 
 | |
| class Empty {}; // no-warning
 | |
| 
 | |
| class LotsOfSpace { // expected-warning{{Excessive padding in 'class LotsOfSpace'}}
 | |
|   Empty e1;
 | |
|   int i;
 | |
|   Empty e2;
 | |
| };
 | |
| 
 | |
| class EBO1 : public Empty { // xxxexpected-warning{{Excessive padding in 'class EBO1'}}
 | |
|   char c1;
 | |
|   int i;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| class EBO2 : public Empty { // xxxexpected-warning{{Excessive padding in 'class EBO2'}}
 | |
|   Empty c1;
 | |
|   int i;
 | |
|   Empty c2;
 | |
| };
 | |
| 
 | |
| template <typename T>
 | |
| class TemplateSandwich { // expected-warning{{Excessive padding in 'class TemplateSandwich<int>' instantiated here}}
 | |
|   char c1;
 | |
|   T t;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| template <typename T>
 | |
| class TemplateSandwich<T *> { // expected-warning{{Excessive padding in 'class TemplateSandwich<void *>' instantiated here}}
 | |
|   char c1;
 | |
|   T *t;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| template <>
 | |
| class TemplateSandwich<long long> { // expected-warning{{Excessive padding in 'class TemplateSandwich<long long>' (}}
 | |
|   char c1;
 | |
|   long long t;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| class Holder1 { // no-warning
 | |
|   TemplateSandwich<int> t1;
 | |
|   TemplateSandwich<char> t2;
 | |
|   TemplateSandwich<void *> t3;
 | |
| };
 | |
| 
 | |
| typedef struct TypedefSandwich2 { // expected-warning{{Excessive padding in 'struct TypedefSandwich2'}}
 | |
|   char c1;
 | |
|   typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich2::NestedTypedef'}}
 | |
|     char c1;
 | |
|     int i;
 | |
|     char c2;
 | |
|   } NestedTypedef;
 | |
|   NestedTypedef t;
 | |
|   char c2;
 | |
| } TypedefSandwich2;
 | |
| 
 | |
| template <typename T>
 | |
| struct Foo {
 | |
|   // expected-warning@+1{{Excessive padding in 'struct Foo<int>::Nested'}}
 | |
|   struct Nested {
 | |
|     char c1;
 | |
|     T t;
 | |
|     char c2;
 | |
|   };
 | |
| };
 | |
| 
 | |
| struct Holder { // no-warning
 | |
|   Foo<int>::Nested t1;
 | |
|   Foo<char>::Nested t2;
 | |
| };
 | |
| 
 | |
| struct GlobalsForLambda { // no-warning
 | |
|   int i;
 | |
|   char c1;
 | |
|   char c2;
 | |
| } G;
 | |
| 
 | |
| // expected-warning@+1{{Excessive padding in 'class (lambda}}
 | |
| auto lambda1 = [ c1 = G.c1, i = G.i, c2 = G.c2 ]{};
 | |
| auto lambda2 = [ i = G.i, c1 = G.c1, c2 = G.c2 ]{}; // no-warning
 |