// RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++14 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
// expected-warning@+1{{Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal)}}
struct IntSandwich {
char c1;
int i;
char c2;
};
// expected-warning@+1{{Excessive padding in 'struct TurDuckHen' (6 padding bytes, where 2 is optimal)}}
struct TurDuckHen {
char c1;
struct IntSandwich i;
char c2;
};
#pragma pack(push)
#pragma pack(2)
// expected-warning@+1{{Excessive padding in 'struct SmallIntSandwich' (4 padding bytes, where 0 is optimal)}}
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;
};
// expected-warning@+1{{Excessive padding in 'struct HoldsAUnion' (6 padding bytes, where 2 is optimal)}}
struct HoldsAUnion {
char c1;
union SomeUnion u;
char c2;
};
struct SmallCharArray { // no-warning
char c[5];
};
struct MediumIntArray { // no-warning
int i[5];
};
// expected-warning@+1{{Excessive padding in 'struct StructSandwich' (6 padding bytes, where 2 is optimal)}}
struct StructSandwich {
struct SmallCharArray s;
struct MediumIntArray m;
struct SmallCharArray s2;
};
// expected-warning@+1{{Excessive padding in 'TypedefSandwich' (6 padding bytes, where 2 is optimal)}}
typedef struct {
char c1;
int i;
char c2;
} TypedefSandwich;
// expected-warning@+1{{Excessive padding in 'struct StructAttrAlign' (10 padding bytes, where 2 is optimal)}}
struct StructAttrAlign {
char c1;
int i;
char c2;
} __attribute__((aligned(8)));
// expected-warning@+1{{Excessive padding in 'struct OverlyAlignedChar' (8185 padding bytes, where 4089 is optimal)}}
struct OverlyAlignedChar {
char c1;
int x;
char c2;
char c __attribute__((aligned(4096)));
};
// expected-warning@+1{{Excessive padding in 'struct HoldsOverlyAlignedChar' (8190 padding bytes, where 4094 is optimal)}}
struct HoldsOverlyAlignedChar {
char c1;
struct OverlyAlignedChar o;
char c2;
};
void internalStructFunc() {
// expected-warning@+1{{Excessive padding in 'struct X' (6 padding bytes, where 2 is optimal)}}
struct X {
char c1;
int t;
char c2;
};
struct X obj;
}
void typedefStructFunc() {
// expected-warning@+1{{Excessive padding in 'S' (6 padding bytes, where 2 is optimal)}}
typedef struct {
char c1;
int t;
char c2;
} S;
S obj;
}
// expected-warning@+1{{Excessive padding in 'struct DefaultAttrAlign' (22 padding bytes, where 6 is optimal)}}
struct DefaultAttrAlign {
char c1;
long long i;
char c2;
} __attribute__((aligned));
// expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich' (2 padding bytes, where 0 is optimal)}}
struct SmallArrayShortSandwich {
char c1;
short s;
char c2;
} ShortArray[20];
// expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc' (2 padding bytes, where 0 is optimal)}}
struct SmallArrayInFunc {
char c1;
short s;
char c2;
};
void arrayHolder() {
struct SmallArrayInFunc Arr[15];
}
// expected-warning@+1{{Excessive padding in 'class VirtualIntSandwich' (10 padding bytes, where 2 is optimal)}}
class VirtualIntSandwich {
virtual void foo() {}
char c1;
int i;
char c2;
};
// constructed so as not to have tail padding
// expected-warning@+1{{Excessive padding in 'class InnerPaddedB' (6 padding bytes, where 2 is optimal)}}
class InnerPaddedB {
char c1;
int i1;
char c2;
int i2;
};
class Empty {}; // no-warning
// expected-warning@+1{{Excessive padding in 'class LotsOfSpace' (6 padding bytes, where 2 is optimal)}}
class LotsOfSpace {
Empty e1;
int i;
Empty e2;
};
// expected-warning@+1{{Excessive padding in 'TypedefSandwich2' (6 padding bytes, where 2 is optimal)}}
typedef struct {
char c1;
// expected-warning@+1{{Excessive padding in 'TypedefSandwich2::NestedTypedef' (6 padding bytes, where 2 is optimal)}}
typedef struct {
char c1;
int i;
char c2;
} NestedTypedef;
NestedTypedef t;
char c2;
} TypedefSandwich2;
template <typename T>
struct Foo {
// expected-warning@+1{{Excessive padding in 'struct Foo<int>::Nested' (6 padding bytes, where 2 is optimal)}}
struct Nested {
char c1;
T t;
char c2;
};
};
struct Holder { // no-warning
Foo<int>::Nested t1;
Foo<char>::Nested t2;
};