// 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(void) {
struct X { // expected-warning{{Excessive padding in 'struct X'}}
char c1;
int t;
char c2;
};
struct X obj;
}
void typedefStructFunc(void) {
typedef struct { // expected-warning{{Excessive padding in 'S'}}
char c1;
int t;
char c2;
} S;
S obj;
}
void anonStructFunc(void) {
struct { // expected-warning{{Excessive padding in 'struct (unnamed}}
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(void) {
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(void) {
struct HoldsSmallArray Arr[15];
}