1184c6242SDominic Chen // RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
297c191c4SBen Craig 
3b9250475SSaleem Abdulrasool // expected-warning@+7{{\
4b9250475SSaleem Abdulrasool Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal). \
5b9250475SSaleem Abdulrasool Optimal fields order: \
6b9250475SSaleem Abdulrasool i, \
7b9250475SSaleem Abdulrasool c1, \
8b9250475SSaleem Abdulrasool c2, \
9b9250475SSaleem Abdulrasool }}
1097c191c4SBen Craig struct IntSandwich {
1197c191c4SBen Craig   char c1;
1297c191c4SBen Craig   int i;
1397c191c4SBen Craig   char c2;
1497c191c4SBen Craig };
1597c191c4SBen Craig 
16b9250475SSaleem Abdulrasool // expected-warning@+7{{\
17b9250475SSaleem Abdulrasool Excessive padding in 'struct TurDuckHen' (6 padding bytes, where 2 is optimal). \
18b9250475SSaleem Abdulrasool Optimal fields order: \
19b9250475SSaleem Abdulrasool i, \
20b9250475SSaleem Abdulrasool c1, \
21b9250475SSaleem Abdulrasool c2, \
22b9250475SSaleem Abdulrasool }}
2397c191c4SBen Craig struct TurDuckHen {
2497c191c4SBen Craig   char c1;
2597c191c4SBen Craig   struct IntSandwich i;
2697c191c4SBen Craig   char c2;
2797c191c4SBen Craig };
2897c191c4SBen Craig 
2997c191c4SBen Craig #pragma pack(push)
3097c191c4SBen Craig #pragma pack(2)
31b9250475SSaleem Abdulrasool // expected-warning@+11{{\
32b9250475SSaleem Abdulrasool Excessive padding in 'struct SmallIntSandwich' (4 padding bytes, where 0 is optimal). \
33b9250475SSaleem Abdulrasool Optimal fields order: \
34b9250475SSaleem Abdulrasool i1, \
35b9250475SSaleem Abdulrasool i2, \
36b9250475SSaleem Abdulrasool i3, \
37b9250475SSaleem Abdulrasool c1, \
38b9250475SSaleem Abdulrasool c2, \
39b9250475SSaleem Abdulrasool c3, \
40b9250475SSaleem Abdulrasool c4, \
41b9250475SSaleem Abdulrasool }}
4297c191c4SBen Craig struct SmallIntSandwich {
4397c191c4SBen Craig   char c1;
4497c191c4SBen Craig   int i1;
4597c191c4SBen Craig   char c2;
4697c191c4SBen Craig   int i2;
4797c191c4SBen Craig   char c3;
4897c191c4SBen Craig   int i3;
4997c191c4SBen Craig   char c4;
5097c191c4SBen Craig };
5197c191c4SBen Craig #pragma pack(pop)
5297c191c4SBen Craig 
5397c191c4SBen Craig union SomeUnion { // no-warning
5497c191c4SBen Craig   char c;
5597c191c4SBen Craig   short s;
5697c191c4SBen Craig   int i;
5797c191c4SBen Craig };
5897c191c4SBen Craig 
59b9250475SSaleem Abdulrasool // expected-warning@+7{{\
60b9250475SSaleem Abdulrasool Excessive padding in 'struct HoldsAUnion' (6 padding bytes, where 2 is optimal). \
61b9250475SSaleem Abdulrasool Optimal fields order: \
62b9250475SSaleem Abdulrasool u, \
63b9250475SSaleem Abdulrasool c1, \
64b9250475SSaleem Abdulrasool c2, \
65b9250475SSaleem Abdulrasool }}
6697c191c4SBen Craig struct HoldsAUnion {
6797c191c4SBen Craig   char c1;
6897c191c4SBen Craig   union SomeUnion u;
6997c191c4SBen Craig   char c2;
7097c191c4SBen Craig };
7197c191c4SBen Craig 
7297c191c4SBen Craig struct SmallCharArray { // no-warning
7397c191c4SBen Craig   char c[5];
7497c191c4SBen Craig };
7597c191c4SBen Craig 
7697c191c4SBen Craig struct MediumIntArray { // no-warning
7797c191c4SBen Craig   int i[5];
7897c191c4SBen Craig };
7997c191c4SBen Craig 
80b9250475SSaleem Abdulrasool // expected-warning@+7{{\
81b9250475SSaleem Abdulrasool Excessive padding in 'struct StructSandwich' (6 padding bytes, where 2 is optimal). \
82b9250475SSaleem Abdulrasool Optimal fields order: \
83b9250475SSaleem Abdulrasool m, \
84b9250475SSaleem Abdulrasool s, \
85b9250475SSaleem Abdulrasool s2, \
86b9250475SSaleem Abdulrasool }}
8797c191c4SBen Craig struct StructSandwich {
8897c191c4SBen Craig   struct SmallCharArray s;
8997c191c4SBen Craig   struct MediumIntArray m;
9097c191c4SBen Craig   struct SmallCharArray s2;
9197c191c4SBen Craig };
9297c191c4SBen Craig 
93b9250475SSaleem Abdulrasool // expected-warning@+7{{\
94b9250475SSaleem Abdulrasool Excessive padding in 'TypedefSandwich' (6 padding bytes, where 2 is optimal). \
95b9250475SSaleem Abdulrasool Optimal fields order: \
96b9250475SSaleem Abdulrasool i, \
97b9250475SSaleem Abdulrasool c1, \
98b9250475SSaleem Abdulrasool c2, \
99b9250475SSaleem Abdulrasool }}
10097c191c4SBen Craig typedef struct {
10197c191c4SBen Craig   char c1;
10297c191c4SBen Craig   int i;
10397c191c4SBen Craig   char c2;
10497c191c4SBen Craig } TypedefSandwich;
10597c191c4SBen Craig 
106b9250475SSaleem Abdulrasool // expected-warning@+7{{\
107b9250475SSaleem Abdulrasool Excessive padding in 'struct StructAttrAlign' (10 padding bytes, where 2 is optimal). \
108b9250475SSaleem Abdulrasool Optimal fields order: \
109b9250475SSaleem Abdulrasool i, \
110b9250475SSaleem Abdulrasool c1, \
111b9250475SSaleem Abdulrasool c2, \
112b9250475SSaleem Abdulrasool }}
11397c191c4SBen Craig struct StructAttrAlign {
11497c191c4SBen Craig   char c1;
11597c191c4SBen Craig   int i;
11697c191c4SBen Craig   char c2;
11797c191c4SBen Craig } __attribute__((aligned(8)));
11897c191c4SBen Craig 
119b9250475SSaleem Abdulrasool // expected-warning@+8{{\
120b9250475SSaleem Abdulrasool Excessive padding in 'struct OverlyAlignedChar' (8185 padding bytes, where 4089 is optimal). \
121b9250475SSaleem Abdulrasool Optimal fields order: \
122b9250475SSaleem Abdulrasool c, \
123b9250475SSaleem Abdulrasool c1, \
124b9250475SSaleem Abdulrasool c2, \
125b9250475SSaleem Abdulrasool x, \
126b9250475SSaleem Abdulrasool }}
12797c191c4SBen Craig struct OverlyAlignedChar {
12897c191c4SBen Craig   char c1;
12997c191c4SBen Craig   int x;
13097c191c4SBen Craig   char c2;
13197c191c4SBen Craig   char c __attribute__((aligned(4096)));
13297c191c4SBen Craig };
13397c191c4SBen Craig 
134b9250475SSaleem Abdulrasool // expected-warning@+7{{\
135b9250475SSaleem Abdulrasool Excessive padding in 'struct HoldsOverlyAlignedChar' (8190 padding bytes, where 4094 is optimal). \
136b9250475SSaleem Abdulrasool Optimal fields order: \
137b9250475SSaleem Abdulrasool o, \
138b9250475SSaleem Abdulrasool c1, \
139b9250475SSaleem Abdulrasool c2, \
140b9250475SSaleem Abdulrasool }}
14197c191c4SBen Craig struct HoldsOverlyAlignedChar {
14297c191c4SBen Craig   char c1;
14397c191c4SBen Craig   struct OverlyAlignedChar o;
14497c191c4SBen Craig   char c2;
14597c191c4SBen Craig };
14697c191c4SBen Craig 
internalStructFunc()14797c191c4SBen Craig void internalStructFunc() {
148b9250475SSaleem Abdulrasool   // expected-warning@+7{{\
149b9250475SSaleem Abdulrasool Excessive padding in 'struct X' (6 padding bytes, where 2 is optimal). \
150b9250475SSaleem Abdulrasool Optimal fields order: \
151b9250475SSaleem Abdulrasool t, \
152b9250475SSaleem Abdulrasool c1, \
153b9250475SSaleem Abdulrasool c2, \
154b9250475SSaleem Abdulrasool }}
15597c191c4SBen Craig   struct X {
15697c191c4SBen Craig     char c1;
15797c191c4SBen Craig     int t;
15897c191c4SBen Craig     char c2;
15997c191c4SBen Craig   };
16097c191c4SBen Craig   struct X obj;
16197c191c4SBen Craig }
16297c191c4SBen Craig 
typedefStructFunc()16397c191c4SBen Craig void typedefStructFunc() {
164b9250475SSaleem Abdulrasool   // expected-warning@+7{{\
165b9250475SSaleem Abdulrasool Excessive padding in 'S' (6 padding bytes, where 2 is optimal). \
166b9250475SSaleem Abdulrasool Optimal fields order: \
167b9250475SSaleem Abdulrasool t, \
168b9250475SSaleem Abdulrasool c1, \
169b9250475SSaleem Abdulrasool c2, \
170b9250475SSaleem Abdulrasool }}
17197c191c4SBen Craig   typedef struct {
17297c191c4SBen Craig     char c1;
17397c191c4SBen Craig     int t;
17497c191c4SBen Craig     char c2;
17597c191c4SBen Craig   } S;
17697c191c4SBen Craig   S obj;
17797c191c4SBen Craig }
17897c191c4SBen Craig 
179b9250475SSaleem Abdulrasool // expected-warning@+7{{\
180b9250475SSaleem Abdulrasool Excessive padding in 'struct DefaultAttrAlign' (22 padding bytes, where 6 is optimal). \
181b9250475SSaleem Abdulrasool Optimal fields order: \
182b9250475SSaleem Abdulrasool i, \
183b9250475SSaleem Abdulrasool c1, \
184b9250475SSaleem Abdulrasool c2, \
185b9250475SSaleem Abdulrasool }}
18697c191c4SBen Craig struct DefaultAttrAlign {
18797c191c4SBen Craig   char c1;
18897c191c4SBen Craig   long long i;
18997c191c4SBen Craig   char c2;
19097c191c4SBen Craig } __attribute__((aligned));
19197c191c4SBen Craig 
192b9250475SSaleem Abdulrasool // expected-warning@+7{{\
193b9250475SSaleem Abdulrasool Excessive padding in 'struct SmallArrayShortSandwich' (2 padding bytes, where 0 is optimal). \
194b9250475SSaleem Abdulrasool Optimal fields order: \
195b9250475SSaleem Abdulrasool s, \
196b9250475SSaleem Abdulrasool c1, \
197b9250475SSaleem Abdulrasool c2, \
198b9250475SSaleem Abdulrasool }}
19997c191c4SBen Craig struct SmallArrayShortSandwich {
20097c191c4SBen Craig   char c1;
20197c191c4SBen Craig   short s;
20297c191c4SBen Craig   char c2;
20397c191c4SBen Craig } ShortArray[20];
20497c191c4SBen Craig 
205b9250475SSaleem Abdulrasool // expected-warning@+7{{\
206b9250475SSaleem Abdulrasool Excessive padding in 'struct SmallArrayInFunc' (2 padding bytes, where 0 is optimal). \
207b9250475SSaleem Abdulrasool Optimal fields order: \
208b9250475SSaleem Abdulrasool s, \
209b9250475SSaleem Abdulrasool c1, \
210b9250475SSaleem Abdulrasool c2, \
211b9250475SSaleem Abdulrasool }}
21297c191c4SBen Craig struct SmallArrayInFunc {
21397c191c4SBen Craig   char c1;
21497c191c4SBen Craig   short s;
21597c191c4SBen Craig   char c2;
21697c191c4SBen Craig };
21797c191c4SBen Craig 
arrayHolder()21897c191c4SBen Craig void arrayHolder() {
21997c191c4SBen Craig   struct SmallArrayInFunc Arr[15];
22097c191c4SBen Craig }
22197c191c4SBen Craig 
222b9250475SSaleem Abdulrasool // expected-warning@+7{{\
223b9250475SSaleem Abdulrasool Excessive padding in 'class VirtualIntSandwich' (10 padding bytes, where 2 is optimal). \
224b9250475SSaleem Abdulrasool Optimal fields order: \
225b9250475SSaleem Abdulrasool i, \
226b9250475SSaleem Abdulrasool c1, \
227b9250475SSaleem Abdulrasool c2, \
228b9250475SSaleem Abdulrasool }}
22997c191c4SBen Craig class VirtualIntSandwich {
foo()23097c191c4SBen Craig   virtual void foo() {}
23197c191c4SBen Craig   char c1;
23297c191c4SBen Craig   int i;
23397c191c4SBen Craig   char c2;
23497c191c4SBen Craig };
23597c191c4SBen Craig 
23697c191c4SBen Craig // constructed so as not to have tail padding
237b9250475SSaleem Abdulrasool // expected-warning@+8{{\
238b9250475SSaleem Abdulrasool Excessive padding in 'class InnerPaddedB' (6 padding bytes, where 2 is optimal). \
239b9250475SSaleem Abdulrasool Optimal fields order: \
240b9250475SSaleem Abdulrasool i1, \
241b9250475SSaleem Abdulrasool i2, \
242b9250475SSaleem Abdulrasool c1, \
243b9250475SSaleem Abdulrasool c2, \
244b9250475SSaleem Abdulrasool }}
24597c191c4SBen Craig class InnerPaddedB {
24697c191c4SBen Craig   char c1;
24797c191c4SBen Craig   int i1;
24897c191c4SBen Craig   char c2;
24997c191c4SBen Craig   int i2;
25097c191c4SBen Craig };
25197c191c4SBen Craig 
25297c191c4SBen Craig class Empty {}; // no-warning
25397c191c4SBen Craig 
254b9250475SSaleem Abdulrasool // expected-warning@+7{{\
255b9250475SSaleem Abdulrasool Excessive padding in 'class LotsOfSpace' (6 padding bytes, where 2 is optimal). \
256b9250475SSaleem Abdulrasool Optimal fields order: \
257b9250475SSaleem Abdulrasool i, \
258b9250475SSaleem Abdulrasool e1, \
259b9250475SSaleem Abdulrasool e2, \
260b9250475SSaleem Abdulrasool }}
26197c191c4SBen Craig class LotsOfSpace {
26297c191c4SBen Craig   Empty e1;
26397c191c4SBen Craig   int i;
26497c191c4SBen Craig   Empty e2;
26597c191c4SBen Craig };
26697c191c4SBen Craig 
267b9250475SSaleem Abdulrasool // expected-warning@+7{{\
268*7ae1b4a0SRichard Smith Excessive padding in 'struct TypedefSandwich2' (6 padding bytes, where 2 is optimal). \
269b9250475SSaleem Abdulrasool Optimal fields order: \
270b9250475SSaleem Abdulrasool t, \
271b9250475SSaleem Abdulrasool c1, \
272b9250475SSaleem Abdulrasool c2, \
273b9250475SSaleem Abdulrasool }}
274*7ae1b4a0SRichard Smith typedef struct TypedefSandwich2 {
27597c191c4SBen Craig   char c1;
276b9250475SSaleem Abdulrasool   // expected-warning@+7{{\
277b9250475SSaleem Abdulrasool Excessive padding in 'TypedefSandwich2::NestedTypedef' (6 padding bytes, where 2 is optimal). \
278b9250475SSaleem Abdulrasool Optimal fields order: \
279b9250475SSaleem Abdulrasool i, \
280b9250475SSaleem Abdulrasool c1, \
281b9250475SSaleem Abdulrasool c2, \
282b9250475SSaleem Abdulrasool }}
28397c191c4SBen Craig   typedef struct {
28497c191c4SBen Craig     char c1;
28597c191c4SBen Craig     int i;
28697c191c4SBen Craig     char c2;
28797c191c4SBen Craig   } NestedTypedef;
28897c191c4SBen Craig   NestedTypedef t;
28997c191c4SBen Craig   char c2;
29097c191c4SBen Craig } TypedefSandwich2;
29197c191c4SBen Craig 
29297c191c4SBen Craig template <typename T>
29397c191c4SBen Craig struct Foo {
294b9250475SSaleem Abdulrasool   // expected-warning@+7{{\
295b9250475SSaleem Abdulrasool Excessive padding in 'struct Foo<int>::Nested' (6 padding bytes, where 2 is optimal). \
296b9250475SSaleem Abdulrasool Optimal fields order: \
297b9250475SSaleem Abdulrasool t, \
298b9250475SSaleem Abdulrasool c1, \
299b9250475SSaleem Abdulrasool c2, \
300b9250475SSaleem Abdulrasool }}
30197c191c4SBen Craig   struct Nested {
30297c191c4SBen Craig     char c1;
30397c191c4SBen Craig     T t;
30497c191c4SBen Craig     char c2;
30597c191c4SBen Craig   };
30697c191c4SBen Craig };
30797c191c4SBen Craig 
30897c191c4SBen Craig struct Holder { // no-warning
30997c191c4SBen Craig   Foo<int>::Nested t1;
31097c191c4SBen Craig   Foo<char>::Nested t2;
31197c191c4SBen Craig };
312