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