1// RUN: %clang_cc1 -std=c++14 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
2
3// Make sure that the C cases still work fine, even when compiled as C++.
4#include "padding_c.c"
5
6struct BigCharArray2 { // no-warning
7  char c[129];
8};
9
10// xxxexpected-warning@+1{{Excessive padding in 'struct LowAlignmentBase'}}
11struct LowAlignmentBase : public BigCharArray2 {
12  int i;
13  char c;
14};
15
16struct CorrectLowAlignmentBase : public BigCharArray2 { // no-warning
17  char c;
18  int i;
19};
20
21// xxxexpected-warning@+1{{Excessive padding in 'struct LowAlignmentBase2'}}
22struct LowAlignmentBase2 : public BigCharArray2 {
23  char c1;
24  int i;
25  char c2;
26};
27
28class PaddedA { // expected-warning{{Excessive padding in 'class PaddedA'}}
29  char c1;
30  int i;
31  char c2;
32};
33
34class VirtualPaddedA : public PaddedA { // no-warning
35  virtual void foo() {}
36};
37
38class VirtualIntSandwich { // expected-warning{{Excessive padding in 'class VirtualIntSandwich'}}
39  virtual void foo() {}
40  char c1;
41  int i;
42  char c2;
43};
44
45// constructed so as not to have tail padding
46class InnerPaddedB { // expected-warning{{Excessive padding in 'class InnerPaddedB'}}
47  char c1;
48  int i1;
49  char c2;
50  int i2;
51};
52
53class TailPaddedB { // expected-warning{{Excessive padding in 'class TailPaddedB'}}
54  char c1;
55  int i1;
56  char c2;
57};
58
59class SI : public PaddedA { // no-warning
60  char c;
61};
62
63class SI2 : public PaddedA { // xxxexpected-warning{{Excessive padding in 'class SI2'}}
64  char c10;
65  int i10;
66  char c11;
67};
68
69class VirtualSI : virtual public PaddedA { // no-warning
70  char c;
71};
72
73// currently not checked for
74class VirtualSI2 : virtual public PaddedA { // no-warning
75  char c10;
76  int i10;
77  char c11;
78};
79
80class VtblSI : public PaddedA { // no-warning
81  virtual void foo() {}
82  char c;
83};
84
85class VtblSI2 : public PaddedA { // xxxexpected-warning{{Excessive padding in 'class VtblSI2'}}
86  virtual void foo() {}
87  char c10;
88  int i10;
89  char c11;
90};
91
92class VtblSI3 : public VirtualPaddedA { // xxxexpected-warning{{Excessive padding in 'class VtblSI3'}}
93  char c10;
94  int i10;
95  char c11;
96};
97
98class MI : public PaddedA, public InnerPaddedB { // no-warning
99  char c;
100};
101
102class MI2 : public PaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class MI2'}}
103  char c10;
104  int i10;
105  char c11;
106};
107
108class VtblMI : public PaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class VtblMI'}}
109  virtual void foo() {}
110  char c10;
111  int i10;
112  char c11;
113};
114
115class VtblMI2 : public VirtualPaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class VtblMI2'}}
116  char c10;
117  int i10;
118  char c11;
119};
120
121class Empty {}; // no-warning
122
123class LotsOfSpace { // expected-warning{{Excessive padding in 'class LotsOfSpace'}}
124  Empty e1;
125  int i;
126  Empty e2;
127};
128
129class EBO1 : public Empty { // xxxexpected-warning{{Excessive padding in 'class EBO1'}}
130  char c1;
131  int i;
132  char c2;
133};
134
135class EBO2 : public Empty { // xxxexpected-warning{{Excessive padding in 'class EBO2'}}
136  Empty c1;
137  int i;
138  Empty c2;
139};
140
141template <typename T>
142class TemplateSandwich { // expected-warning{{Excessive padding in 'class TemplateSandwich<int>' instantiated here}}
143  char c1;
144  T t;
145  char c2;
146};
147
148template <typename T>
149class TemplateSandwich<T *> { // expected-warning{{Excessive padding in 'class TemplateSandwich<void *>' instantiated here}}
150  char c1;
151  T *t;
152  char c2;
153};
154
155template <>
156class TemplateSandwich<long long> { // expected-warning{{Excessive padding in 'class TemplateSandwich<long long>' (}}
157  char c1;
158  long long t;
159  char c2;
160};
161
162class Holder1 { // no-warning
163  TemplateSandwich<int> t1;
164  TemplateSandwich<char> t2;
165  TemplateSandwich<void *> t3;
166};
167
168typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich2'}}
169  char c1;
170  typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich2::NestedTypedef'}}
171    char c1;
172    int i;
173    char c2;
174  } NestedTypedef;
175  NestedTypedef t;
176  char c2;
177} TypedefSandwich2;
178
179template <typename T>
180struct Foo {
181  // expected-warning@+1{{Excessive padding in 'struct Foo<int>::Nested'}}
182  struct Nested {
183    char c1;
184    T t;
185    char c2;
186  };
187};
188
189struct Holder { // no-warning
190  Foo<int>::Nested t1;
191  Foo<char>::Nested t2;
192};
193
194struct GlobalsForLambda { // no-warning
195  int i;
196  char c1;
197  char c2;
198} G;
199
200// expected-warning@+1{{Excessive padding in 'class (lambda}}
201auto lambda1 = [ c1 = G.c1, i = G.i, c2 = G.c2 ]{};
202auto lambda2 = [ i = G.i, c1 = G.c1, c2 = G.c2 ]{}; // no-warning
203