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 | |
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 | |
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 | |
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 { |
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 'TypedefSandwich2' (6 padding bytes, where 2 is optimal). \ |
269 | Optimal fields order: \ |
270 | t, \ |
271 | c1, \ |
272 | c2, \ |
273 | }} |
274 | typedef struct { |
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 | |