Skip to content

Commit 347d4d7

Browse files
[ADT] Fix Optional<> with llvm::is_trivially_move_constructible
Fix the compatibility of Optional<> with some GCC versions that it will fail to compile when T is getting checked for `is_trivially_move_constructible` as mentioned here: https://reviews.llvm.org/D93510#2538983 Fix the problem by using `llvm::is_trivially_move_constructible`. Reviewed By: jplayer-nv, tatyana-krasnukha Differential Revision: https://reviews.llvm.org/D117254
1 parent f5ff1ca commit 347d4d7

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

llvm/include/llvm/ADT/Optional.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ namespace optional_detail {
3434
/// Storage for any type.
3535
//
3636
// The specialization condition intentionally uses
37-
// llvm::is_trivially_copy_constructible instead of
38-
// std::is_trivially_copy_constructible. GCC versions prior to 7.4 may
39-
// instantiate the copy constructor of `T` when
40-
// std::is_trivially_copy_constructible is instantiated. This causes
41-
// compilation to fail if we query the trivially copy constructible property of
42-
// a class which is not copy constructible.
37+
// llvm::is_trivially_{copy/move}_constructible instead of
38+
// std::is_trivially_{copy/move}_constructible. GCC versions prior to 7.4 may
39+
// instantiate the copy/move constructor of `T` when
40+
// std::is_trivially_{copy/move}_constructible is instantiated. This causes
41+
// compilation to fail if we query the trivially copy/move constructible
42+
// property of a class which is not copy/move constructible.
4343
//
4444
// The current implementation of OptionalStorage insists that in order to use
4545
// the trivial specialization, the value_type must be trivially copy
@@ -50,12 +50,13 @@ namespace optional_detail {
5050
//
5151
// The move constructible / assignable conditions emulate the remaining behavior
5252
// of std::is_trivially_copyable.
53-
template <typename T, bool = (llvm::is_trivially_copy_constructible<T>::value &&
54-
std::is_trivially_copy_assignable<T>::value &&
55-
(std::is_trivially_move_constructible<T>::value ||
56-
!std::is_move_constructible<T>::value) &&
57-
(std::is_trivially_move_assignable<T>::value ||
58-
!std::is_move_assignable<T>::value))>
53+
template <typename T,
54+
bool = (llvm::is_trivially_copy_constructible<T>::value &&
55+
std::is_trivially_copy_assignable<T>::value &&
56+
(llvm::is_trivially_move_constructible<T>::value ||
57+
!std::is_move_constructible<T>::value) &&
58+
(std::is_trivially_move_assignable<T>::value ||
59+
!std::is_move_assignable<T>::value))>
5960
class OptionalStorage {
6061
union {
6162
char empty;

llvm/unittests/ADT/OptionalTest.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,4 +805,15 @@ TEST(OptionalTest, HashValue) {
805805
EXPECT_EQ(hash_value(B), hash_value(I));
806806
}
807807

808+
struct NotTriviallyCopyable {
809+
NotTriviallyCopyable(); // Constructor out-of-line.
810+
virtual ~NotTriviallyCopyable() = default;
811+
Optional<MoveOnly> MO;
812+
};
813+
814+
TEST(OptionalTest, GCCIsTriviallyMoveConstructibleCompat) {
815+
Optional<NotTriviallyCopyable> V;
816+
EXPECT_FALSE(V);
817+
}
818+
808819
} // end anonymous namespace

0 commit comments

Comments
 (0)