| // RUN: %clang_analyze_cc1 -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]; |
| } |