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