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