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];
 | 
						|
}
 |