| 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;
|
| + }
|
| +}
|
|
|