1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <cstddef>
10 #include <type_traits>
11 #include <cassert>
12 
13 #include "test_macros.h"
14 
15 // typedef decltype(nullptr) nullptr_t;
16 
17 struct A
18 {
AA19     A(std::nullptr_t) {}
20 };
21 
22 template <class T>
test_conversions()23 void test_conversions()
24 {
25     {
26         T p = 0;
27         assert(p == nullptr);
28     }
29     {
30         T p = nullptr;
31         assert(p == nullptr);
32         assert(nullptr == p);
33         assert(!(p != nullptr));
34         assert(!(nullptr != p));
35     }
36 }
37 
38 template <class T> struct Voider { typedef void type; };
39 template <class T, class = void> struct has_less : std::false_type {};
40 
41 template <class T> struct has_less<T,
42     typename Voider<decltype(std::declval<T>() < nullptr)>::type> : std::true_type {};
43 
44 template <class T>
test_comparisons()45 void test_comparisons()
46 {
47     T p = nullptr;
48     assert(p == nullptr);
49     assert(!(p != nullptr));
50     assert(nullptr == p);
51     assert(!(nullptr != p));
52 }
53 
54 #if defined(__clang__)
55 #pragma clang diagnostic push
56 #pragma clang diagnostic ignored "-Wnull-conversion"
57 #endif
test_nullptr_conversions()58 void test_nullptr_conversions() {
59     {
60         bool b(nullptr);
61         assert(!b);
62     }
63 }
64 #if defined(__clang__)
65 #pragma clang diagnostic pop
66 #endif
67 
68 
main(int,char **)69 int main(int, char**)
70 {
71     static_assert(sizeof(std::nullptr_t) == sizeof(void*),
72                   "sizeof(std::nullptr_t) == sizeof(void*)");
73 
74     {
75         test_conversions<std::nullptr_t>();
76         test_conversions<void*>();
77         test_conversions<A*>();
78         test_conversions<void(*)()>();
79         test_conversions<void(A::*)()>();
80         test_conversions<int A::*>();
81     }
82     {
83 #ifdef _LIBCPP_HAS_NO_NULLPTR
84         static_assert(!has_less<std::nullptr_t>::value, "");
85         // FIXME: our C++03 nullptr emulation still allows for comparisons
86         // with other pointer types by way of the conversion operator.
87         //static_assert(!has_less<void*>::value, "");
88 #else
89         // TODO Enable this assertion when all compilers implement core DR 583.
90         // static_assert(!has_less<std::nullptr_t>::value, "");
91 #endif
92         test_comparisons<std::nullptr_t>();
93         test_comparisons<void*>();
94         test_comparisons<A*>();
95         test_comparisons<void(*)()>();
96     }
97     test_nullptr_conversions();
98 
99   return 0;
100 }
101