1// RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++14 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
2
3// expected-warning@+1{{Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal)}}
4struct IntSandwich {
5  char c1;
6  int i;
7  char c2;
8};
9
10// expected-warning@+1{{Excessive padding in 'struct TurDuckHen' (6 padding bytes, where 2 is optimal)}}
11struct TurDuckHen {
12  char c1;
13  struct IntSandwich i;
14  char c2;
15};
16
17#pragma pack(push)
18#pragma pack(2)
19// expected-warning@+1{{Excessive padding in 'struct SmallIntSandwich' (4 padding bytes, where 0 is optimal)}}
20struct SmallIntSandwich {
21  char c1;
22  int i1;
23  char c2;
24  int i2;
25  char c3;
26  int i3;
27  char c4;
28};
29#pragma pack(pop)
30
31union SomeUnion { // no-warning
32  char c;
33  short s;
34  int i;
35};
36
37// expected-warning@+1{{Excessive padding in 'struct HoldsAUnion' (6 padding bytes, where 2 is optimal)}}
38struct HoldsAUnion {
39  char c1;
40  union SomeUnion u;
41  char c2;
42};
43
44struct SmallCharArray { // no-warning
45  char c[5];
46};
47
48struct MediumIntArray { // no-warning
49  int i[5];
50};
51
52// expected-warning@+1{{Excessive padding in 'struct StructSandwich' (6 padding bytes, where 2 is optimal)}}
53struct StructSandwich {
54  struct SmallCharArray s;
55  struct MediumIntArray m;
56  struct SmallCharArray s2;
57};
58
59// expected-warning@+1{{Excessive padding in 'TypedefSandwich' (6 padding bytes, where 2 is optimal)}}
60typedef struct {
61  char c1;
62  int i;
63  char c2;
64} TypedefSandwich;
65
66// expected-warning@+1{{Excessive padding in 'struct StructAttrAlign' (10 padding bytes, where 2 is optimal)}}
67struct StructAttrAlign {
68  char c1;
69  int i;
70  char c2;
71} __attribute__((aligned(8)));
72
73// expected-warning@+1{{Excessive padding in 'struct OverlyAlignedChar' (8185 padding bytes, where 4089 is optimal)}}
74struct OverlyAlignedChar {
75  char c1;
76  int x;
77  char c2;
78  char c __attribute__((aligned(4096)));
79};
80
81// expected-warning@+1{{Excessive padding in 'struct HoldsOverlyAlignedChar' (8190 padding bytes, where 4094 is optimal)}}
82struct HoldsOverlyAlignedChar {
83  char c1;
84  struct OverlyAlignedChar o;
85  char c2;
86};
87
88void internalStructFunc() {
89  // expected-warning@+1{{Excessive padding in 'struct X' (6 padding bytes, where 2 is optimal)}}
90  struct X {
91    char c1;
92    int t;
93    char c2;
94  };
95  struct X obj;
96}
97
98void typedefStructFunc() {
99  // expected-warning@+1{{Excessive padding in 'S' (6 padding bytes, where 2 is optimal)}}
100  typedef struct {
101    char c1;
102    int t;
103    char c2;
104  } S;
105  S obj;
106}
107
108// expected-warning@+1{{Excessive padding in 'struct DefaultAttrAlign' (22 padding bytes, where 6 is optimal)}}
109struct DefaultAttrAlign {
110  char c1;
111  long long i;
112  char c2;
113} __attribute__((aligned));
114
115// expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich' (2 padding bytes, where 0 is optimal)}}
116struct SmallArrayShortSandwich {
117  char c1;
118  short s;
119  char c2;
120} ShortArray[20];
121
122// expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc' (2 padding bytes, where 0 is optimal)}}
123struct SmallArrayInFunc {
124  char c1;
125  short s;
126  char c2;
127};
128
129void arrayHolder() {
130  struct SmallArrayInFunc Arr[15];
131}
132
133// expected-warning@+1{{Excessive padding in 'class VirtualIntSandwich' (10 padding bytes, where 2 is optimal)}}
134class VirtualIntSandwich {
135  virtual void foo() {}
136  char c1;
137  int i;
138  char c2;
139};
140
141// constructed so as not to have tail padding
142// expected-warning@+1{{Excessive padding in 'class InnerPaddedB' (6 padding bytes, where 2 is optimal)}}
143class InnerPaddedB {
144  char c1;
145  int i1;
146  char c2;
147  int i2;
148};
149
150class Empty {}; // no-warning
151
152// expected-warning@+1{{Excessive padding in 'class LotsOfSpace' (6 padding bytes, where 2 is optimal)}}
153class LotsOfSpace {
154  Empty e1;
155  int i;
156  Empty e2;
157};
158
159// expected-warning@+1{{Excessive padding in 'TypedefSandwich2' (6 padding bytes, where 2 is optimal)}}
160typedef struct {
161  char c1;
162  // expected-warning@+1{{Excessive padding in 'TypedefSandwich2::NestedTypedef' (6 padding bytes, where 2 is optimal)}}
163  typedef struct {
164    char c1;
165    int i;
166    char c2;
167  } NestedTypedef;
168  NestedTypedef t;
169  char c2;
170} TypedefSandwich2;
171
172template <typename T>
173struct Foo {
174  // expected-warning@+1{{Excessive padding in 'struct Foo<int>::Nested' (6 padding bytes, where 2 is optimal)}}
175  struct Nested {
176    char c1;
177    T t;
178    char c2;
179  };
180};
181
182struct Holder { // no-warning
183  Foo<int>::Nested t1;
184  Foo<char>::Nested t2;
185};
186