The table head of test freshness page should not scroll with the page.
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WTF / PoisonedUniquePtrForTriviallyDestructibleArrays.cpp
1 /*
2  * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #include <mutex>
29 #include <wtf/FastMalloc.h>
30 #include <wtf/PoisonedUniquePtr.h>
31
32 namespace TestWebKitAPI {
33
34 namespace {
35
36 uintptr_t g_poisonA;
37 uintptr_t g_poisonB;
38
39 using PoisonA = Poison<g_poisonA>;
40 using PoisonB = Poison<g_poisonB>;
41
42 static void initializePoisons()
43 {
44     static std::once_flag initializeOnceFlag;
45     std::call_once(initializeOnceFlag, [] {
46         // Make sure we get 2 different poison values.
47         g_poisonA = makePoison();
48         while (!g_poisonB || g_poisonB == g_poisonA)
49             g_poisonB = makePoison();
50     });
51 }
52
53 template<typename T>
54 static void fillArray(T& array, int size)
55 {
56     for (int i = 0; i < size; ++i)
57         array[i] = i + 100;
58 }
59
60 static const int arraySize = 5;
61
62 } // anonymous namespace
63
64 TEST(WTF_PoisonedUniquePtrForTriviallyDestructibleArrays, DISABLED_Basic)
65 {
66     initializePoisons();
67
68     {
69         PoisonedUniquePtr<PoisonA, int[]> empty;
70         ASSERT_EQ(nullptr, empty.unpoisoned());
71         ASSERT_EQ(0u, empty.bits());
72     }
73     {
74         PoisonedUniquePtr<PoisonA, int[]> empty(nullptr);
75         ASSERT_EQ(nullptr, empty.unpoisoned());
76         ASSERT_EQ(0u, empty.bits());
77     }
78
79     {
80         auto* a = new int[arraySize];
81         fillArray(a, arraySize);
82         {
83             PoisonedUniquePtr<PoisonA, int[]> ptr(a);
84             ASSERT_EQ(a, ptr.unpoisoned());
85             ASSERT_EQ(a, &*ptr);
86             for (auto i = 0; i < arraySize; ++i)
87                 ASSERT_EQ(a[i], ptr[i]);
88
89 #if ENABLE(POISON)
90             uintptr_t ptrBits;
91             std::memcpy(&ptrBits, &ptr, sizeof(ptrBits));
92             ASSERT_TRUE(ptrBits != bitwise_cast<uintptr_t>(a));
93 #if ENABLE(POISON_ASSERTS)
94             ASSERT_TRUE((PoisonedUniquePtr<PoisonA, int[]>::isPoisoned(ptrBits)));
95 #endif
96 #endif // ENABLE(POISON)
97         }
98     }
99
100     {
101         auto* a = new int[arraySize];
102         fillArray(a, arraySize);
103
104         PoisonedUniquePtr<PoisonA, int[]> ptr = a;
105         ASSERT_EQ(a, ptr.unpoisoned());
106         ASSERT_EQ(a, &*ptr);
107         for (auto i = 0; i < arraySize; ++i)
108             ASSERT_EQ(a[i], ptr[i]);
109     }
110
111     {
112         PoisonedUniquePtr<PoisonA, int[]> ptr = PoisonedUniquePtr<PoisonA, int[]>::create(arraySize);
113         ASSERT_TRUE(nullptr != ptr.unpoisoned());
114         fillArray(ptr, arraySize);
115         for (auto i = 0; i < arraySize; ++i)
116             ASSERT_EQ((100 + i), ptr[i]);
117     }
118
119     {
120         auto* a = new int[arraySize];
121         fillArray(a, arraySize);
122         auto* b = new int[arraySize];
123         fillArray(b, arraySize);
124
125         PoisonedUniquePtr<PoisonA, int[]> p1 = a;
126         PoisonedUniquePtr<PoisonA, int[]> p2 = WTFMove(p1);
127         ASSERT_EQ(nullptr, p1.unpoisoned());
128         ASSERT_EQ(0u, p1.bits());
129         ASSERT_EQ(a, p2.unpoisoned());
130         for (auto i = 0; i < arraySize; ++i)
131             ASSERT_EQ(a[i], p2[i]);
132
133         PoisonedUniquePtr<PoisonA, int[]> p3 = b;
134         PoisonedUniquePtr<PoisonB, int[]> p4 = WTFMove(p3);
135         ASSERT_EQ(nullptr, p3.unpoisoned());
136         ASSERT_EQ(0u, p3.bits());
137         ASSERT_EQ(b, p4.unpoisoned());
138         for (auto i = 0; i < arraySize; ++i)
139             ASSERT_EQ(b[i], p4[i]);
140     }
141
142     {
143         auto* a = new int[arraySize];
144         fillArray(a, arraySize);
145         auto* b = new int[arraySize];
146         fillArray(b, arraySize);
147
148         PoisonedUniquePtr<PoisonA, int[]> p1 = a;
149         PoisonedUniquePtr<PoisonA, int[]> p2(WTFMove(p1));
150         ASSERT_EQ(nullptr, p1.unpoisoned());
151         ASSERT_EQ(0u, p1.bits());
152         ASSERT_EQ(a, p2.unpoisoned());
153         for (auto i = 0; i < arraySize; ++i)
154             ASSERT_EQ(a[i], p2[i]);
155
156         PoisonedUniquePtr<PoisonA, int[]> p3 = b;
157         PoisonedUniquePtr<PoisonB, int[]> p4(WTFMove(p3));
158         ASSERT_EQ(nullptr, p3.unpoisoned());
159         ASSERT_EQ(0u, p3.bits());
160         ASSERT_EQ(b, p4.unpoisoned());
161         for (auto i = 0; i < arraySize; ++i)
162             ASSERT_EQ(b[i], p4[i]);
163     }
164
165     {
166         auto* a = new int[arraySize];
167         fillArray(a, arraySize);
168
169         PoisonedUniquePtr<PoisonA, int[]> ptr(a);
170         ASSERT_EQ(a, ptr.unpoisoned());
171         ptr.clear();
172         ASSERT_TRUE(!ptr.unpoisoned());
173         ASSERT_TRUE(!ptr.bits());
174     }
175 }
176
177 TEST(WTF_PoisonedUniquePtrForTriviallyDestructibleArrays, DISABLED_Assignment)
178 {
179     initializePoisons();
180
181     {
182         auto* a = new int[arraySize];
183         auto* b = new int[arraySize];
184         fillArray(a, arraySize);
185         fillArray(b, arraySize);
186
187         PoisonedUniquePtr<PoisonA, int[]> ptr(a);
188         ASSERT_EQ(a, ptr.unpoisoned());
189         ptr = b;
190         ASSERT_EQ(b, ptr.unpoisoned());
191     }
192
193     {
194         auto* a = new int[arraySize];
195         fillArray(a, arraySize);
196
197         PoisonedUniquePtr<PoisonA, int[]> ptr(a);
198         ASSERT_EQ(a, ptr.unpoisoned());
199         ptr = nullptr;
200         ASSERT_EQ(nullptr, ptr.unpoisoned());
201     }
202
203     {
204         auto* a = new int[arraySize];
205         auto* b = new int[arraySize];
206         auto* c = new int[arraySize];
207         auto* d = new int[arraySize];
208         fillArray(a, arraySize);
209         fillArray(b, arraySize);
210         fillArray(c, arraySize);
211         fillArray(d, arraySize);
212
213         PoisonedUniquePtr<PoisonA, int[]> p1(a);
214         PoisonedUniquePtr<PoisonA, int[]> p2(b);
215         ASSERT_EQ(a, p1.unpoisoned());
216         ASSERT_EQ(b, p2.unpoisoned());
217         p1 = WTFMove(p2);
218         ASSERT_EQ(b, p1.unpoisoned());
219         ASSERT_EQ(nullptr, p2.unpoisoned());
220
221         PoisonedUniquePtr<PoisonA, int[]> p3(c);
222         PoisonedUniquePtr<PoisonB, int[]> p4(d);
223         ASSERT_EQ(c, p3.unpoisoned());
224         ASSERT_EQ(d, p4.unpoisoned());
225         p3 = WTFMove(p4);
226         ASSERT_EQ(d, p3.unpoisoned());
227         ASSERT_EQ(nullptr, p4.unpoisoned());
228     }
229
230     {
231         auto* a = new int[arraySize];
232         fillArray(a, arraySize);
233
234         PoisonedUniquePtr<PoisonA, int[]> ptr(a);
235         ASSERT_EQ(a, ptr.unpoisoned());
236         ptr = a;
237         ASSERT_EQ(a, ptr.unpoisoned());
238     }
239
240     {
241         auto* a = new int[arraySize];
242         fillArray(a, arraySize);
243
244         PoisonedUniquePtr<PoisonA, int[]> ptr(a);
245         ASSERT_EQ(a, ptr.unpoisoned());
246 #if COMPILER(CLANG)
247 #pragma clang diagnostic push
248 #pragma clang diagnostic ignored "-Wunknown-pragmas"
249 #pragma clang diagnostic ignored "-Wself-move"
250 #endif
251         ptr = WTFMove(ptr);
252 #if COMPILER(CLANG)
253 #pragma clang diagnostic pop
254 #endif
255         ASSERT_EQ(a, ptr.unpoisoned());
256     }
257 }
258
259 TEST(WTF_PoisonedUniquePtrForTriviallyDestructibleArrays, DISABLED_Swap)
260 {
261     initializePoisons();
262
263     {
264         auto* a = new int[arraySize];
265         auto* b = new int[arraySize];
266         fillArray(a, arraySize);
267         fillArray(b, arraySize);
268
269         PoisonedUniquePtr<PoisonA, int[]> p1 = a;
270         PoisonedUniquePtr<PoisonA, int[]> p2;
271         ASSERT_EQ(p1.unpoisoned(), a);
272         ASSERT_TRUE(!p2.bits());
273         ASSERT_TRUE(!p2.unpoisoned());
274         p2.swap(p1);
275         ASSERT_TRUE(!p1.bits());
276         ASSERT_TRUE(!p1.unpoisoned());
277         ASSERT_EQ(p2.unpoisoned(), a);
278
279         PoisonedUniquePtr<PoisonA, int[]> p3 = b;
280         PoisonedUniquePtr<PoisonB, int[]> p4;
281         ASSERT_EQ(p3.unpoisoned(), b);
282         ASSERT_TRUE(!p4.bits());
283         ASSERT_TRUE(!p4.unpoisoned());
284         p4.swap(p3);
285         ASSERT_TRUE(!p3.bits());
286         ASSERT_TRUE(!p3.unpoisoned());
287         ASSERT_EQ(p4.unpoisoned(), b);
288     }
289
290     {
291         auto* a = new int[arraySize];
292         auto* b = new int[arraySize];
293         fillArray(a, arraySize);
294         fillArray(b, arraySize);
295
296         PoisonedUniquePtr<PoisonA, int[]> p1 = a;
297         PoisonedUniquePtr<PoisonA, int[]> p2;
298         ASSERT_EQ(p1.unpoisoned(), a);
299         ASSERT_TRUE(!p2.bits());
300         ASSERT_TRUE(!p2.unpoisoned());
301         swap(p1, p2);
302         ASSERT_TRUE(!p1.bits());
303         ASSERT_TRUE(!p1.unpoisoned());
304         ASSERT_EQ(p2.unpoisoned(), a);
305
306         PoisonedUniquePtr<PoisonA, int[]> p3 = b;
307         PoisonedUniquePtr<PoisonB, int[]> p4;
308         ASSERT_EQ(p3.unpoisoned(), b);
309         ASSERT_TRUE(!p4.bits());
310         ASSERT_TRUE(!p4.unpoisoned());
311         swap(p3, p4);
312         ASSERT_TRUE(!p3.bits());
313         ASSERT_TRUE(!p3.unpoisoned());
314         ASSERT_EQ(p4.unpoisoned(), b);
315     }
316 }
317
318 static PoisonedUniquePtr<PoisonA, int[]> poisonedPtrFoo(int* ptr)
319 {
320     return PoisonedUniquePtr<PoisonA, int[]>(ptr);
321 }
322
323 TEST(WTF_PoisonedUniquePtrForTriviallyDestructibleArrays, DISABLED_ReturnValue)
324 {
325     initializePoisons();
326
327     {
328         auto* a = new int[arraySize];
329         fillArray(a, arraySize);
330
331         auto ptr = poisonedPtrFoo(a);
332         ASSERT_EQ(a, ptr.unpoisoned());
333         ASSERT_EQ(a, &*ptr);
334         for (auto i = 0; i < arraySize; ++i)
335             ASSERT_EQ(a[i], ptr[i]);
336     }
337 }
338
339 } // namespace TestWebKitAPI
340