1*67e74705SXin Li // 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
2*67e74705SXin Li
3*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal)}}
4*67e74705SXin Li struct IntSandwich {
5*67e74705SXin Li char c1;
6*67e74705SXin Li int i;
7*67e74705SXin Li char c2;
8*67e74705SXin Li };
9*67e74705SXin Li
10*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct TurDuckHen' (6 padding bytes, where 2 is optimal)}}
11*67e74705SXin Li struct TurDuckHen {
12*67e74705SXin Li char c1;
13*67e74705SXin Li struct IntSandwich i;
14*67e74705SXin Li char c2;
15*67e74705SXin Li };
16*67e74705SXin Li
17*67e74705SXin Li #pragma pack(push)
18*67e74705SXin Li #pragma pack(2)
19*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct SmallIntSandwich' (4 padding bytes, where 0 is optimal)}}
20*67e74705SXin Li struct SmallIntSandwich {
21*67e74705SXin Li char c1;
22*67e74705SXin Li int i1;
23*67e74705SXin Li char c2;
24*67e74705SXin Li int i2;
25*67e74705SXin Li char c3;
26*67e74705SXin Li int i3;
27*67e74705SXin Li char c4;
28*67e74705SXin Li };
29*67e74705SXin Li #pragma pack(pop)
30*67e74705SXin Li
31*67e74705SXin Li union SomeUnion { // no-warning
32*67e74705SXin Li char c;
33*67e74705SXin Li short s;
34*67e74705SXin Li int i;
35*67e74705SXin Li };
36*67e74705SXin Li
37*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct HoldsAUnion' (6 padding bytes, where 2 is optimal)}}
38*67e74705SXin Li struct HoldsAUnion {
39*67e74705SXin Li char c1;
40*67e74705SXin Li union SomeUnion u;
41*67e74705SXin Li char c2;
42*67e74705SXin Li };
43*67e74705SXin Li
44*67e74705SXin Li struct SmallCharArray { // no-warning
45*67e74705SXin Li char c[5];
46*67e74705SXin Li };
47*67e74705SXin Li
48*67e74705SXin Li struct MediumIntArray { // no-warning
49*67e74705SXin Li int i[5];
50*67e74705SXin Li };
51*67e74705SXin Li
52*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct StructSandwich' (6 padding bytes, where 2 is optimal)}}
53*67e74705SXin Li struct StructSandwich {
54*67e74705SXin Li struct SmallCharArray s;
55*67e74705SXin Li struct MediumIntArray m;
56*67e74705SXin Li struct SmallCharArray s2;
57*67e74705SXin Li };
58*67e74705SXin Li
59*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'TypedefSandwich' (6 padding bytes, where 2 is optimal)}}
60*67e74705SXin Li typedef struct {
61*67e74705SXin Li char c1;
62*67e74705SXin Li int i;
63*67e74705SXin Li char c2;
64*67e74705SXin Li } TypedefSandwich;
65*67e74705SXin Li
66*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct StructAttrAlign' (10 padding bytes, where 2 is optimal)}}
67*67e74705SXin Li struct StructAttrAlign {
68*67e74705SXin Li char c1;
69*67e74705SXin Li int i;
70*67e74705SXin Li char c2;
71*67e74705SXin Li } __attribute__((aligned(8)));
72*67e74705SXin Li
73*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct OverlyAlignedChar' (8185 padding bytes, where 4089 is optimal)}}
74*67e74705SXin Li struct OverlyAlignedChar {
75*67e74705SXin Li char c1;
76*67e74705SXin Li int x;
77*67e74705SXin Li char c2;
78*67e74705SXin Li char c __attribute__((aligned(4096)));
79*67e74705SXin Li };
80*67e74705SXin Li
81*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct HoldsOverlyAlignedChar' (8190 padding bytes, where 4094 is optimal)}}
82*67e74705SXin Li struct HoldsOverlyAlignedChar {
83*67e74705SXin Li char c1;
84*67e74705SXin Li struct OverlyAlignedChar o;
85*67e74705SXin Li char c2;
86*67e74705SXin Li };
87*67e74705SXin Li
internalStructFunc()88*67e74705SXin Li void internalStructFunc() {
89*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct X' (6 padding bytes, where 2 is optimal)}}
90*67e74705SXin Li struct X {
91*67e74705SXin Li char c1;
92*67e74705SXin Li int t;
93*67e74705SXin Li char c2;
94*67e74705SXin Li };
95*67e74705SXin Li struct X obj;
96*67e74705SXin Li }
97*67e74705SXin Li
typedefStructFunc()98*67e74705SXin Li void typedefStructFunc() {
99*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'S' (6 padding bytes, where 2 is optimal)}}
100*67e74705SXin Li typedef struct {
101*67e74705SXin Li char c1;
102*67e74705SXin Li int t;
103*67e74705SXin Li char c2;
104*67e74705SXin Li } S;
105*67e74705SXin Li S obj;
106*67e74705SXin Li }
107*67e74705SXin Li
108*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct DefaultAttrAlign' (22 padding bytes, where 6 is optimal)}}
109*67e74705SXin Li struct DefaultAttrAlign {
110*67e74705SXin Li char c1;
111*67e74705SXin Li long long i;
112*67e74705SXin Li char c2;
113*67e74705SXin Li } __attribute__((aligned));
114*67e74705SXin Li
115*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich' (2 padding bytes, where 0 is optimal)}}
116*67e74705SXin Li struct SmallArrayShortSandwich {
117*67e74705SXin Li char c1;
118*67e74705SXin Li short s;
119*67e74705SXin Li char c2;
120*67e74705SXin Li } ShortArray[20];
121*67e74705SXin Li
122*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc' (2 padding bytes, where 0 is optimal)}}
123*67e74705SXin Li struct SmallArrayInFunc {
124*67e74705SXin Li char c1;
125*67e74705SXin Li short s;
126*67e74705SXin Li char c2;
127*67e74705SXin Li };
128*67e74705SXin Li
arrayHolder()129*67e74705SXin Li void arrayHolder() {
130*67e74705SXin Li struct SmallArrayInFunc Arr[15];
131*67e74705SXin Li }
132*67e74705SXin Li
133*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'class VirtualIntSandwich' (10 padding bytes, where 2 is optimal)}}
134*67e74705SXin Li class VirtualIntSandwich {
foo()135*67e74705SXin Li virtual void foo() {}
136*67e74705SXin Li char c1;
137*67e74705SXin Li int i;
138*67e74705SXin Li char c2;
139*67e74705SXin Li };
140*67e74705SXin Li
141*67e74705SXin Li // constructed so as not to have tail padding
142*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'class InnerPaddedB' (6 padding bytes, where 2 is optimal)}}
143*67e74705SXin Li class InnerPaddedB {
144*67e74705SXin Li char c1;
145*67e74705SXin Li int i1;
146*67e74705SXin Li char c2;
147*67e74705SXin Li int i2;
148*67e74705SXin Li };
149*67e74705SXin Li
150*67e74705SXin Li class Empty {}; // no-warning
151*67e74705SXin Li
152*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'class LotsOfSpace' (6 padding bytes, where 2 is optimal)}}
153*67e74705SXin Li class LotsOfSpace {
154*67e74705SXin Li Empty e1;
155*67e74705SXin Li int i;
156*67e74705SXin Li Empty e2;
157*67e74705SXin Li };
158*67e74705SXin Li
159*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'TypedefSandwich2' (6 padding bytes, where 2 is optimal)}}
160*67e74705SXin Li typedef struct {
161*67e74705SXin Li char c1;
162*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'TypedefSandwich2::NestedTypedef' (6 padding bytes, where 2 is optimal)}}
163*67e74705SXin Li typedef struct {
164*67e74705SXin Li char c1;
165*67e74705SXin Li int i;
166*67e74705SXin Li char c2;
167*67e74705SXin Li } NestedTypedef;
168*67e74705SXin Li NestedTypedef t;
169*67e74705SXin Li char c2;
170*67e74705SXin Li } TypedefSandwich2;
171*67e74705SXin Li
172*67e74705SXin Li template <typename T>
173*67e74705SXin Li struct Foo {
174*67e74705SXin Li // expected-warning@+1{{Excessive padding in 'struct Foo<int>::Nested' (6 padding bytes, where 2 is optimal)}}
175*67e74705SXin Li struct Nested {
176*67e74705SXin Li char c1;
177*67e74705SXin Li T t;
178*67e74705SXin Li char c2;
179*67e74705SXin Li };
180*67e74705SXin Li };
181*67e74705SXin Li
182*67e74705SXin Li struct Holder { // no-warning
183*67e74705SXin Li Foo<int>::Nested t1;
184*67e74705SXin Li Foo<char>::Nested t2;
185*67e74705SXin Li };
186