1 // 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
2 
3 // expected-warning@+7{{\
4 Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal). \
5 Optimal fields order: \
6 i, \
7 c1, \
8 c2, \
9 }}
10 struct IntSandwich {
11   char c1;
12   int i;
13   char c2;
14 };
15 
16 // expected-warning@+7{{\
17 Excessive padding in 'struct TurDuckHen' (6 padding bytes, where 2 is optimal). \
18 Optimal fields order: \
19 i, \
20 c1, \
21 c2, \
22 }}
23 struct TurDuckHen {
24   char c1;
25   struct IntSandwich i;
26   char c2;
27 };
28 
29 #pragma pack(push)
30 #pragma pack(2)
31 // expected-warning@+11{{\
32 Excessive padding in 'struct SmallIntSandwich' (4 padding bytes, where 0 is optimal). \
33 Optimal fields order: \
34 i1, \
35 i2, \
36 i3, \
37 c1, \
38 c2, \
39 c3, \
40 c4, \
41 }}
42 struct SmallIntSandwich {
43   char c1;
44   int i1;
45   char c2;
46   int i2;
47   char c3;
48   int i3;
49   char c4;
50 };
51 #pragma pack(pop)
52 
53 union SomeUnion { // no-warning
54   char c;
55   short s;
56   int i;
57 };
58 
59 // expected-warning@+7{{\
60 Excessive padding in 'struct HoldsAUnion' (6 padding bytes, where 2 is optimal). \
61 Optimal fields order: \
62 u, \
63 c1, \
64 c2, \
65 }}
66 struct HoldsAUnion {
67   char c1;
68   union SomeUnion u;
69   char c2;
70 };
71 
72 struct SmallCharArray { // no-warning
73   char c[5];
74 };
75 
76 struct MediumIntArray { // no-warning
77   int i[5];
78 };
79 
80 // expected-warning@+7{{\
81 Excessive padding in 'struct StructSandwich' (6 padding bytes, where 2 is optimal). \
82 Optimal fields order: \
83 m, \
84 s, \
85 s2, \
86 }}
87 struct StructSandwich {
88   struct SmallCharArray s;
89   struct MediumIntArray m;
90   struct SmallCharArray s2;
91 };
92 
93 // expected-warning@+7{{\
94 Excessive padding in 'TypedefSandwich' (6 padding bytes, where 2 is optimal). \
95 Optimal fields order: \
96 i, \
97 c1, \
98 c2, \
99 }}
100 typedef struct {
101   char c1;
102   int i;
103   char c2;
104 } TypedefSandwich;
105 
106 // expected-warning@+7{{\
107 Excessive padding in 'struct StructAttrAlign' (10 padding bytes, where 2 is optimal). \
108 Optimal fields order: \
109 i, \
110 c1, \
111 c2, \
112 }}
113 struct StructAttrAlign {
114   char c1;
115   int i;
116   char c2;
117 } __attribute__((aligned(8)));
118 
119 // expected-warning@+8{{\
120 Excessive padding in 'struct OverlyAlignedChar' (8185 padding bytes, where 4089 is optimal). \
121 Optimal fields order: \
122 c, \
123 c1, \
124 c2, \
125 x, \
126 }}
127 struct OverlyAlignedChar {
128   char c1;
129   int x;
130   char c2;
131   char c __attribute__((aligned(4096)));
132 };
133 
134 // expected-warning@+7{{\
135 Excessive padding in 'struct HoldsOverlyAlignedChar' (8190 padding bytes, where 4094 is optimal). \
136 Optimal fields order: \
137 o, \
138 c1, \
139 c2, \
140 }}
141 struct HoldsOverlyAlignedChar {
142   char c1;
143   struct OverlyAlignedChar o;
144   char c2;
145 };
146 
internalStructFunc()147 void internalStructFunc() {
148   // expected-warning@+7{{\
149 Excessive padding in 'struct X' (6 padding bytes, where 2 is optimal). \
150 Optimal fields order: \
151 t, \
152 c1, \
153 c2, \
154 }}
155   struct X {
156     char c1;
157     int t;
158     char c2;
159   };
160   struct X obj;
161 }
162 
typedefStructFunc()163 void typedefStructFunc() {
164   // expected-warning@+7{{\
165 Excessive padding in 'S' (6 padding bytes, where 2 is optimal). \
166 Optimal fields order: \
167 t, \
168 c1, \
169 c2, \
170 }}
171   typedef struct {
172     char c1;
173     int t;
174     char c2;
175   } S;
176   S obj;
177 }
178 
179 // expected-warning@+7{{\
180 Excessive padding in 'struct DefaultAttrAlign' (22 padding bytes, where 6 is optimal). \
181 Optimal fields order: \
182 i, \
183 c1, \
184 c2, \
185 }}
186 struct DefaultAttrAlign {
187   char c1;
188   long long i;
189   char c2;
190 } __attribute__((aligned));
191 
192 // expected-warning@+7{{\
193 Excessive padding in 'struct SmallArrayShortSandwich' (2 padding bytes, where 0 is optimal). \
194 Optimal fields order: \
195 s, \
196 c1, \
197 c2, \
198 }}
199 struct SmallArrayShortSandwich {
200   char c1;
201   short s;
202   char c2;
203 } ShortArray[20];
204 
205 // expected-warning@+7{{\
206 Excessive padding in 'struct SmallArrayInFunc' (2 padding bytes, where 0 is optimal). \
207 Optimal fields order: \
208 s, \
209 c1, \
210 c2, \
211 }}
212 struct SmallArrayInFunc {
213   char c1;
214   short s;
215   char c2;
216 };
217 
arrayHolder()218 void arrayHolder() {
219   struct SmallArrayInFunc Arr[15];
220 }
221 
222 // expected-warning@+7{{\
223 Excessive padding in 'class VirtualIntSandwich' (10 padding bytes, where 2 is optimal). \
224 Optimal fields order: \
225 i, \
226 c1, \
227 c2, \
228 }}
229 class VirtualIntSandwich {
foo()230   virtual void foo() {}
231   char c1;
232   int i;
233   char c2;
234 };
235 
236 // constructed so as not to have tail padding
237 // expected-warning@+8{{\
238 Excessive padding in 'class InnerPaddedB' (6 padding bytes, where 2 is optimal). \
239 Optimal fields order: \
240 i1, \
241 i2, \
242 c1, \
243 c2, \
244 }}
245 class InnerPaddedB {
246   char c1;
247   int i1;
248   char c2;
249   int i2;
250 };
251 
252 class Empty {}; // no-warning
253 
254 // expected-warning@+7{{\
255 Excessive padding in 'class LotsOfSpace' (6 padding bytes, where 2 is optimal). \
256 Optimal fields order: \
257 i, \
258 e1, \
259 e2, \
260 }}
261 class LotsOfSpace {
262   Empty e1;
263   int i;
264   Empty e2;
265 };
266 
267 // expected-warning@+7{{\
268 Excessive padding in 'struct TypedefSandwich2' (6 padding bytes, where 2 is optimal). \
269 Optimal fields order: \
270 t, \
271 c1, \
272 c2, \
273 }}
274 typedef struct TypedefSandwich2 {
275   char c1;
276   // expected-warning@+7{{\
277 Excessive padding in 'TypedefSandwich2::NestedTypedef' (6 padding bytes, where 2 is optimal). \
278 Optimal fields order: \
279 i, \
280 c1, \
281 c2, \
282 }}
283   typedef struct {
284     char c1;
285     int i;
286     char c2;
287   } NestedTypedef;
288   NestedTypedef t;
289   char c2;
290 } TypedefSandwich2;
291 
292 template <typename T>
293 struct Foo {
294   // expected-warning@+7{{\
295 Excessive padding in 'struct Foo<int>::Nested' (6 padding bytes, where 2 is optimal). \
296 Optimal fields order: \
297 t, \
298 c1, \
299 c2, \
300 }}
301   struct Nested {
302     char c1;
303     T t;
304     char c2;
305   };
306 };
307 
308 struct Holder { // no-warning
309   Foo<int>::Nested t1;
310   Foo<char>::Nested t2;
311 };
312