// RUN: %clang_cc1 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s #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]; }