Clang Project

clang_source_code/test/Analysis/padding_c.c
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}}
21struct 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}}
28struct 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
37struct LeadingChar { // no-warning
38  char c;
39  int i;
40};
41
42struct TrailingChar { // no-warning
43  int i;
44  char c;
45};
46
47struct Helpless { // no-warning
48  struct TrailingChar i1;
49  struct LeadingChar i2;
50  char c;
51};
52
53#pragma pack(push)
54#pragma pack(1)
55struct 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
63struct IntSandwich { // expected-warning{{Excessive padding in 'struct IntSandwich'}}
64  char c1;
65  int i;
66  char c2;
67};
68
69struct 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)
77struct 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
88union SomeUnion { // no-warning
89  char c;
90  short s;
91  int i;
92};
93
94struct HoldsAUnion { // expected-warning{{Excessive padding in 'struct HoldsAUnion'}}
95  char c1;
96  union SomeUnion u;
97  char c2;
98};
99
100struct BigCharArray { // no-warning
101  char c[129];
102};
103
104struct SmallCharArray { // no-warning
105  char c[5];
106};
107
108struct MediumIntArray { // no-warning
109  int i[5];
110};
111
112struct LargeSizeToSmallSize { // expected-warning{{Excessive padding in 'struct LargeSizeToSmallSize'}}
113  struct BigCharArray b;
114  struct MediumIntArray m;
115  struct SmallCharArray s;
116};
117
118struct 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
126struct 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
135struct 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
144typedef 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}}
151struct StructAttrAlign {
152  char c1;
153  int i;
154  char c2;
155} __attribute__((aligned(8)));
156
157struct 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
166struct 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
173struct HoldsOverlyAlignedChar { // expected-warning{{Excessive padding in 'struct HoldsOverlyAlignedChar'}}
174  char c1;
175  struct OverlyAlignedChar o;
176  char c2;
177};
178
179void 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
188void 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
197void anonStructFunc() {
198  struct { // expected-warning{{Excessive padding in 'struct (anonymous}}
199    char c1;
200    int t;
201    char c2;
202  } obj;
203}
204
205struct CorrectDefaultAttrAlign { // no-warning
206  long long i;
207  char c1;
208  char c2;
209} __attribute__((aligned));
210
211struct TooSmallShortSandwich { // no-warning
212  char c1;
213  short s;
214  char c2;
215};
216
217// expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich'}}
218struct SmallArrayShortSandwich {
219  char c1;
220  short s;
221  char c2;
222} ShortArray[20];
223
224// expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc'}}
225struct SmallArrayInFunc {
226  char c1;
227  short s;
228  char c2;
229};
230
231void arrayHolder() {
232  struct SmallArrayInFunc Arr[15];
233}
234
235// xxxexpected-warning@+1{{Excessive padding in 'struct SmallArrayInStruct'}}
236struct SmallArrayInStruct {
237  char c1;
238  short s;
239  char c2;
240};
241
242struct HoldsSmallArray {
243  struct SmallArrayInStruct Field[20];
244} HoldsSmallArrayElt;
245
246void nestedPadding() {
247  struct HoldsSmallArray Arr[15];
248}
249