summaryrefslogtreecommitdiffstats
path: root/test/Analysis/padding_c.c
blob: 9e216a923e707123c631a6db69494ee306515288 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
// RUN: %clang_analyze_cc1 -verify %s \
// RUN:   -analyzer-checker=optin.performance \
// RUN:   -analyzer-config optin.performance.Padding:AllowedPad=2

// RUN: not %clang_analyze_cc1 -verify %s \
// RUN:   -analyzer-checker=core \
// RUN:   -analyzer-checker=optin.performance.Padding \
// RUN:   -analyzer-config optin.performance.Padding:AllowedPad=-10 \
// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-PAD-NEGATIVE-VALUE

// CHECK-PAD-NEGATIVE-VALUE: (frontend): invalid input for checker option
// CHECK-PAD-NEGATIVE-VALUE-SAME: 'optin.performance.Padding:AllowedPad', that
// CHECK-PAD-NEGATIVE-VALUE-SAME: expects a non-negative value

#if __has_include(<stdalign.h>)
#include <stdalign.h>
#endif

#if __has_include(<stdalign.h>) || defined(__cplusplus)
// expected-warning@+1{{Excessive padding in 'struct FieldAttrAlign' (6 padding}}
struct FieldAttrAlign {
  char c1;
  alignas(4) int i;
  char c2;
};

// expected-warning@+1{{Excessive padding in 'struct FieldAttrOverAlign' (10 padding}}
struct FieldAttrOverAlign {
  char c1;
  alignas(8) int i;
  char c2;
};

#endif // __has_include(<stdalign.h>) || defined(__cplusplus)

// Re-ordering members of these structs won't reduce padding, so don't warn
struct LeadingChar { // no-warning
  char c;
  int i;
};

struct TrailingChar { // no-warning
  int i;
  char c;
};

struct Helpless { // no-warning
  struct TrailingChar i1;
  struct LeadingChar i2;
  char c;
};

#pragma pack(push)
#pragma pack(1)
struct SquishedIntSandwich { // no-warning
  char c1;
  int i;
  char c2;
};
#pragma pack(pop)

// Re-ordering members of these structs will reduce padding, so warn
struct IntSandwich { // expected-warning{{Excessive padding in 'struct IntSandwich'}}
  char c1;
  int i;
  char c2;
};

struct TurDuckHen { // expected-warning{{Excessive padding in 'struct TurDuckHen'}}
  char c1;
  struct IntSandwich i;
  char c2;
};

#pragma pack(push)
#pragma pack(2)
struct SmallIntSandwich { // expected-warning{{Excessive padding in 'struct SmallIntSandwich'}}
  char c1;
  int i1;
  char c2;
  int i2;
  char c3;
  int i3;
  char c4;
};
#pragma pack(pop)

union SomeUnion { // no-warning
  char c;
  short s;
  int i;
};

struct HoldsAUnion { // expected-warning{{Excessive padding in 'struct HoldsAUnion'}}
  char c1;
  union SomeUnion u;
  char c2;
};

struct BigCharArray { // no-warning
  char c[129];
};

struct SmallCharArray { // no-warning
  char c[5];
};

struct MediumIntArray { // no-warning
  int i[5];
};

struct LargeSizeToSmallSize { // expected-warning{{Excessive padding in 'struct LargeSizeToSmallSize'}}
  struct BigCharArray b;
  struct MediumIntArray m;
  struct SmallCharArray s;
};

struct LargeAlignToSmallAlign { // no-warning
  struct MediumIntArray m;
  struct BigCharArray b;
  struct SmallCharArray s;
};

// Currently ignoring VLA padding problems.  Still need to make sure we don't
// choke on VLAs though
struct HoldsVLA { // no-warning
  char c1;
  int x;
  char c2;
  int vla[];
};

// Currently ignoring bitfield padding problems.  Still need to make sure we
// don't choke on bitfields though
struct HoldsBitfield { // no-warning
  char c1;
  int x;
  char c2;
  unsigned char b1 : 3;
  unsigned char b2 : 3;
  unsigned char b3 : 2;
};

typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich'}}
  char c1;
  int i;
  char c2;
} TypedefSandwich;

// expected-warning@+1{{Excessive padding in 'struct StructAttrAlign' (10 padding}}
struct StructAttrAlign {
  char c1;
  int i;
  char c2;
} __attribute__((aligned(8)));

struct CorrectOverlyAlignedChar { // no-warning
  char c __attribute__((aligned(4096)));
  char c1;
  int x1;
  char c2;
  int x2;
  char c3;
};

struct OverlyAlignedChar { // expected-warning{{Excessive padding in 'struct OverlyAlignedChar'}}
  char c1;
  int x;
  char c2;
  char c __attribute__((aligned(4096)));
};

struct HoldsOverlyAlignedChar { // expected-warning{{Excessive padding in 'struct HoldsOverlyAlignedChar'}}
  char c1;
  struct OverlyAlignedChar o;
  char c2;
};

void internalStructFunc() {
  struct X { // expected-warning{{Excessive padding in 'struct X'}}
    char c1;
    int t;
    char c2;
  };
  struct X obj;
}

void typedefStructFunc() {
  typedef struct { // expected-warning{{Excessive padding in 'S'}}
    char c1;
    int t;
    char c2;
  } S;
  S obj;
}

void anonStructFunc() {
  struct { // expected-warning{{Excessive padding in 'struct (anonymous}}
    char c1;
    int t;
    char c2;
  } obj;
}

struct CorrectDefaultAttrAlign { // no-warning
  long long i;
  char c1;
  char c2;
} __attribute__((aligned));

struct TooSmallShortSandwich { // no-warning
  char c1;
  short s;
  char c2;
};

// expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich'}}
struct SmallArrayShortSandwich {
  char c1;
  short s;
  char c2;
} ShortArray[20];

// expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc'}}
struct SmallArrayInFunc {
  char c1;
  short s;
  char c2;
};

void arrayHolder() {
  struct SmallArrayInFunc Arr[15];
}

// xxxexpected-warning@+1{{Excessive padding in 'struct SmallArrayInStruct'}}
struct SmallArrayInStruct {
  char c1;
  short s;
  char c2;
};

struct HoldsSmallArray {
  struct SmallArrayInStruct Field[20];
} HoldsSmallArrayElt;

void nestedPadding() {
  struct HoldsSmallArray Arr[15];
}