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