Skip to content

Commit f9135a5

Browse files
committed
[libc++] Clang-trunk-friendly __libcpp_is_trivially_relocatable<T>
This is not a fully P1144-compliant implementation on Clang trunk; Clang trunk's builtin __is_trivially_relocatable(T) gets at least the following cases wrong: https://p1144.godbolt.org/z/MhncMxrdj However, this patch will minimize the diffs between libc++ trunk and libc++ P1144-branch.
1 parent e74197b commit f9135a5

File tree

6 files changed

+149
-0
lines changed

6 files changed

+149
-0
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ set(files
591591
__type_traits/is_trivially_destructible.h
592592
__type_traits/is_trivially_move_assignable.h
593593
__type_traits/is_trivially_move_constructible.h
594+
__type_traits/is_trivially_relocatable.h
594595
__type_traits/is_unbounded_array.h
595596
__type_traits/is_union.h
596597
__type_traits/is_unsigned.h
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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+
#ifndef _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_RELOCATABLE_H
10+
#define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_RELOCATABLE_H
11+
12+
#include <__config>
13+
#include <__type_traits/integral_constant.h>
14+
#include <__type_traits/is_trivially_destructible.h>
15+
#include <__type_traits/is_trivially_move_constructible.h>
16+
#include <__type_traits/remove_all_extents.h>
17+
18+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19+
# pragma GCC system_header
20+
#endif
21+
22+
_LIBCPP_BEGIN_NAMESPACE_STD
23+
24+
template <class _Tp>
25+
struct _LIBCPP_TEMPLATE_VIS __libcpp_is_trivially_relocatable
26+
: public integral_constant<bool,
27+
#if __has_extension(trivially_relocatable)
28+
__is_trivially_relocatable(_Tp)
29+
#else
30+
is_trivially_move_constructible<typename remove_all_extents<_Tp>::type>::value &&
31+
is_trivially_destructible<typename remove_all_extents<_Tp>::type>::value
32+
#endif
33+
> {};
34+
35+
#if _LIBCPP_STD_VER > 14
36+
template <class _Tp>
37+
inline constexpr bool __libcpp_is_trivially_relocatable_v = __libcpp_is_trivially_relocatable<_Tp>::value;
38+
#endif
39+
40+
_LIBCPP_END_NAMESPACE_STD
41+
42+
#endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_RELOCATABLE_H

libcxx/include/module.modulemap.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,7 @@ module std [system] {
11761176
module is_trivially_destructible { private header "__type_traits/is_trivially_destructible.h" }
11771177
module is_trivially_move_assignable { private header "__type_traits/is_trivially_move_assignable.h" }
11781178
module is_trivially_move_constructible { private header "__type_traits/is_trivially_move_constructible.h" }
1179+
module is_trivially_relocatable { private header "__type_traits/is_trivially_relocatable.h" }
11791180
module is_unbounded_array { private header "__type_traits/is_unbounded_array.h" }
11801181
module is_union { private header "__type_traits/is_union.h" }
11811182
module is_unsigned { private header "__type_traits/is_unsigned.h" }

libcxx/include/type_traits

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ namespace std
503503
#include <__type_traits/is_trivially_destructible.h>
504504
#include <__type_traits/is_trivially_move_assignable.h>
505505
#include <__type_traits/is_trivially_move_constructible.h>
506+
#include <__type_traits/is_trivially_relocatable.h>
506507
#include <__type_traits/is_unbounded_array.h>
507508
#include <__type_traits/is_union.h>
508509
#include <__type_traits/is_unsigned.h>

libcxx/test/libcxx/private_headers.verify.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ END-SCRIPT
603603
#include <__type_traits/is_trivially_destructible.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_trivially_destructible.h'}}
604604
#include <__type_traits/is_trivially_move_assignable.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_trivially_move_assignable.h'}}
605605
#include <__type_traits/is_trivially_move_constructible.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_trivially_move_constructible.h'}}
606+
#include <__type_traits/is_trivially_relocatable.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_trivially_relocatable.h'}}
606607
#include <__type_traits/is_unbounded_array.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_unbounded_array.h'}}
607608
#include <__type_traits/is_union.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_union.h'}}
608609
#include <__type_traits/is_unsigned.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_unsigned.h'}}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is dual licensed under the MIT and the University of Illinois Open
6+
// Source Licenses. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
// type_traits
11+
12+
// __libcpp_is_trivially_relocatable
13+
// __libcpp_is_trivially_relocatable_v
14+
15+
#include <memory>
16+
#include <type_traits>
17+
#include "test_macros.h"
18+
19+
20+
template <class T>
21+
void test_is_trivially_relocatable()
22+
{
23+
static_assert(std::__libcpp_is_trivially_relocatable<T>::value, "");
24+
#if TEST_STD_VER > 14
25+
static_assert(std::__libcpp_is_trivially_relocatable_v<T>, "");
26+
#endif
27+
}
28+
29+
template <class T>
30+
void test_is_not_trivially_relocatable()
31+
{
32+
static_assert(!std::__libcpp_is_trivially_relocatable<T>::value, "");
33+
#if TEST_STD_VER > 14
34+
static_assert(!std::__libcpp_is_trivially_relocatable_v<T>, "");
35+
#endif
36+
}
37+
38+
class Empty {};
39+
40+
class Abstract {
41+
public:
42+
virtual ~Abstract() = 0;
43+
};
44+
45+
class Polymorphic {
46+
public:
47+
virtual ~Polymorphic() = default;
48+
};
49+
50+
union Union {};
51+
52+
struct bit_zero {
53+
int : 0;
54+
};
55+
56+
struct CopyCtor {
57+
CopyCtor(const CopyCtor&);
58+
};
59+
60+
#if TEST_STD_VER >= 11
61+
struct MoveOnly1 {
62+
MoveOnly1(MoveOnly1&&);
63+
};
64+
65+
struct MoveOnly2 {
66+
MoveOnly2(MoveOnly2&&) = default;
67+
};
68+
#endif
69+
70+
int main(int, char**)
71+
{
72+
test_is_not_trivially_relocatable<void>();
73+
test_is_not_trivially_relocatable<const void>();
74+
test_is_not_trivially_relocatable<Abstract>();
75+
test_is_not_trivially_relocatable<Polymorphic>();
76+
test_is_not_trivially_relocatable<CopyCtor>();
77+
78+
test_is_trivially_relocatable<Union>();
79+
test_is_trivially_relocatable<Empty>();
80+
test_is_trivially_relocatable<double>();
81+
test_is_trivially_relocatable<int*>();
82+
test_is_trivially_relocatable<const int*>();
83+
test_is_trivially_relocatable<bit_zero>();
84+
85+
test_is_trivially_relocatable<int>();
86+
test_is_trivially_relocatable<const int>();
87+
test_is_trivially_relocatable<volatile int>();
88+
test_is_trivially_relocatable<const volatile int>();
89+
90+
test_is_trivially_relocatable<int[]>();
91+
test_is_trivially_relocatable<int[10]>();
92+
test_is_trivially_relocatable<int[][2]>();
93+
test_is_trivially_relocatable<int[1][2]>();
94+
95+
#if TEST_STD_VER >= 11
96+
test_is_not_trivially_relocatable<MoveOnly1>();
97+
test_is_not_trivially_relocatable<const MoveOnly1>();
98+
test_is_trivially_relocatable<MoveOnly2>();
99+
test_is_trivially_relocatable<const MoveOnly2>();
100+
#endif
101+
102+
return 0;
103+
}

0 commit comments

Comments
 (0)