1 // RUN: %clang_cc1 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
2 
3 #if __has_include(<stdalign.h>)
4 #include <stdalign.h>
5 #endif
6 
7 #if __has_include(<stdalign.h>) || defined(__cplusplus)
8 // expected-warning@+1{{Excessive padding in 'struct FieldAttrAlign' (6 padding}}
9 struct FieldAttrAlign {
10   char c1;
11   alignas(4) int i;
12   char c2;
13 };
14 
15 // expected-warning@+1{{Excessive padding in 'struct FieldAttrOverAlign' (10 padding}}
16 struct FieldAttrOverAlign {
17   char c1;
18   alignas(8) int i;
19   char c2;
20 };
21 
22 #endif // __has_include(<stdalign.h>) || defined(__cplusplus)
23 
24 // Re-ordering members of these structs won't reduce padding, so don't warn
25 struct LeadingChar { // no-warning
26   char c;
27   int i;
28 };
29 
30 struct TrailingChar { // no-warning
31   int i;
32   char c;
33 };
34 
35 struct Helpless { // no-warning
36   struct TrailingChar i1;
37   struct LeadingChar i2;
38   char c;
39 };
40 
41 #pragma pack(push)
42 #pragma pack(1)
43 struct SquishedIntSandwich { // no-warning
44   char c1;
45   int i;
46   char c2;
47 };
48 #pragma pack(pop)
49 
50 // Re-ordering members of these structs will reduce padding, so warn
51 struct IntSandwich { // expected-warning{{Excessive padding in 'struct IntSandwich'}}
52   char c1;
53   int i;
54   char c2;
55 };
56 
57 struct TurDuckHen { // expected-warning{{Excessive padding in 'struct TurDuckHen'}}
58   char c1;
59   struct IntSandwich i;
60   char c2;
61 };
62 
63 #pragma pack(push)
64 #pragma pack(2)
65 struct SmallIntSandwich { // expected-warning{{Excessive padding in 'struct SmallIntSandwich'}}
66   char c1;
67   int i1;
68   char c2;
69   int i2;
70   char c3;
71   int i3;
72   char c4;
73 };
74 #pragma pack(pop)
75 
76 union SomeUnion { // no-warning
77   char c;
78   short s;
79   int i;
80 };
81 
82 struct HoldsAUnion { // expected-warning{{Excessive padding in 'struct HoldsAUnion'}}
83   char c1;
84   union SomeUnion u;
85   char c2;
86 };
87 
88 struct BigCharArray { // no-warning
89   char c[129];
90 };
91 
92 struct SmallCharArray { // no-warning
93   char c[5];
94 };
95 
96 struct MediumIntArray { // no-warning
97   int i[5];
98 };
99 
100 struct LargeSizeToSmallSize { // expected-warning{{Excessive padding in 'struct LargeSizeToSmallSize'}}
101   struct BigCharArray b;
102   struct MediumIntArray m;
103   struct SmallCharArray s;
104 };
105 
106 struct LargeAlignToSmallAlign { // no-warning
107   struct MediumIntArray m;
108   struct BigCharArray b;
109   struct SmallCharArray s;
110 };
111 
112 // Currently ignoring VLA padding problems.  Still need to make sure we don't
113 // choke on VLAs though
114 struct HoldsVLA { // no-warning
115   char c1;
116   int x;
117   char c2;
118   int vla[];
119 };
120 
121 // Currently ignoring bitfield padding problems.  Still need to make sure we
122 // don't choke on bitfields though
123 struct HoldsBitfield { // no-warning
124   char c1;
125   int x;
126   char c2;
127   unsigned char b1 : 3;
128   unsigned char b2 : 3;
129   unsigned char b3 : 2;
130 };
131 
132 typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich'}}
133   char c1;
134   int i;
135   char c2;
136 } TypedefSandwich;
137 
138 // expected-warning@+1{{Excessive padding in 'struct StructAttrAlign' (10 padding}}
139 struct StructAttrAlign {
140   char c1;
141   int i;
142   char c2;
143 } __attribute__((aligned(8)));
144 
145 struct CorrectOverlyAlignedChar { // no-warning
146   char c __attribute__((aligned(4096)));
147   char c1;
148   int x1;
149   char c2;
150   int x2;
151   char c3;
152 };
153 
154 struct OverlyAlignedChar { // expected-warning{{Excessive padding in 'struct OverlyAlignedChar'}}
155   char c1;
156   int x;
157   char c2;
158   char c __attribute__((aligned(4096)));
159 };
160 
161 struct HoldsOverlyAlignedChar { // expected-warning{{Excessive padding in 'struct HoldsOverlyAlignedChar'}}
162   char c1;
163   struct OverlyAlignedChar o;
164   char c2;
165 };
166 
internalStructFunc()167 void internalStructFunc() {
168   struct X { // expected-warning{{Excessive padding in 'struct X'}}
169     char c1;
170     int t;
171     char c2;
172   };
173   struct X obj;
174 }
175 
typedefStructFunc()176 void typedefStructFunc() {
177   typedef struct { // expected-warning{{Excessive padding in 'S'}}
178     char c1;
179     int t;
180     char c2;
181   } S;
182   S obj;
183 }
184 
anonStructFunc()185 void anonStructFunc() {
186   struct { // expected-warning{{Excessive padding in 'struct (anonymous}}
187     char c1;
188     int t;
189     char c2;
190   } obj;
191 }
192 
193 struct CorrectDefaultAttrAlign { // no-warning
194   long long i;
195   char c1;
196   char c2;
197 } __attribute__((aligned));
198 
199 struct TooSmallShortSandwich { // no-warning
200   char c1;
201   short s;
202   char c2;
203 };
204 
205 // expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich'}}
206 struct SmallArrayShortSandwich {
207   char c1;
208   short s;
209   char c2;
210 } ShortArray[20];
211 
212 // expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc'}}
213 struct SmallArrayInFunc {
214   char c1;
215   short s;
216   char c2;
217 };
218 
arrayHolder()219 void arrayHolder() {
220   struct SmallArrayInFunc Arr[15];
221 }
222 
223 // xxxexpected-warning@+1{{Excessive padding in 'struct SmallArrayInStruct'}}
224 struct SmallArrayInStruct {
225   char c1;
226   short s;
227   char c2;
228 };
229 
230 struct HoldsSmallArray {
231   struct SmallArrayInStruct Field[20];
232 } HoldsSmallArrayElt;
233 
nestedPadding()234 void nestedPadding() {
235   struct HoldsSmallArray Arr[15];
236 }
237