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 |
35 | virtual void foo() {} |
36 | }; |
37 | |
38 | class 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 |
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 |
81 | virtual void foo() {} |
82 | char c; |
83 | }; |
84 | |
85 | class 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 | |
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'}} |
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 { // 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 | |
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}} |
201 | auto lambda1 = [ c1 = G.c1, i = G.i, c2 = G.c2 ]{}; |
202 | auto lambda2 = [ i = G.i, c1 = G.c1, c2 = G.c2 ]{}; // no-warning |
203 | |