diff options
Diffstat (limited to 'test/Analysis/padding_c.c')
-rw-r--r-- | test/Analysis/padding_c.c | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/test/Analysis/padding_c.c b/test/Analysis/padding_c.c new file mode 100644 index 000000000000..93cefcad8930 --- /dev/null +++ b/test/Analysis/padding_c.c @@ -0,0 +1,236 @@ +// 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]; +} |