Index: tools/clang/plugins/tests/ipc.cpp |
diff --git a/tools/clang/plugins/tests/ipc.cpp b/tools/clang/plugins/tests/ipc.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1a0dee158c16fb6f9f33691ad3c902cf3c76a5e9 |
--- /dev/null |
+++ b/tools/clang/plugins/tests/ipc.cpp |
@@ -0,0 +1,158 @@ |
+// Copyright (c) 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+typedef __SIZE_TYPE__ size_t; // BAD type |
+typedef __SIZE_TYPE__ uint64_t; // GOOD type |
+ |
+namespace IPC { |
+ class Message {}; |
+ |
+ // ParamTuple |
+ |
+ template <class F, class... T> |
+ struct ParamTupleValue { |
+ typedef F Type; |
+ }; |
+ |
+ template <class... T> |
+ struct ParamTuple { |
+ typename ParamTupleValue<T...>::Type value; |
+ }; |
+ |
+ // ParamTraits & WriteParam |
+ |
+ template <class T> |
+ struct ParamTraits { |
+ static void Write(Message* m, const T&) {} |
+ }; |
+ |
+ template <class T> |
+ void WriteParam(Message* m, const T& value) { |
+ ParamTraits<T>::Write(m, value); |
+ } |
+ |
+ // ParamTraits specializations |
+ |
+ template <class... T> |
+ struct ParamTraits<ParamTuple<T...>> { |
+ static void Write(Message* m, const ParamTuple<T...>& tuple) { |
+ WriteParam(m, tuple.value); |
+ } |
+ }; |
+ |
+ template <> |
+ struct ParamTraits<unsigned long> { |
+ static void Write(Message* m, const unsigned long&) {} |
+ }; |
+} |
+ |
+struct SomeStruct { |
+ int field1; |
+ size_t field2; |
+ __SIZE_TYPE__ field3; |
+}; |
+ |
+template <> |
+struct IPC::ParamTraits<SomeStruct> { |
+ static void Write(Message* m, const SomeStruct& value) { |
+ WriteParam(m, value.field1); |
+ |
+ // ERROR: WriteParam called on size_t |
+ WriteParam(m, value.field2); |
+ |
+ // OK: WriteParam is called on something that is not size_t even if |
+ // it's equivalent to size_t |
+ // TODO: require typedef, error on plain __SIZE_TYPE__ |
+ WriteParam(m, value.field3); |
+ } |
+}; |
+ |
+template <class T> |
+struct Container { |
+ T value; |
+}; |
+ |
+template <class T> |
+struct IPC::ParamTraits<Container<T>> { |
+ static void Write(Message* m, const Container<T>& container) { |
+ WriteParam(m, container.value); |
+ } |
+}; |
+ |
+template <class T> |
+struct Container2 { |
+ T value; |
+}; |
+ |
+typedef __SIZE_TYPE__ Payload; |
+ |
+template <> |
+struct IPC::ParamTraits<Container2<Payload>> { |
+ static void Write(Message* m, const Container2<Payload>& container) { |
+ WriteParam(m, container.value); |
+ } |
+}; |
+ |
+template <class T> |
+void CallWriteParam(IPC::Message* m, const T& value) { |
+ IPC::WriteParam(m, value); |
+} |
+ |
+int main() { |
+ { |
+ // ERROR: WriteParam called on size_t |
+ size_t p = 0; |
+ IPC::WriteParam(nullptr, p); |
+ } |
+ { |
+ // ERROR: size_t used somewhere in WriteParam invocation, and resulting |
+ // type is equivalent to size_t |
+ size_t p = 0; |
+ IPC::WriteParam(nullptr, p + static_cast<uint64_t>(1)); |
+ } |
+ { |
+ // OK: WriteParam called on something that is not size_t, even though |
+ // its type is equivalent to size_t |
+ uint64_t p = 0; |
+ IPC::WriteParam(nullptr, p); |
+ } |
+ |
+ { |
+ // ERROR: WriteParam called from an implicit template instantiation with |
+ // a type equivalent to size_t |
+ Container<uint64_t> p; |
+ IPC::WriteParam(nullptr, p); |
+ } |
+ { |
+ // ERROR: same as above, but from a function |
+ size_t p = 0; |
+ CallWriteParam(nullptr, p); |
+ } |
+ { |
+ // OK: It's fine to call WriteParam on something equivalent to size_t in |
+ // explicit template instantiations |
+ // TODO: require explicit WriteParam instantiation with a typedef |
+ Container2<Payload> value; |
+ IPC::WriteParam(nullptr, value); |
+ } |
+ |
+ { |
+ // ERROR: ParamTuple specialized with size_t |
+ typedef IPC::ParamTuple<size_t, char, bool> Params; |
+ } |
+ { |
+ // ERROR: ParamTuple specialized with a typedef to size_t |
+ typedef volatile size_t size_type; |
+ IPC::ParamTuple<size_type, char, bool> params; |
+ } |
+ { |
+ // OK: ParamTuple specialized with something equivalent to size_t |
+ IPC::ParamTuple<uint64_t, char, bool> params; |
+ } |
+ { |
+ // OK: ParamTuple specialized with something equivalent to size_t |
+ // TODO: error in this case, demand typedef |
+ IPC::ParamTuple<__SIZE_TYPE__, char, bool> params; |
+ } |
+} |