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

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: Blacklist types instead Created 4 years, 10 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 T value;
34 };
35
36 template <class F, class S>
37 struct pair {};
38 }
39
40 namespace base {
41 class Pickle {};
42
43 template <class T, class... Ts>
44 struct Tuple {
45 T value;
46 };
47 }
48
49 namespace IPC {
50 template <class... T>
51 struct CheckedTuple {
52 typedef base::Tuple<T...> Tuple;
53 };
54
55 template <class T>
56 struct ParamTraits {
57 static void Write(base::Pickle*, const T&) {}
58 };
59
60 template <class T>
61 void WriteParam(base::Pickle* pickle, const T& value) {
62 ParamTraits<T>::Write(pickle, value);
63 }
64 }
65
66 #if 1
67
68 /* Test IPC::WriteParam() usage in templates. ERRORS: 6 */
69
70 struct Data {
71 uint32_t value;
72 };
73
74 template <>
75 struct IPC::ParamTraits<Data> {
76 static void Write(base::Pickle* pickle, const Data& p) {
77 // OK: WriteParam() called in explicit specialization
78 WriteParam(pickle, p.value); // OK
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 // ERROR: T is not explicitly referenced
91 IPC::WriteParam(pickle, container.value); // ERROR
92 WriteParam(pickle, container.value); // ERROR
93
94 // OK: T explicitly referenced
95 IPC::WriteParam<T>(pickle, container.value); // OK
96 WriteParam<T>(pickle, container.value); // OK
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 // OK: template argument explicitly referenced
116 bool helper[] = {(WriteParam<Ts>(pickle, container.value), true)...}; // OK
117 (void)helper;
118 }
119 };
120
121 template <class T>
122 struct SomeClass {
123 static void Write(base::Pickle* pickle) {
124 // ERROR: WriteParam() can only be used in ParamTraits templates
125 T p;
126 IPC::WriteParam(pickle, p); // ERROR
127 }
128 };
129
130 template <class T>
131 void SomeWriteFunction(base::Pickle* pickle) {
132 // ERROR: WriteParam() can only be used in ParamTraits templates
133 T p;
134 IPC::WriteParam(pickle, p); // ERROR
135 [&](){
136 IPC::WriteParam(pickle, p); // ERROR
137 }();
138 }
139
140 void TestWriteParamInTemplates() {
141 SomeClass<int>::Write(nullptr);
142 SomeWriteFunction<uint32_t>(nullptr);
143 }
144
145 #endif
146
147 #if 1
148
149 /* Test IPC::CheckedTuple. ERRORS: 4 */
150
151 #define IPC_TUPLE(...) IPC::CheckedTuple<__VA_ARGS__>::Tuple
152
153 #define IPC_MESSAGE_DECL(name, id, in_tuple) \
154 struct name ## Meta_ ## id { \
155 using InTuple = in_tuple; \
156 };
157
158 #define IPC_TEST_MESSAGE(id, in) \
159 IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
160
161 struct Empty {};
162
163 IPC_TEST_MESSAGE(__COUNTER__, (bool, size_t, Empty, long)) // 2 ERRORs
164
165 typedef std::vector<long> long1D;
166 typedef std::vector<long1D> long2D;
167 IPC_TEST_MESSAGE(__COUNTER__, (bool, long2D)) // ERROR
168
169 IPC_TEST_MESSAGE(__COUNTER__, (char, short, std::pair<size_t, bool>)) // ERROR
170
171 #endif
172
173 #if 1
174
175 /* Check IPC::WriteParam() arguments. ERRORS: 26 */
176
177 void TestWriteParamArgument() {
178 #define CALL_WRITEPARAM(Type) \
179 { \
180 Type p = 0; \
181 IPC::WriteParam(nullptr, p); \
182 }
183
184 // ERROR: blacklisted types / typedefs
185 CALL_WRITEPARAM(long) // ERROR
186 CALL_WRITEPARAM(unsigned long) // ERROR
187 CALL_WRITEPARAM(intmax_t) // ERROR
188 CALL_WRITEPARAM(uintmax_t) // ERROR
189 CALL_WRITEPARAM(intptr_t) // ERROR
190 CALL_WRITEPARAM(uintptr_t) // ERROR
191 CALL_WRITEPARAM(wint_t) // ERROR
192 CALL_WRITEPARAM(size_t) // ERROR
193 CALL_WRITEPARAM(rsize_t) // ERROR
194 CALL_WRITEPARAM(ssize_t) // ERROR
195 CALL_WRITEPARAM(ptrdiff_t) // ERROR
196 CALL_WRITEPARAM(dev_t) // ERROR
197 CALL_WRITEPARAM(off_t) // ERROR
198 CALL_WRITEPARAM(clock_t) // ERROR
199 CALL_WRITEPARAM(time_t) // ERROR
200 CALL_WRITEPARAM(suseconds_t) // ERROR
201
202 // ERROR: typedef to blacklisted typedef
203 typedef size_t my_size;
204 CALL_WRITEPARAM(my_size) // ERROR
205
206 // ERROR: expression ends up with type "unsigned long"
207 {
208 uint64_t p = 0;
209 IPC::WriteParam(nullptr, p + 1); // ERROR
210 }
211
212 // ERROR: long chain of typedefs, ends up with blacklisted typedef
213 {
214 typedef size_t my_size_base;
215 typedef const my_size_base my_size;
216 typedef my_size& my_size_ref;
217 my_size_ref p = 0;
218 IPC::WriteParam(nullptr, p); // ERROR
219 }
220
221 // OK: typedef to blacklisted type
222 typedef long my_long;
223 CALL_WRITEPARAM(my_long) // OK
224
225 // OK: other types / typedefs
226 CALL_WRITEPARAM(char) // OK
227 CALL_WRITEPARAM(int) // OK
228 CALL_WRITEPARAM(uint32_t) // OK
229 CALL_WRITEPARAM(int64_t) // OK
230
231 // OK: long chain of typedefs, ends up with non-blacklisted typedef
232 {
233 typedef uint32_t my_int_base;
234 typedef const my_int_base my_int;
235 typedef my_int& my_int_ref;
236 my_int_ref p = 0;
237 IPC::WriteParam(nullptr, p); // OK
238 }
239
240 #undef CALL_WRITEPARAM
241 }
242
243 struct Provider {
244 typedef unsigned int flags;
245
246 short get_short() const { return 0; }
247 uint64_t get_uint64() const { return 0; }
248 long get_long() const { return 0; }
249 unsigned int get_uint() const { return 0; }
250 flags get_flags() const { return 0; }
251 size_t get_size() const { return 0; }
252
253 template <class T>
254 T get() const { return 0; }
255
256 short short_data;
257 unsigned int uint_data;
258 flags flags_data;
259 long long_data;
260 size_t size_data;
261 uint64_t uint64_data;
262 };
263
264 void TestWriteParamMemberArgument() {
265 Provider p;
266
267 IPC::WriteParam(nullptr, p.get<short>()); // OK
268 IPC::WriteParam(nullptr, p.get_short()); // OK
269 IPC::WriteParam(nullptr, p.short_data); // OK
270
271 IPC::WriteParam(nullptr, p.get<unsigned int>()); // OK
272 IPC::WriteParam(nullptr, p.get_uint()); // OK
273 IPC::WriteParam(nullptr, p.uint_data); // OK
274
275 IPC::WriteParam(nullptr, p.get<Provider::flags>()); // OK
276 IPC::WriteParam(nullptr, p.get_flags()); // OK
277 IPC::WriteParam(nullptr, p.flags_data); // OK
278
279 IPC::WriteParam(nullptr, p.get<long>()); // ERROR
280 IPC::WriteParam(nullptr, p.get_long()); // ERROR
281 IPC::WriteParam(nullptr, p.long_data); // ERROR
282
283 IPC::WriteParam(nullptr, p.get<size_t>()); // ERROR
284 IPC::WriteParam(nullptr, p.get_size()); // ERROR
285 IPC::WriteParam(nullptr, p.size_data); // ERROR
286
287 // uint64_t is unsigned long, which is blacklisted. Plugin only sees
288 // "unsigned long", and not uint64_t.
289 IPC::WriteParam(nullptr, p.get<uint64_t>()); // ERROR
290 IPC::WriteParam(nullptr, p.get_uint64()); // OK
291 IPC::WriteParam(nullptr, p.uint64_data); // OK
292 }
293
294 #endif
295
296 /* ERRORS: 36 */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698