forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			249 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			249 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
| // RUN: %clang_analyze_cc1 -verify %s \
 | |
| // RUN:   -analyzer-checker=optin.performance \
 | |
| // RUN:   -analyzer-config optin.performance.Padding:AllowedPad=2
 | |
| 
 | |
| // RUN: not %clang_analyze_cc1 -verify %s \
 | |
| // RUN:   -analyzer-checker=core \
 | |
| // RUN:   -analyzer-checker=optin.performance.Padding \
 | |
| // RUN:   -analyzer-config optin.performance.Padding:AllowedPad=-10 \
 | |
| // RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-PAD-NEGATIVE-VALUE
 | |
| 
 | |
| // CHECK-PAD-NEGATIVE-VALUE: (frontend): invalid input for checker option
 | |
| // CHECK-PAD-NEGATIVE-VALUE-SAME: 'optin.performance.Padding:AllowedPad', that
 | |
| // CHECK-PAD-NEGATIVE-VALUE-SAME: expects a non-negative value
 | |
| 
 | |
| #if __has_include(<stdalign.h>)
 | |
| #include <stdalign.h>
 | |
| #endif
 | |
| 
 | |
| #if __has_include(<stdalign.h>) || defined(__cplusplus)
 | |
| // expected-warning@+1{{Excessive padding in 'struct FieldAttrAlign' (6 padding}}
 | |
| struct FieldAttrAlign {
 | |
|   char c1;
 | |
|   alignas(4) int i;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| // expected-warning@+1{{Excessive padding in 'struct FieldAttrOverAlign' (10 padding}}
 | |
| struct FieldAttrOverAlign {
 | |
|   char c1;
 | |
|   alignas(8) int i;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| #endif // __has_include(<stdalign.h>) || defined(__cplusplus)
 | |
| 
 | |
| // Re-ordering members of these structs won't reduce padding, so don't warn
 | |
| struct LeadingChar { // no-warning
 | |
|   char c;
 | |
|   int i;
 | |
| };
 | |
| 
 | |
| struct TrailingChar { // no-warning
 | |
|   int i;
 | |
|   char c;
 | |
| };
 | |
| 
 | |
| struct Helpless { // no-warning
 | |
|   struct TrailingChar i1;
 | |
|   struct LeadingChar i2;
 | |
|   char c;
 | |
| };
 | |
| 
 | |
| #pragma pack(push)
 | |
| #pragma pack(1)
 | |
| struct SquishedIntSandwich { // no-warning
 | |
|   char c1;
 | |
|   int i;
 | |
|   char c2;
 | |
| };
 | |
| #pragma pack(pop)
 | |
| 
 | |
| // Re-ordering members of these structs will reduce padding, so warn
 | |
| struct IntSandwich { // expected-warning{{Excessive padding in 'struct IntSandwich'}}
 | |
|   char c1;
 | |
|   int i;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| struct TurDuckHen { // expected-warning{{Excessive padding in 'struct TurDuckHen'}}
 | |
|   char c1;
 | |
|   struct IntSandwich i;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| #pragma pack(push)
 | |
| #pragma pack(2)
 | |
| struct SmallIntSandwich { // expected-warning{{Excessive padding in 'struct SmallIntSandwich'}}
 | |
|   char c1;
 | |
|   int i1;
 | |
|   char c2;
 | |
|   int i2;
 | |
|   char c3;
 | |
|   int i3;
 | |
|   char c4;
 | |
| };
 | |
| #pragma pack(pop)
 | |
| 
 | |
| union SomeUnion { // no-warning
 | |
|   char c;
 | |
|   short s;
 | |
|   int i;
 | |
| };
 | |
| 
 | |
| struct HoldsAUnion { // expected-warning{{Excessive padding in 'struct HoldsAUnion'}}
 | |
|   char c1;
 | |
|   union SomeUnion u;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| struct BigCharArray { // no-warning
 | |
|   char c[129];
 | |
| };
 | |
| 
 | |
| struct SmallCharArray { // no-warning
 | |
|   char c[5];
 | |
| };
 | |
| 
 | |
| struct MediumIntArray { // no-warning
 | |
|   int i[5];
 | |
| };
 | |
| 
 | |
| struct LargeSizeToSmallSize { // expected-warning{{Excessive padding in 'struct LargeSizeToSmallSize'}}
 | |
|   struct BigCharArray b;
 | |
|   struct MediumIntArray m;
 | |
|   struct SmallCharArray s;
 | |
| };
 | |
| 
 | |
| struct LargeAlignToSmallAlign { // no-warning
 | |
|   struct MediumIntArray m;
 | |
|   struct BigCharArray b;
 | |
|   struct SmallCharArray s;
 | |
| };
 | |
| 
 | |
| // Currently ignoring VLA padding problems.  Still need to make sure we don't
 | |
| // choke on VLAs though
 | |
| struct HoldsVLA { // no-warning
 | |
|   char c1;
 | |
|   int x;
 | |
|   char c2;
 | |
|   int vla[];
 | |
| };
 | |
| 
 | |
| // Currently ignoring bitfield padding problems.  Still need to make sure we
 | |
| // don't choke on bitfields though
 | |
| struct HoldsBitfield { // no-warning
 | |
|   char c1;
 | |
|   int x;
 | |
|   char c2;
 | |
|   unsigned char b1 : 3;
 | |
|   unsigned char b2 : 3;
 | |
|   unsigned char b3 : 2;
 | |
| };
 | |
| 
 | |
| typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich'}}
 | |
|   char c1;
 | |
|   int i;
 | |
|   char c2;
 | |
| } TypedefSandwich;
 | |
| 
 | |
| // expected-warning@+1{{Excessive padding in 'struct StructAttrAlign' (10 padding}}
 | |
| struct StructAttrAlign {
 | |
|   char c1;
 | |
|   int i;
 | |
|   char c2;
 | |
| } __attribute__((aligned(8)));
 | |
| 
 | |
| struct CorrectOverlyAlignedChar { // no-warning
 | |
|   char c __attribute__((aligned(4096)));
 | |
|   char c1;
 | |
|   int x1;
 | |
|   char c2;
 | |
|   int x2;
 | |
|   char c3;
 | |
| };
 | |
| 
 | |
| struct OverlyAlignedChar { // expected-warning{{Excessive padding in 'struct OverlyAlignedChar'}}
 | |
|   char c1;
 | |
|   int x;
 | |
|   char c2;
 | |
|   char c __attribute__((aligned(4096)));
 | |
| };
 | |
| 
 | |
| struct HoldsOverlyAlignedChar { // expected-warning{{Excessive padding in 'struct HoldsOverlyAlignedChar'}}
 | |
|   char c1;
 | |
|   struct OverlyAlignedChar o;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| void internalStructFunc() {
 | |
|   struct X { // expected-warning{{Excessive padding in 'struct X'}}
 | |
|     char c1;
 | |
|     int t;
 | |
|     char c2;
 | |
|   };
 | |
|   struct X obj;
 | |
| }
 | |
| 
 | |
| void typedefStructFunc() {
 | |
|   typedef struct { // expected-warning{{Excessive padding in 'S'}}
 | |
|     char c1;
 | |
|     int t;
 | |
|     char c2;
 | |
|   } S;
 | |
|   S obj;
 | |
| }
 | |
| 
 | |
| void anonStructFunc() {
 | |
|   struct { // expected-warning{{Excessive padding in 'struct (anonymous}}
 | |
|     char c1;
 | |
|     int t;
 | |
|     char c2;
 | |
|   } obj;
 | |
| }
 | |
| 
 | |
| struct CorrectDefaultAttrAlign { // no-warning
 | |
|   long long i;
 | |
|   char c1;
 | |
|   char c2;
 | |
| } __attribute__((aligned));
 | |
| 
 | |
| struct TooSmallShortSandwich { // no-warning
 | |
|   char c1;
 | |
|   short s;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| // expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich'}}
 | |
| struct SmallArrayShortSandwich {
 | |
|   char c1;
 | |
|   short s;
 | |
|   char c2;
 | |
| } ShortArray[20];
 | |
| 
 | |
| // expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc'}}
 | |
| struct SmallArrayInFunc {
 | |
|   char c1;
 | |
|   short s;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| void arrayHolder() {
 | |
|   struct SmallArrayInFunc Arr[15];
 | |
| }
 | |
| 
 | |
| // xxxexpected-warning@+1{{Excessive padding in 'struct SmallArrayInStruct'}}
 | |
| struct SmallArrayInStruct {
 | |
|   char c1;
 | |
|   short s;
 | |
|   char c2;
 | |
| };
 | |
| 
 | |
| struct HoldsSmallArray {
 | |
|   struct SmallArrayInStruct Field[20];
 | |
| } HoldsSmallArrayElt;
 | |
| 
 | |
| void nestedPadding() {
 | |
|   struct HoldsSmallArray Arr[15];
 | |
| }
 |