Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: tools/clang/plugins/tests/ipc.cpp

Issue 1665363002: Clang plugin to check that unstable types are not used in IPC. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use SmallVector; revert build script changes Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Blacklisted typedefs
6 typedef __INTMAX_TYPE__ intmax_t;
7 typedef __UINTMAX_TYPE__ uintmax_t;
8 typedef int intptr_t;
9 typedef unsigned int uintptr_t;
10 typedef __WINT_TYPE__ wint_t;
11 typedef __SIZE_TYPE__ size_t;
12 typedef __SIZE_TYPE__ rsize_t;
13 typedef long ssize_t;
14 typedef __PTRDIFF_TYPE__ ptrdiff_t;
15 typedef unsigned int dev_t;
16 typedef int off_t;
17 typedef long clock_t;
18 typedef int time_t;
19 typedef long suseconds_t;
20
21 // Other typedefs
22 typedef int int32_t;
23 typedef unsigned int uint32_t;
24 typedef long int64_t;
25 typedef unsigned long uint64_t;
26
27 namespace std {
28 template <class T>
29 struct allocator {};
30
31 template <class T, class A = allocator<T>>
32 struct vector {};
33
34 template <class F, class S>
35 struct pair {};
36 }
37
38 namespace base {
39 class Pickle {};
40
41 template <class T, class... Ts>
42 struct Tuple {
43 T value;
44 };
45 }
46
47 namespace IPC {
48 template <class... T>
dcheng 2016/03/07 23:44:39 No indent in namespace (similar comment above)
49 struct CheckedTuple {
50 typedef base::Tuple<T...> Tuple;
51 };
52
53 template <class T>
54 struct ParamTraits {
55 static void Write(base::Pickle*, const T&) {}
56 };
57
58 template <class T>
59 void WriteParam(base::Pickle* pickle, const T& value) {
60 ParamTraits<T>::Write(pickle, value);
61 }
62 }
63
64 #if 1
dcheng 2016/03/07 23:44:39 Remove the #if 1's.
65
66 /* Test IPC::WriteParam() usage in templates. ERRORS: 6 */
67
68 struct Data {
69 uint32_t value;
70 size_t size;
71 };
72
73 template <>
74 struct IPC::ParamTraits<Data> {
75 static void Write(base::Pickle* pickle, const Data& p) {
76 // OK: WriteParam() called in explicit specialization
77 WriteParam(pickle, p.value); // OK
78 WriteParam(pickle, p.size); // ERROR
79 }
80 };
81
82 template <class T>
83 struct Container {
84 T value;
85 };
86
87 template <class T>
88 struct IPC::ParamTraits<Container<T>> {
89 static void Write(base::Pickle* pickle, const Container<T>& container) {
90 // NOT CHECKED: T is not explicitly referenced
91 IPC::WriteParam(pickle, container.value); // NOT CHECKED
92 WriteParam(pickle, container.value); // NOT CHECKED
93
94 // NOT CHECKED: T explicitly referenced
95 IPC::WriteParam<T>(pickle, container.value); // NOT CHECKED
96 WriteParam<T>(pickle, container.value); // NOT CHECKED
97
98 // OK: explicit cast to non-dependent allowed type
99 WriteParam(pickle, static_cast<uint32_t>(container.value)); // OK
100
101 // ERROR: explicit cast to non-dependent banned type
102 WriteParam(pickle, static_cast<long>(container.value)); // ERROR
103 }
104 };
105
106 template <class T, class... Ts>
107 struct MultiContainer {
108 T value;
109 };
110
111 template <class T, class... Ts>
112 struct IPC::ParamTraits<MultiContainer<T, Ts...>> {
113 static void Write(base::Pickle* pickle,
114 const MultiContainer<T, Ts...>& container) {
115 // NOT CHECKED: template argument explicitly referenced
116 bool helper[] = {
117 (WriteParam<Ts>(pickle, container.value), true)... // NOT CHECKED
118 };
119 (void)helper;
120 }
121 };
122
123 template <class T>
124 struct SomeClass {
125 static void Write(base::Pickle* pickle) {
126 // NOT CHECKED: WriteParam() can only be used in ParamTraits templates
dcheng 2016/03/07 23:44:39 I don't think I understand how this comment relate
Dmitry Skiba 2016/03/08 01:16:11 Done.
127 IPC::WriteParam(pickle, T(0)); // NOT CHECKED
128 IPC::WriteParam(pickle, size_t(0)); // ERROR
129 IPC::WriteParam(pickle, uint64_t(0)); // OK
130 }
131
132 template <class U>
133 static void WriteEx(base::Pickle* pickle) {
134 // NOT CHECKED: WriteParam() can only be used in ParamTraits templates
dcheng 2016/03/07 23:44:39 Same here.
135 IPC::WriteParam(pickle, U(0)); // NOT CHECKED
136 IPC::WriteParam(pickle, time_t(0)); // ERROR
137 IPC::WriteParam(pickle, uint32_t(0)); // OK
138 }
139 };
140
141 template <class T>
142 void SomeWriteFunction(base::Pickle* pickle) {
143 // NOT CHECKED: WriteParam() can only be used in ParamTraits templates
dcheng 2016/03/07 23:44:39 And here.
144 IPC::WriteParam(pickle, T(0)); // NOT CHECKED
145 IPC::WriteParam(pickle, long(0)); // ERROR
146 IPC::WriteParam(pickle, char(0)); // OK
147
148 [&](){
149 IPC::WriteParam(pickle, T(0)); // NOT CHECKED
150 IPC::WriteParam(pickle, clock_t(0)); // ERROR
151 IPC::WriteParam(pickle, int64_t(0)); // OK
152 }();
153 }
154
155 void TestWriteParamInTemplates() {
156 // These specializations call WriteParam() on various banned types, either
157 // because they were specified directly (long) or because non-blacklisted
158 // typedef (uint64_t) was stripped down to its underlying type, which is
159 // blacklisted when used as is (unsigned long).
160 // However, since it's hard (if not impossible) to check specializations
161 // properly, we're simply not checking them.
162 SomeClass<long>::Write(nullptr);
163 SomeClass<long>::WriteEx<uint64_t>(nullptr);
164 SomeWriteFunction<uint64_t>(nullptr);
165 }
166
167 #endif
168
169 #if 1
170
171 /* Test IPC::CheckedTuple. ERRORS: 5 */
172
173 #define IPC_TUPLE(...) IPC::CheckedTuple<__VA_ARGS__>::Tuple
174
175 #define IPC_MESSAGE_DECL(name, id, in_tuple) \
176 struct name ## Meta_ ## id { \
177 using InTuple = in_tuple; \
178 };
179
180 #define IPC_TEST_MESSAGE(id, in) \
181 IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
182
183 struct Empty {};
184
185 IPC_TEST_MESSAGE(__COUNTER__, (bool, size_t, Empty, long)) // 2 ERRORs
186
187 typedef std::vector<long> long1D;
188 typedef std::vector<long1D> long2D;
189 IPC_TEST_MESSAGE(__COUNTER__, (bool, long2D)) // ERROR
190
191 IPC_TEST_MESSAGE(__COUNTER__, (char, short, std::pair<size_t, bool>)) // ERROR
192
193 IPC_TEST_MESSAGE(__COUNTER__, (std::vector<std::vector<long&>&>&)) // ERROR
194
195 #endif
196
197 #if 1
198
199 /* Check IPC::WriteParam() arguments. ERRORS: 31 */
200
201 // ERRORS: 21
202 void TestWriteParamArgument() {
203 #define CALL_WRITEPARAM(Type) \
204 { \
205 Type p; \
206 IPC::WriteParam(nullptr, p); \
207 }
208
209 // ERROR: blacklisted types / typedefs
210 CALL_WRITEPARAM(long) // ERROR
211 CALL_WRITEPARAM(unsigned long) // ERROR
212 CALL_WRITEPARAM(intmax_t) // ERROR
213 CALL_WRITEPARAM(uintmax_t) // ERROR
214 CALL_WRITEPARAM(intptr_t) // ERROR
215 CALL_WRITEPARAM(uintptr_t) // ERROR
216 CALL_WRITEPARAM(wint_t) // ERROR
217 CALL_WRITEPARAM(size_t) // ERROR
218 CALL_WRITEPARAM(rsize_t) // ERROR
219 CALL_WRITEPARAM(ssize_t) // ERROR
220 CALL_WRITEPARAM(ptrdiff_t) // ERROR
221 CALL_WRITEPARAM(dev_t) // ERROR
222 CALL_WRITEPARAM(off_t) // ERROR
223 CALL_WRITEPARAM(clock_t) // ERROR
224 CALL_WRITEPARAM(time_t) // ERROR
225 CALL_WRITEPARAM(suseconds_t) // ERROR
226
227 // ERROR: typedef to blacklisted typedef
228 typedef size_t my_size;
229 CALL_WRITEPARAM(my_size) // ERROR
230
231 // ERROR: expression ends up with type "unsigned long"
232 {
233 uint64_t p = 0;
234 IPC::WriteParam(nullptr, p + 1); // ERROR
dcheng 2016/03/07 23:44:39 Slightly unexpected. I guess this basically should
Dmitry Skiba 2016/03/08 01:16:11 Yes, p + 1 turns uint64_t into its base type, whic
235 }
236
237 // ERROR: long chain of typedefs, ends up with blacklisted typedef
238 {
239 typedef size_t my_size_base;
240 typedef const my_size_base my_size;
241 typedef my_size& my_size_ref;
242 my_size_ref p = 0;
243 IPC::WriteParam(nullptr, p); // ERROR
244 }
245
246 // ERROR: template specialization references blacklisted type
247 CALL_WRITEPARAM(std::vector<long>) // ERROR
248 CALL_WRITEPARAM(std::vector<size_t>) // ERROR
249
250 // OK: typedef to blacklisted type
251 typedef long my_long;
252 CALL_WRITEPARAM(my_long) // OK
253
254 // OK: other types / typedefs
255 CALL_WRITEPARAM(char) // OK
256 CALL_WRITEPARAM(int) // OK
257 CALL_WRITEPARAM(uint32_t) // OK
258 CALL_WRITEPARAM(int64_t) // OK
259
260 // OK: long chain of typedefs, ends up with non-blacklisted typedef
261 {
262 typedef uint32_t my_int_base;
263 typedef const my_int_base my_int;
264 typedef my_int& my_int_ref;
265 my_int_ref p = 0;
266 IPC::WriteParam(nullptr, p); // OK
267 }
268
269 // OK: template specialization references non-blacklisted type
270 CALL_WRITEPARAM(std::vector<char>) // OK
271 CALL_WRITEPARAM(std::vector<my_long>) // OK
272
273 #undef CALL_WRITEPARAM
274 }
275
276 struct Provider {
277 typedef unsigned int flags;
278
279 short get_short() const { return 0; }
280 uint64_t get_uint64() const { return 0; }
281 long get_long() const { return 0; }
282 unsigned int get_uint() const { return 0; }
283 flags get_flags() const { return 0; }
284 size_t get_size() const { return 0; }
285
286 const std::vector<size_t>& get_sizes() const { return sizes_data; }
287 const std::vector<uint64_t>& get_uint64s() const { return uint64s_data; }
288
289 template <class T>
290 T get() const { return T(); }
291
292 short short_data;
293 unsigned int uint_data;
294 flags flags_data;
295 long long_data;
296 size_t size_data;
297 uint64_t uint64_data;
298 std::vector<size_t> sizes_data;
299 std::vector<uint64_t> uint64s_data;
300 };
301
302 // ERRORS: 10
303 void TestWriteParamMemberArgument() {
304 Provider p;
305
306 IPC::WriteParam(nullptr, p.get<short>()); // OK
307 IPC::WriteParam(nullptr, p.get_short()); // OK
308 IPC::WriteParam(nullptr, p.short_data); // OK
309
310 IPC::WriteParam(nullptr, p.get<unsigned int>()); // OK
311 IPC::WriteParam(nullptr, p.get_uint()); // OK
312 IPC::WriteParam(nullptr, p.uint_data); // OK
313
314 IPC::WriteParam(nullptr, p.get<Provider::flags>()); // OK
315 IPC::WriteParam(nullptr, p.get_flags()); // OK
316 IPC::WriteParam(nullptr, p.flags_data); // OK
317
318 IPC::WriteParam(nullptr, p.get<long>()); // ERROR
319 IPC::WriteParam(nullptr, p.get_long()); // ERROR
320 IPC::WriteParam(nullptr, p.long_data); // ERROR
321
322 IPC::WriteParam(nullptr, p.get<size_t>()); // ERROR
323 IPC::WriteParam(nullptr, p.get_size()); // ERROR
324 IPC::WriteParam(nullptr, p.size_data); // ERROR
325
326 // Information about uint64_t gets lost, and plugin sees WriteParam()
327 // call on unsigned long, which is blacklisted.
328 IPC::WriteParam(nullptr, p.get<uint64_t>()); // ERROR
dcheng 2016/03/07 23:44:39 I guess this is just for the template case, so may
329 IPC::WriteParam(nullptr, p.get_uint64()); // OK
330 IPC::WriteParam(nullptr, p.uint64_data); // OK
331
332 // Same thing here, WriteParam() sees vector<unsigned long>, and denies it.
333 IPC::WriteParam(nullptr, p.get<std::vector<uint64_t>>()); // ERROR
334 IPC::WriteParam(nullptr, p.get_uint64s()); // OK
335 IPC::WriteParam(nullptr, p.uint64s_data); // OK
336
337 // This one is flaky and depends on whether size_t is typedefed to a
338 // blacklisted type (unsigned long).
339 //IPC::WriteParam(nullptr, p.get<std::vector<uint64_t>>());
340 IPC::WriteParam(nullptr, p.get_sizes()); // ERROR
341 IPC::WriteParam(nullptr, p.sizes_data); // ERROR
342 }
343
344 #endif
345
346 /* ERRORS: 42 */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698