OLD | NEW |
(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 typedef __SIZE_TYPE__ size_t; // BAD type |
| 6 typedef __SIZE_TYPE__ uint64_t; // GOOD type |
| 7 |
| 8 namespace IPC { |
| 9 class Message {}; |
| 10 |
| 11 // ParamTuple |
| 12 |
| 13 template <class F, class... T> |
| 14 struct ParamTupleValue { |
| 15 typedef F Type; |
| 16 }; |
| 17 |
| 18 template <class... T> |
| 19 struct ParamTuple { |
| 20 typename ParamTupleValue<T...>::Type value; |
| 21 }; |
| 22 |
| 23 // ParamTraits & WriteParam |
| 24 |
| 25 template <class T> |
| 26 struct ParamTraits { |
| 27 static void Write(Message* m, const T&) {} |
| 28 }; |
| 29 |
| 30 template <class T> |
| 31 void WriteParam(Message* m, const T& value) { |
| 32 ParamTraits<T>::Write(m, value); |
| 33 } |
| 34 |
| 35 // ParamTraits specializations |
| 36 |
| 37 template <class... T> |
| 38 struct ParamTraits<ParamTuple<T...>> { |
| 39 static void Write(Message* m, const ParamTuple<T...>& tuple) { |
| 40 WriteParam(m, tuple.value); |
| 41 } |
| 42 }; |
| 43 |
| 44 template <> |
| 45 struct ParamTraits<unsigned long> { |
| 46 static void Write(Message* m, const unsigned long&) {} |
| 47 }; |
| 48 } |
| 49 |
| 50 struct SomeStruct { |
| 51 int field1; |
| 52 size_t field2; |
| 53 __SIZE_TYPE__ field3; |
| 54 }; |
| 55 |
| 56 template <> |
| 57 struct IPC::ParamTraits<SomeStruct> { |
| 58 static void Write(Message* m, const SomeStruct& value) { |
| 59 WriteParam(m, value.field1); |
| 60 |
| 61 // ERROR: WriteParam called on size_t |
| 62 WriteParam(m, value.field2); |
| 63 |
| 64 // OK: WriteParam is called on something that is not size_t even if |
| 65 // it's equivalent to size_t |
| 66 // TODO: require typedef, error on plain __SIZE_TYPE__ |
| 67 WriteParam(m, value.field3); |
| 68 } |
| 69 }; |
| 70 |
| 71 template <class T> |
| 72 struct Container { |
| 73 T value; |
| 74 }; |
| 75 |
| 76 template <class T> |
| 77 struct IPC::ParamTraits<Container<T>> { |
| 78 static void Write(Message* m, const Container<T>& container) { |
| 79 WriteParam(m, container.value); |
| 80 } |
| 81 }; |
| 82 |
| 83 template <class T> |
| 84 struct Container2 { |
| 85 T value; |
| 86 }; |
| 87 |
| 88 typedef __SIZE_TYPE__ Payload; |
| 89 |
| 90 template <> |
| 91 struct IPC::ParamTraits<Container2<Payload>> { |
| 92 static void Write(Message* m, const Container2<Payload>& container) { |
| 93 WriteParam(m, container.value); |
| 94 } |
| 95 }; |
| 96 |
| 97 template <class T> |
| 98 void CallWriteParam(IPC::Message* m, const T& value) { |
| 99 IPC::WriteParam(m, value); |
| 100 } |
| 101 |
| 102 int main() { |
| 103 { |
| 104 // ERROR: WriteParam called on size_t |
| 105 size_t p = 0; |
| 106 IPC::WriteParam(nullptr, p); |
| 107 } |
| 108 { |
| 109 // ERROR: size_t used somewhere in WriteParam invocation, and resulting |
| 110 // type is equivalent to size_t |
| 111 size_t p = 0; |
| 112 IPC::WriteParam(nullptr, p + static_cast<uint64_t>(1)); |
| 113 } |
| 114 { |
| 115 // OK: WriteParam called on something that is not size_t, even though |
| 116 // its type is equivalent to size_t |
| 117 uint64_t p = 0; |
| 118 IPC::WriteParam(nullptr, p); |
| 119 } |
| 120 |
| 121 { |
| 122 // ERROR: WriteParam called from an implicit template instantiation with |
| 123 // a type equivalent to size_t |
| 124 Container<uint64_t> p; |
| 125 IPC::WriteParam(nullptr, p); |
| 126 } |
| 127 { |
| 128 // ERROR: same as above, but from a function |
| 129 size_t p = 0; |
| 130 CallWriteParam(nullptr, p); |
| 131 } |
| 132 { |
| 133 // OK: It's fine to call WriteParam on something equivalent to size_t in |
| 134 // explicit template instantiations |
| 135 // TODO: require explicit WriteParam instantiation with a typedef |
| 136 Container2<Payload> value; |
| 137 IPC::WriteParam(nullptr, value); |
| 138 } |
| 139 |
| 140 { |
| 141 // ERROR: ParamTuple specialized with size_t |
| 142 typedef IPC::ParamTuple<size_t, char, bool> Params; |
| 143 } |
| 144 { |
| 145 // ERROR: ParamTuple specialized with a typedef to size_t |
| 146 typedef volatile size_t size_type; |
| 147 IPC::ParamTuple<size_type, char, bool> params; |
| 148 } |
| 149 { |
| 150 // OK: ParamTuple specialized with something equivalent to size_t |
| 151 IPC::ParamTuple<uint64_t, char, bool> params; |
| 152 } |
| 153 { |
| 154 // OK: ParamTuple specialized with something equivalent to size_t |
| 155 // TODO: error in this case, demand typedef |
| 156 IPC::ParamTuple<__SIZE_TYPE__, char, bool> params; |
| 157 } |
| 158 } |
OLD | NEW |