1 // Copyright 2014 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.
5 #include "mojo/system/memory.h"
12 #include "mojo/public/c/system/macros.h"
13 #include "testing/gtest/include/gtest/gtest.h"
19 TEST(MemoryTest, Valid) {
22 int64_t my_int64_array[5] = {}; // Zero initialize.
24 UserPointer<char> my_char_ptr(&my_char);
25 UserPointer<int32_t> my_int32_ptr(&my_int32);
26 UserPointer<int64_t> my_int64_array_ptr(my_int64_array);
28 // |UserPointer<>::IsNull()|:
29 EXPECT_FALSE(my_char_ptr.IsNull());
30 EXPECT_FALSE(my_int32_ptr.IsNull());
31 EXPECT_FALSE(my_int64_array_ptr.IsNull());
33 // |UserPointer<>::Put()| and |UserPointer<>::Get()|:
35 EXPECT_EQ('x', my_char);
36 EXPECT_EQ('x', my_char_ptr.Get());
37 my_int32_ptr.Put(123);
38 EXPECT_EQ(123, my_int32);
39 EXPECT_EQ(123, my_int32_ptr.Get());
40 my_int64_array_ptr.Put(456);
41 EXPECT_EQ(456, my_int64_array[0]);
42 EXPECT_EQ(456, my_int64_array_ptr.Get());
44 // |UserPointer<>::At()|, etc.:
45 my_int64_array_ptr.At(3).Put(789);
46 EXPECT_EQ(789, my_int64_array[3]);
49 UserPointer<int64_t> other(my_int64_array_ptr.At(3));
50 EXPECT_FALSE(other.IsNull());
51 EXPECT_EQ(789, other.Get());
54 other = my_int64_array_ptr;
55 EXPECT_FALSE(other.IsNull());
56 EXPECT_EQ(456, other.Get());
58 // Assignment to |NullUserPointer()|:
59 other = NullUserPointer();
60 EXPECT_TRUE(other.IsNull());
62 // |MakeUserPointer()|:
63 other = MakeUserPointer(&my_int64_array[1]);
65 EXPECT_EQ(-123, my_int64_array_ptr.At(1).Get());
68 // "const" |UserPointer<>|:
70 // Explicit constructor from |NullUserPointer()|:
71 UserPointer<const char> other((NullUserPointer()));
72 EXPECT_TRUE(other.IsNull());
74 // Conversion to "const":
76 EXPECT_EQ('x', other.Get());
79 // Default constructor:
81 UserPointer<int32_t> other;
82 EXPECT_TRUE(other.IsNull());
86 EXPECT_EQ(-456, my_int32_ptr.Get());
89 // |UserPointer<>::CheckArray()|:
90 my_int64_array_ptr.CheckArray(5);
92 // |UserPointer<>::GetArray()|:
94 // From a "const" |UserPointer<>| (why not?):
95 UserPointer<const int64_t> other(my_int64_array_ptr);
96 int64_t array[3] = {1, 2, 3};
97 other.At(1).GetArray(array, 3);
98 EXPECT_EQ(-123, array[0]);
99 EXPECT_EQ(0, array[1]);
100 EXPECT_EQ(789, array[2]);
103 // |UserPointer<>::PutArray()|:
105 const int64_t array[2] = {654, 321};
106 my_int64_array_ptr.At(3).PutArray(array, 2);
107 EXPECT_EQ(0, my_int64_array[2]);
108 EXPECT_EQ(654, my_int64_array[3]);
109 EXPECT_EQ(321, my_int64_array[4]);
112 // |UserPointer<>::Reader|:
114 UserPointer<int64_t>::Reader reader(my_int64_array_ptr, 5);
115 EXPECT_EQ(456, reader.GetPointer()[0]);
116 EXPECT_EQ(321, reader.GetPointer()[4]);
119 // Non-const to const:
121 UserPointer<const int64_t>::Reader reader(my_int64_array_ptr.At(3), 1);
122 const int64_t* ptr = reader.GetPointer();
123 EXPECT_EQ(654, *ptr);
126 // |UserPointer<>::Writer|:
128 UserPointer<int64_t>::Writer writer(my_int64_array_ptr.At(2), 1);
129 int64_t* ptr = writer.GetPointer();
130 *ptr = 1234567890123LL;
132 EXPECT_EQ(1234567890123LL, my_int64_array[2]);
135 // |UserPointer<>::ReaderWriter|:
137 UserPointer<int32_t>::ReaderWriter reader_writer(my_int32_ptr, 1);
138 int32_t* ptr = reader_writer.GetPointer();
139 EXPECT_EQ(-456, *ptr);
141 reader_writer.Commit();
142 EXPECT_EQ(42, my_int32);
145 // |UserPointer<>::ReinterpretCast<>|:
146 // (This assumes little-endian, etc.)
148 UserPointer<const char> other(my_int32_ptr.ReinterpretCast<char>());
149 EXPECT_EQ(42, other.Get());
150 EXPECT_EQ(0, other.At(1).Get());
151 EXPECT_EQ(0, other.At(2).Get());
152 EXPECT_EQ(0, other.At(3).Get());
155 // |UserPointer<>::GetPointerValue()|:
157 UserPointer<int32_t> other;
158 EXPECT_EQ(0u, other.GetPointerValue());
159 other = my_int32_ptr;
160 EXPECT_EQ(reinterpret_cast<uintptr_t>(&my_int32), other.GetPointerValue());
164 TEST(MemoryTest, InvalidDeath) {
165 const char kMemoryCheckFailedRegex[] = "Check failed";
167 // Note: |Check...()| are defined to be "best effort" checks (and may always
168 // return true). Thus these tests of invalid cases only reflect the current
171 // These tests depend on |int32_t| and |int64_t| having nontrivial alignment.
172 static_assert(MOJO_ALIGNOF(int32_t) != 1,
173 "int32_t does not require nontrivial alignment");
174 static_assert(MOJO_ALIGNOF(int64_t) != 1,
175 "int64_t does not require nontrivial alignment");
179 UserPointer<char> ptr(nullptr);
181 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex);
182 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex);
183 EXPECT_DEATH_IF_SUPPORTED(ptr.Put('x'), kMemoryCheckFailedRegex);
184 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex);
185 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex);
186 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex);
189 UserPointer<int32_t> ptr(nullptr);
190 int32_t array[5] = {};
191 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex);
192 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex);
193 EXPECT_DEATH_IF_SUPPORTED(ptr.Put(123), kMemoryCheckFailedRegex);
194 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex);
195 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex);
196 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex);
199 UserPointer<int64_t> ptr(nullptr);
200 int64_t array[5] = {};
201 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex);
202 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex);
203 EXPECT_DEATH_IF_SUPPORTED(ptr.Put(123), kMemoryCheckFailedRegex);
204 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex);
205 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex);
206 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex);
208 // Also check a const pointer:
210 UserPointer<const int32_t> ptr(nullptr);
211 int32_t array[5] = {};
212 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex);
213 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex);
214 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex);
215 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex);
221 UserPointer<int32_t> ptr(
222 reinterpret_cast<int32_t*>(reinterpret_cast<uintptr_t>(x) + 1));
223 int32_t array[5] = {};
224 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex);
225 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex);
226 EXPECT_DEATH_IF_SUPPORTED(ptr.Put(123), kMemoryCheckFailedRegex);
227 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex);
228 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex);
229 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex);
233 UserPointer<int64_t> ptr(
234 reinterpret_cast<int64_t*>(reinterpret_cast<uintptr_t>(x) + 1));
235 int64_t array[5] = {};
236 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex);
237 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex);
238 EXPECT_DEATH_IF_SUPPORTED(ptr.Put(123), kMemoryCheckFailedRegex);
239 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex);
240 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex);
241 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex);
243 // Also check a const pointer:
246 UserPointer<const int32_t> ptr(
247 reinterpret_cast<const int32_t*>(reinterpret_cast<uintptr_t>(x) + 1));
248 int32_t array[5] = {};
249 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex);
250 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex);
251 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex);
252 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex);
257 const size_t kTooBig =
258 std::numeric_limits<size_t>::max() / sizeof(int32_t) + 1;
260 UserPointer<int32_t> ptr(&x);
261 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(kTooBig), kMemoryCheckFailedRegex);
262 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(&x, kTooBig),
263 kMemoryCheckFailedRegex);
264 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(&x, kTooBig),
265 kMemoryCheckFailedRegex);
268 const size_t kTooBig =
269 std::numeric_limits<size_t>::max() / sizeof(int64_t) + 1;
271 UserPointer<int64_t> ptr(&x);
272 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(kTooBig), kMemoryCheckFailedRegex);
273 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(&x, kTooBig),
274 kMemoryCheckFailedRegex);
275 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(&x, kTooBig),
276 kMemoryCheckFailedRegex);
278 // Also check a const pointer:
280 const size_t kTooBig =
281 std::numeric_limits<size_t>::max() / sizeof(int32_t) + 1;
283 UserPointer<const int32_t> ptr(&x);
284 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(kTooBig), kMemoryCheckFailedRegex);
285 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(&x, kTooBig),
286 kMemoryCheckFailedRegex);
289 // TODO(vtl): Tests for |UserPointer{Reader,Writer,ReaderWriter}|.
293 } // namespace system