diff --git a/clang/include/clang/Basic/LLVM.h b/clang/include/clang/Basic/LLVM.h index 5d4d72630970b..7ffc4c403473b 100644 --- a/clang/include/clang/Basic/LLVM.h +++ b/clang/include/clang/Basic/LLVM.h @@ -37,7 +37,7 @@ namespace llvm { template class SmallString; template class SmallVector; template class SmallVectorImpl; - template class Optional; + template using Optional = std::optional; template class Expected; template diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 7ced94a7dc371..f9e76d85efdde 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -481,7 +481,7 @@ Optional ExprEngine::getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx) { const unsigned *V = State->get({E, LCtx->getStackFrame()}); - return V ? Optional(*V) : std::nullopt; + return V ? std::make_optional(*V) : std::nullopt; } ProgramStateRef ExprEngine::removePendingInitLoop(ProgramStateRef State, @@ -510,7 +510,7 @@ ExprEngine::getIndexOfElementToConstruct(ProgramStateRef State, const LocationContext *LCtx) { const unsigned *V = State->get({E, LCtx->getStackFrame()}); - return V ? Optional(*V) : std::nullopt; + return V ? std::make_optional(*V) : std::nullopt; } ProgramStateRef @@ -530,7 +530,7 @@ ExprEngine::getPendingArrayDestruction(ProgramStateRef State, const unsigned *V = State->get(LCtx->getStackFrame()); - return V ? Optional(*V) : std::nullopt; + return V ? std::make_optional(*V) : std::nullopt; } ProgramStateRef ExprEngine::setPendingArrayDestruction( @@ -600,7 +600,7 @@ ExprEngine::getObjectUnderConstruction(ProgramStateRef State, const LocationContext *LC) { ConstructedObjectKey Key(Item, LC->getStackFrame()); const SVal *V = State->get(Key); - return V ? Optional(*V) : std::nullopt; + return V ? std::make_optional(*V) : std::nullopt; } ProgramStateRef diff --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h index 64e9a16fd7988..da01d1a87cccd 100644 --- a/flang/include/flang/Lower/Runtime.h +++ b/flang/include/flang/Lower/Runtime.h @@ -16,9 +16,10 @@ #ifndef FORTRAN_LOWER_RUNTIME_H #define FORTRAN_LOWER_RUNTIME_H +#include + namespace llvm { -template -class Optional; +template using Optional = std::optional; } namespace mlir { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index 4efb5a2029e85..32960c2102eda 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -190,7 +190,7 @@ static FormSize g_form_sizes[] = { llvm::Optional DWARFFormValue::GetFixedSize(dw_form_t form, const DWARFUnit *u) { if (form <= DW_FORM_ref_sig8 && g_form_sizes[form].valid) - return g_form_sizes[form].size; + return static_cast(g_form_sizes[form].size); if (form == DW_FORM_addr && u) return u->GetAddressByteSize(); return std::nullopt; diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index da9eeadc0ecd2..048e37fb1db2f 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -343,7 +343,7 @@ Type *Type::GetEncodingType() { llvm::Optional Type::GetByteSize(ExecutionContextScope *exe_scope) { if (m_byte_size_has_value) - return m_byte_size; + return static_cast(m_byte_size); switch (m_encoding_uid_type) { case eEncodingInvalid: @@ -360,14 +360,14 @@ llvm::Optional Type::GetByteSize(ExecutionContextScope *exe_scope) { if (llvm::Optional size = encoding_type->GetByteSize(exe_scope)) { m_byte_size = *size; m_byte_size_has_value = true; - return m_byte_size; + return static_cast(m_byte_size); } if (llvm::Optional size = GetLayoutCompilerType().GetByteSize(exe_scope)) { m_byte_size = *size; m_byte_size_has_value = true; - return m_byte_size; + return static_cast(m_byte_size); } } break; @@ -378,7 +378,7 @@ llvm::Optional Type::GetByteSize(ExecutionContextScope *exe_scope) { if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) { m_byte_size = arch.GetAddressByteSize(); m_byte_size_has_value = true; - return m_byte_size; + return static_cast(m_byte_size); } } break; } diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h index a458ccf61c717..c3382837c0aea 100644 --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -16,446 +16,12 @@ #ifndef LLVM_ADT_OPTIONAL_H #define LLVM_ADT_OPTIONAL_H -#include "llvm/ADT/Hashing.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/type_traits.h" -#include -#include -#include +#include namespace llvm { - -namespace optional_detail { - -/// Storage for any type. -// -// The specialization condition intentionally uses -// llvm::is_trivially_{copy/move}_constructible instead of -// std::is_trivially_{copy/move}_constructible. GCC versions prior to 7.4 may -// instantiate the copy/move constructor of `T` when -// std::is_trivially_{copy/move}_constructible is instantiated. This causes -// compilation to fail if we query the trivially copy/move constructible -// property of a class which is not copy/move constructible. -// -// The current implementation of OptionalStorage insists that in order to use -// the trivial specialization, the value_type must be trivially copy -// constructible and trivially copy assignable due to =default implementations -// of the copy/move constructor/assignment. It does not follow that this is -// necessarily the case std::is_trivially_copyable is true (hence the expanded -// specialization condition). -// -// The move constructible / assignable conditions emulate the remaining behavior -// of std::is_trivially_copyable. -template ::value && - std::is_trivially_copy_assignable::value && - (llvm::is_trivially_move_constructible::value || - !std::is_move_constructible::value) && - (std::is_trivially_move_assignable::value || - !std::is_move_assignable::value))> -class OptionalStorage { - union { - char empty; - T val; - }; - bool hasVal = false; - -public: - ~OptionalStorage() { reset(); } - - constexpr OptionalStorage() noexcept : empty() {} - - constexpr OptionalStorage(OptionalStorage const &other) : OptionalStorage() { - if (other.has_value()) { - emplace(other.val); - } - } - constexpr OptionalStorage(OptionalStorage &&other) : OptionalStorage() { - if (other.has_value()) { - emplace(std::move(other.val)); - } - } - - template - constexpr explicit OptionalStorage(std::in_place_t, Args &&...args) - : val(std::forward(args)...), hasVal(true) {} - - void reset() noexcept { - if (hasVal) { - val.~T(); - hasVal = false; - } - } - - constexpr bool has_value() const noexcept { return hasVal; } - - T &value() &noexcept { - assert(hasVal); - return val; - } - constexpr T const &value() const &noexcept { - assert(hasVal); - return val; - } - T &&value() &&noexcept { - assert(hasVal); - return std::move(val); - } - - template void emplace(Args &&...args) { - reset(); - ::new ((void *)std::addressof(val)) T(std::forward(args)...); - hasVal = true; - } - - OptionalStorage &operator=(T const &y) { - if (has_value()) { - val = y; - } else { - ::new ((void *)std::addressof(val)) T(y); - hasVal = true; - } - return *this; - } - OptionalStorage &operator=(T &&y) { - if (has_value()) { - val = std::move(y); - } else { - ::new ((void *)std::addressof(val)) T(std::move(y)); - hasVal = true; - } - return *this; - } - - OptionalStorage &operator=(OptionalStorage const &other) { - if (other.has_value()) { - if (has_value()) { - val = other.val; - } else { - ::new ((void *)std::addressof(val)) T(other.val); - hasVal = true; - } - } else { - reset(); - } - return *this; - } - - OptionalStorage &operator=(OptionalStorage &&other) { - if (other.has_value()) { - if (has_value()) { - val = std::move(other.val); - } else { - ::new ((void *)std::addressof(val)) T(std::move(other.val)); - hasVal = true; - } - } else { - reset(); - } - return *this; - } -}; - -template class OptionalStorage { - union { - char empty; - T val; - }; - bool hasVal = false; - -public: - ~OptionalStorage() = default; - - constexpr OptionalStorage() noexcept : empty{} {} - - constexpr OptionalStorage(OptionalStorage const &other) = default; - constexpr OptionalStorage(OptionalStorage &&other) = default; - - OptionalStorage &operator=(OptionalStorage const &other) = default; - OptionalStorage &operator=(OptionalStorage &&other) = default; - - template - constexpr explicit OptionalStorage(std::in_place_t, Args &&...args) - : val(std::forward(args)...), hasVal(true) {} - - void reset() noexcept { - if (hasVal) { - val.~T(); - hasVal = false; - } - } - - constexpr bool has_value() const noexcept { return hasVal; } - - T &value() &noexcept { - assert(hasVal); - return val; - } - constexpr T const &value() const &noexcept { - assert(hasVal); - return val; - } - T &&value() &&noexcept { - assert(hasVal); - return std::move(val); - } - - template void emplace(Args &&...args) { - reset(); - ::new ((void *)std::addressof(val)) T(std::forward(args)...); - hasVal = true; - } - - OptionalStorage &operator=(T const &y) { - if (has_value()) { - val = y; - } else { - ::new ((void *)std::addressof(val)) T(y); - hasVal = true; - } - return *this; - } - OptionalStorage &operator=(T &&y) { - if (has_value()) { - val = std::move(y); - } else { - ::new ((void *)std::addressof(val)) T(std::move(y)); - hasVal = true; - } - return *this; - } -}; - -} // namespace optional_detail - -template class Optional { - optional_detail::OptionalStorage Storage; - -public: - using value_type = T; - - constexpr Optional() = default; - constexpr Optional(std::nullopt_t) {} - - constexpr Optional(const T &y) : Storage(std::in_place, y) {} - constexpr Optional(const Optional &O) = default; - - constexpr Optional(T &&y) : Storage(std::in_place, std::move(y)) {} - constexpr Optional(Optional &&O) = default; - - template - constexpr Optional(std::in_place_t, ArgTypes &&...Args) - : Storage(std::in_place, std::forward(Args)...) {} - - Optional &operator=(T &&y) { - Storage = std::move(y); - return *this; - } - Optional &operator=(Optional &&O) = default; - - /// Create a new object by constructing it in place with the given arguments. - template void emplace(ArgTypes &&... Args) { - Storage.emplace(std::forward(Args)...); - } - - Optional &operator=(const T &y) { - Storage = y; - return *this; - } - Optional &operator=(const Optional &O) = default; - - void reset() { Storage.reset(); } - - LLVM_DEPRECATED("Use &*X instead.", "&*X") - constexpr const T *getPointer() const { return &Storage.value(); } - LLVM_DEPRECATED("Use &*X instead.", "&*X") - T *getPointer() { return &Storage.value(); } - LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") - constexpr const T &value() const & { return Storage.value(); } - LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") - T &value() & { return Storage.value(); } - - constexpr explicit operator bool() const { return has_value(); } - constexpr bool has_value() const { return Storage.has_value(); } - constexpr const T *operator->() const { return &Storage.value(); } - T *operator->() { return &Storage.value(); } - constexpr const T &operator*() const & { return Storage.value(); } - T &operator*() & { return Storage.value(); } - - template constexpr T value_or(U &&alt) const & { - return has_value() ? operator*() : std::forward(alt); - } - - LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") - T &&value() && { return std::move(Storage.value()); } - T &&operator*() && { return std::move(Storage.value()); } - - template T value_or(U &&alt) && { - return has_value() ? std::move(operator*()) : std::forward(alt); - } -}; - -template -Optional(const T&) -> Optional; - -template llvm::hash_code hash_value(const Optional &O) { - return O ? hash_combine(true, *O) : hash_value(false); -} - -template -constexpr bool operator==(const Optional &X, const Optional &Y) { - if (X && Y) - return *X == *Y; - return X.has_value() == Y.has_value(); -} - -template -constexpr bool operator!=(const Optional &X, const Optional &Y) { - return !(X == Y); -} - -template -constexpr bool operator<(const Optional &X, const Optional &Y) { - if (X && Y) - return *X < *Y; - return X.has_value() < Y.has_value(); -} - -template -constexpr bool operator<=(const Optional &X, const Optional &Y) { - return !(Y < X); -} - -template -constexpr bool operator>(const Optional &X, const Optional &Y) { - return Y < X; -} - -template -constexpr bool operator>=(const Optional &X, const Optional &Y) { - return !(X < Y); -} - -template -constexpr bool operator==(const Optional &X, std::nullopt_t) { - return !X; -} - -template -constexpr bool operator==(std::nullopt_t, const Optional &X) { - return X == std::nullopt; -} - -template -constexpr bool operator!=(const Optional &X, std::nullopt_t) { - return !(X == std::nullopt); -} - -template -constexpr bool operator!=(std::nullopt_t, const Optional &X) { - return X != std::nullopt; -} - -template -constexpr bool operator<(const Optional &, std::nullopt_t) { - return false; -} - -template -constexpr bool operator<(std::nullopt_t, const Optional &X) { - return X.has_value(); -} - -template -constexpr bool operator<=(const Optional &X, std::nullopt_t) { - return !(std::nullopt < X); -} - -template -constexpr bool operator<=(std::nullopt_t, const Optional &X) { - return !(X < std::nullopt); -} - -template -constexpr bool operator>(const Optional &X, std::nullopt_t) { - return std::nullopt < X; -} - -template -constexpr bool operator>(std::nullopt_t, const Optional &X) { - return X < std::nullopt; -} - -template -constexpr bool operator>=(const Optional &X, std::nullopt_t) { - return std::nullopt <= X; -} - -template -constexpr bool operator>=(std::nullopt_t, const Optional &X) { - return X <= std::nullopt; -} - -template -constexpr bool operator==(const Optional &X, const T &Y) { - return X && *X == Y; -} - -template -constexpr bool operator==(const T &X, const Optional &Y) { - return Y && X == *Y; -} - -template -constexpr bool operator!=(const Optional &X, const T &Y) { - return !(X == Y); -} - -template -constexpr bool operator!=(const T &X, const Optional &Y) { - return !(X == Y); -} - -template -constexpr bool operator<(const Optional &X, const T &Y) { - return !X || *X < Y; -} - -template -constexpr bool operator<(const T &X, const Optional &Y) { - return Y && X < *Y; -} - -template -constexpr bool operator<=(const Optional &X, const T &Y) { - return !(Y < X); -} - -template -constexpr bool operator<=(const T &X, const Optional &Y) { - return !(Y < X); -} - -template -constexpr bool operator>(const Optional &X, const T &Y) { - return Y < X; -} - -template -constexpr bool operator>(const T &X, const Optional &Y) { - return Y < X; -} - -template -constexpr bool operator>=(const Optional &X, const T &Y) { - return !(X < Y); -} - -template -constexpr bool operator>=(const T &X, const Optional &Y) { - return !(X < Y); -} - -} // end namespace llvm +// Legacy alias of llvm::Optional to std::optional. +// FIXME: Remove this after LLVM 16. +template using Optional = std::optional; +} // namespace llvm #endif // LLVM_ADT_OPTIONAL_H diff --git a/llvm/include/llvm/ADT/STLForwardCompat.h b/llvm/include/llvm/ADT/STLForwardCompat.h index 51748c7c0ea28..b2fe9bc753f63 100644 --- a/llvm/include/llvm/ADT/STLForwardCompat.h +++ b/llvm/include/llvm/ADT/STLForwardCompat.h @@ -61,26 +61,6 @@ auto transformOptional(std::optional &&O, const Function &F) return std::nullopt; } -// TODO: Remove this once the migration from llvm::Optional to std::optional is -// complete. -template -auto transformOptional(const Optional &O, const Function &F) - -> Optional { - if (O) - return F(*O); - return std::nullopt; -} - -// TODO: Remove this once the migration from llvm::Optional to std::optional is -// complete. -template -auto transformOptional(Optional &&O, const Function &F) - -> Optional { - if (O) - return F(*std::move(O)); - return std::nullopt; -} - } // namespace llvm #endif // LLVM_ADT_STLFORWARDCOMPAT_H diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h index b5c3e463d69dc..73c703c7f8732 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h @@ -743,16 +743,6 @@ Error writeToOutput(StringRef OutputFileName, raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t); -template () - << std::declval())> -raw_ostream &operator<<(raw_ostream &OS, const Optional &O) { - if (O) - OS << *O; - else - OS << std::nullopt; - return OS; -} - template () << std::declval())> raw_ostream &operator<<(raw_ostream &OS, const std::optional &O) { diff --git a/llvm/include/llvm/Testing/Support/SupportHelpers.h b/llvm/include/llvm/Testing/Support/SupportHelpers.h index afcad6f9ba307..f9aa136f7a0ac 100644 --- a/llvm/include/llvm/Testing/Support/SupportHelpers.h +++ b/llvm/include/llvm/Testing/Support/SupportHelpers.h @@ -69,12 +69,6 @@ template class ValueIsMatcher { new Impl(::testing::SafeMatcherCast(ValueMatcher))); } - template - operator ::testing::Matcher &>() const { - return ::testing::MakeMatcher( - new Impl>(::testing::SafeMatcherCast(ValueMatcher))); - } - template > class Impl : public ::testing::MatcherInterface { public: diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h index e199772b14069..188cc5664d5d9 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.h +++ b/llvm/lib/CodeGen/RegAllocGreedy.h @@ -80,7 +80,7 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public MachineFunctionPass, unsigned NextCascade = 1; public: - ExtraRegInfo() = default; + ExtraRegInfo() {} ExtraRegInfo(const ExtraRegInfo &) = delete; LiveRangeStage getStage(Register Reg) const { return Info[Reg].Stage; } diff --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt index 8cddaa50341f8..5a918892ff8e4 100644 --- a/llvm/unittests/ADT/CMakeLists.txt +++ b/llvm/unittests/ADT/CMakeLists.txt @@ -49,7 +49,6 @@ add_llvm_unittest(ADTTests MappedIteratorTest.cpp MapVectorTest.cpp MoveOnly.cpp - OptionalTest.cpp PackedVectorTest.cpp PointerEmbeddedIntTest.cpp PointerIntPairTest.cpp diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp deleted file mode 100644 index af4cf2ec46610..0000000000000 --- a/llvm/unittests/ADT/OptionalTest.cpp +++ /dev/null @@ -1,803 +0,0 @@ -//===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/raw_ostream.h" -#include "MoveOnly.h" -#include "gtest/gtest-spi.h" -#include "gtest/gtest.h" - -#include -#include - -using namespace llvm; - -static_assert(std::is_trivially_copyable_v>, - "trivially copyable"); - -static_assert(std::is_trivially_copyable_v>>, - "trivially copyable"); - -void OptionalWorksInConstexpr() { - constexpr auto x1 = Optional(); - constexpr Optional x2{}; - static_assert(!x1.has_value() && !x2.has_value(), - "Default construction and hasValue() are contexpr"); - static_assert(!x1.has_value() && !x2.has_value(), - "Default construction and hasValue() are contexpr"); - constexpr auto y1 = Optional(3); - constexpr Optional y2{3}; - static_assert(*y1 == *y2 && *y1 == 3, - "Construction with value and getValue() are constexpr"); - static_assert(*y1 == *y2 && *y1 == 3, - "Construction with value and getValue() are constexpr"); - static_assert(Optional{3} >= 2 && Optional{1} < Optional{2}, - "Comparisons work in constexpr"); -} - -namespace { - -struct NonDefaultConstructible { - static unsigned CopyConstructions; - static unsigned Destructions; - static unsigned CopyAssignments; - explicit NonDefaultConstructible(int) { - } - NonDefaultConstructible(const NonDefaultConstructible&) { - ++CopyConstructions; - } - NonDefaultConstructible &operator=(const NonDefaultConstructible&) { - ++CopyAssignments; - return *this; - } - ~NonDefaultConstructible() { - ++Destructions; - } - static void ResetCounts() { - CopyConstructions = 0; - Destructions = 0; - CopyAssignments = 0; - } -}; - -unsigned NonDefaultConstructible::CopyConstructions = 0; -unsigned NonDefaultConstructible::Destructions = 0; -unsigned NonDefaultConstructible::CopyAssignments = 0; - -static_assert(!std::is_trivially_copyable_v>, - "not trivially copyable"); - -TEST(OptionalTest, NonDefaultConstructibleTest) { - Optional O; - EXPECT_FALSE(O); -} - -TEST(OptionalTest, ResetTest) { - NonDefaultConstructible::ResetCounts(); - Optional O(NonDefaultConstructible(3)); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - O.reset(); - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, InitializationLeakTest) { - NonDefaultConstructible::ResetCounts(); - Optional(NonDefaultConstructible(3)); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, CopyConstructionTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A(NonDefaultConstructible(3)); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - Optional B(A); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, ConstructingCopyAssignmentTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A(NonDefaultConstructible(3)); - Optional B; - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - B = A; - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, CopyingCopyAssignmentTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A(NonDefaultConstructible(3)); - Optional B(NonDefaultConstructible(4)); - EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - B = A; - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, DeletingCopyAssignmentTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A; - Optional B(NonDefaultConstructible(3)); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - B = A; - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, NullCopyConstructionTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A; - Optional B; - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - B = A; - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, InPlaceConstructionNonDefaultConstructibleTest) { - NonDefaultConstructible::ResetCounts(); - { Optional A{std::in_place, 1}; } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, GetValueOr) { - Optional A; - EXPECT_EQ(42, A.value_or(42)); - - A = 5; - EXPECT_EQ(5, A.value_or(42)); -} - -struct MultiArgConstructor { - int x, y; - MultiArgConstructor(int x, int y) : x(x), y(y) {} - explicit MultiArgConstructor(int x, bool positive) - : x(x), y(positive ? x : -x) {} - - MultiArgConstructor(const MultiArgConstructor &) = delete; - MultiArgConstructor(MultiArgConstructor &&) = delete; - MultiArgConstructor &operator=(const MultiArgConstructor &) = delete; - MultiArgConstructor &operator=(MultiArgConstructor &&) = delete; - - friend bool operator==(const MultiArgConstructor &LHS, - const MultiArgConstructor &RHS) { - return LHS.x == RHS.x && LHS.y == RHS.y; - } - - static unsigned Destructions; - ~MultiArgConstructor() { - ++Destructions; - } - static void ResetCounts() { - Destructions = 0; - } -}; -unsigned MultiArgConstructor::Destructions = 0; - -static_assert(!std::is_trivially_copyable_v>, - "not trivially copyable"); - -TEST(OptionalTest, Emplace) { - MultiArgConstructor::ResetCounts(); - Optional A; - - A.emplace(1, 2); - EXPECT_TRUE(A.has_value()); - EXPECT_TRUE(A.has_value()); - EXPECT_EQ(1, A->x); - EXPECT_EQ(2, A->y); - EXPECT_EQ(0u, MultiArgConstructor::Destructions); - - A.emplace(5, false); - EXPECT_TRUE(A.has_value()); - EXPECT_TRUE(A.has_value()); - EXPECT_EQ(5, A->x); - EXPECT_EQ(-5, A->y); - EXPECT_EQ(1u, MultiArgConstructor::Destructions); -} - -TEST(OptionalTest, InPlaceConstructionMultiArgConstructorTest) { - MultiArgConstructor::ResetCounts(); - { - Optional A{std::in_place, 1, 2}; - EXPECT_TRUE(A.has_value()); - EXPECT_TRUE(A.has_value()); - EXPECT_EQ(1, A->x); - EXPECT_EQ(2, A->y); - Optional B{std::in_place, 5, false}; - EXPECT_TRUE(B.has_value()); - EXPECT_TRUE(B.has_value()); - EXPECT_EQ(5, B->x); - EXPECT_EQ(-5, B->y); - EXPECT_EQ(0u, MultiArgConstructor::Destructions); - } - EXPECT_EQ(2u, MultiArgConstructor::Destructions); -} - -TEST(OptionalTest, InPlaceConstructionAndEmplaceEquivalentTest) { - MultiArgConstructor::ResetCounts(); - { - Optional A{std::in_place, 1, 2}; - Optional B; - B.emplace(1, 2); - EXPECT_EQ(0u, MultiArgConstructor::Destructions); - ASSERT_EQ(A, B); - } - EXPECT_EQ(2u, MultiArgConstructor::Destructions); -} - -static_assert(!std::is_trivially_copyable_v>, - "not trivially copyable"); - -TEST(OptionalTest, MoveOnlyNull) { - MoveOnly::ResetCounts(); - Optional O; - EXPECT_EQ(0u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(0u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyConstruction) { - MoveOnly::ResetCounts(); - Optional O(MoveOnly(3)); - EXPECT_TRUE((bool)O); - EXPECT_EQ(3, O->val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(1u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyMoveConstruction) { - Optional A(MoveOnly(3)); - MoveOnly::ResetCounts(); - Optional B(std::move(A)); - EXPECT_TRUE((bool)A); - EXPECT_TRUE((bool)B); - EXPECT_EQ(3, B->val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(0u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyAssignment) { - MoveOnly::ResetCounts(); - Optional O; - O = MoveOnly(3); - EXPECT_TRUE((bool)O); - EXPECT_EQ(3, O->val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(1u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyInitializingAssignment) { - Optional A(MoveOnly(3)); - Optional B; - MoveOnly::ResetCounts(); - B = std::move(A); - EXPECT_TRUE((bool)A); - EXPECT_TRUE((bool)B); - EXPECT_EQ(3, B->val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(0u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyNullingAssignment) { - Optional A; - Optional B(MoveOnly(3)); - MoveOnly::ResetCounts(); - B = std::move(A); - EXPECT_FALSE((bool)A); - EXPECT_FALSE((bool)B); - EXPECT_EQ(0u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(1u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyAssigningAssignment) { - Optional A(MoveOnly(3)); - Optional B(MoveOnly(4)); - MoveOnly::ResetCounts(); - B = std::move(A); - EXPECT_TRUE((bool)A); - EXPECT_TRUE((bool)B); - EXPECT_EQ(3, B->val); - EXPECT_EQ(0u, MoveOnly::MoveConstructions); - EXPECT_EQ(1u, MoveOnly::MoveAssignments); - EXPECT_EQ(0u, MoveOnly::Destructions); -} - -struct Immovable { - static unsigned Constructions; - static unsigned Destructions; - int val; - explicit Immovable(int val) : val(val) { - ++Constructions; - } - ~Immovable() { - ++Destructions; - } - static void ResetCounts() { - Constructions = 0; - Destructions = 0; - } -private: - // This should disable all move/copy operations. - Immovable(Immovable&& other) = delete; -}; - -unsigned Immovable::Constructions = 0; -unsigned Immovable::Destructions = 0; - -static_assert(!std::is_trivially_copyable_v>, - "not trivially copyable"); - -TEST(OptionalTest, ImmovableEmplace) { - Optional A; - Immovable::ResetCounts(); - A.emplace(4); - EXPECT_TRUE((bool)A); - EXPECT_EQ(4, A->val); - EXPECT_EQ(1u, Immovable::Constructions); - EXPECT_EQ(0u, Immovable::Destructions); -} - -TEST(OptionalTest, ImmovableInPlaceConstruction) { - Immovable::ResetCounts(); - Optional A{std::in_place, 4}; - EXPECT_TRUE((bool)A); - EXPECT_EQ(4, A->val); - EXPECT_EQ(1u, Immovable::Constructions); - EXPECT_EQ(0u, Immovable::Destructions); -} - -// Craft a class which is_trivially_copyable, but not -// is_trivially_copy_constructible. -struct NonTCopy { - NonTCopy() = default; - - // Delete the volatile copy constructor to engage the "rule of 3" and delete - // any unspecified copy assignment or constructor. - NonTCopy(volatile NonTCopy const &) = delete; - - // Leave the non-volatile default copy constructor unspecified (deleted by - // rule of 3) - - // This template can serve as the copy constructor, but isn't chosen - // by =default in a class with a 'NonTCopy' member. - template - NonTCopy(Self const &Other) : Val(Other.Val) {} - - NonTCopy &operator=(NonTCopy const &) = default; - - int Val{0}; -}; - -#if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__) -// Currently only true on recent MSVC releases. -static_assert(std::is_trivially_copyable::value, - "Expect NonTCopy to be trivially copyable"); - -static_assert(!std::is_trivially_copy_constructible::value, - "Expect NonTCopy not to be trivially copy constructible."); -#endif // defined(_MSC_VER) && _MSC_VER >= 1927 - -TEST(OptionalTest, DeletedCopyConstructor) { - - // Expect compile to fail if 'trivial' version of - // optional_detail::OptionalStorage is chosen. - using NonTCopyOptT = Optional; - NonTCopyOptT NonTCopy1; - - // Check that the Optional can be copy constructed. - NonTCopyOptT NonTCopy2{NonTCopy1}; - - // Check that the Optional can be copy assigned. - NonTCopy1 = NonTCopy2; -} - -// Craft a class which is_trivially_copyable, but not -// is_trivially_copy_assignable. -class NonTAssign { -public: - NonTAssign() = default; - NonTAssign(NonTAssign const &) = default; - - // Delete the volatile copy assignment to engage the "rule of 3" and delete - // any unspecified copy assignment or constructor. - NonTAssign &operator=(volatile NonTAssign const &) = delete; - - // Leave the non-volatile default copy assignment unspecified (deleted by rule - // of 3). - - // This template can serve as the copy assignment, but isn't chosen - // by =default in a class with a 'NonTAssign' member. - template - NonTAssign &operator=(Self const &Other) { - A = Other.A; - return *this; - } - - int A{0}; -}; - -#if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__) -// Currently only true on recent MSVC releases. -static_assert(std::is_trivially_copyable::value, - "Expect NonTAssign to be trivially copyable"); - -static_assert(!std::is_trivially_copy_assignable::value, - "Expect NonTAssign not to be trivially assignable."); -#endif // defined(_MSC_VER) && _MSC_VER >= 1927 - -TEST(OptionalTest, DeletedCopyAssignment) { - - // Expect compile to fail if 'trivial' version of - // optional_detail::OptionalStorage is chosen. - using NonTAssignOptT = Optional; - NonTAssignOptT NonTAssign1; - - // Check that the Optional can be copy constructed. - NonTAssignOptT NonTAssign2{NonTAssign1}; - - // Check that the Optional can be copy assigned. - NonTAssign1 = NonTAssign2; -} - -struct NoTMove { - NoTMove() = default; - NoTMove(NoTMove const &) = default; - NoTMove &operator=(NoTMove const &) = default; - - // Delete move constructor / assignment. Compiler should fall-back to the - // trivial copy constructor / assignment in the trivial OptionalStorage - // specialization. - NoTMove(NoTMove &&) = delete; - NoTMove &operator=(NoTMove &&) = delete; - - int Val{0}; -}; - -TEST(OptionalTest, DeletedMoveConstructor) { - using NoTMoveOptT = Optional; - - NoTMoveOptT NonTMove1; - NoTMoveOptT NonTMove2{std::move(NonTMove1)}; - - NonTMove1 = std::move(NonTMove2); - - static_assert( - std::is_trivially_copyable_v, - "Expect Optional to still use the trivial specialization " - "of OptionalStorage despite the deleted move constructor / assignment."); -} - -class NoCopyStringMap { -public: - NoCopyStringMap() = default; - -private: - llvm::StringMap> Map; -}; - -TEST(OptionalTest, DeletedCopyStringMap) { - // Old versions of gcc (7.3 and prior) instantiate the copy constructor when - // std::is_trivially_copyable is instantiated. This test will fail - // compilation if std::is_trivially_copyable is used in the OptionalStorage - // specialization condition by gcc <= 7.3. - Optional TestInstantiation; -} - -TEST(OptionalTest, MoveValueOr) { - Optional A; - - MoveOnly::ResetCounts(); - EXPECT_EQ(42, std::move(A).value_or(MoveOnly(42)).val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(2u, MoveOnly::Destructions); - - A = MoveOnly(5); - MoveOnly::ResetCounts(); - EXPECT_EQ(5, std::move(A).value_or(MoveOnly(42)).val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(2u, MoveOnly::Destructions); -} - -struct EqualTo { - template static bool apply(const T &X, const U &Y) { - return X == Y; - } -}; - -struct NotEqualTo { - template static bool apply(const T &X, const U &Y) { - return X != Y; - } -}; - -struct Less { - template static bool apply(const T &X, const U &Y) { - return X < Y; - } -}; - -struct Greater { - template static bool apply(const T &X, const U &Y) { - return X > Y; - } -}; - -struct LessEqual { - template static bool apply(const T &X, const U &Y) { - return X <= Y; - } -}; - -struct GreaterEqual { - template static bool apply(const T &X, const U &Y) { - return X >= Y; - } -}; - -template -void CheckRelation(const Optional &Lhs, const Optional &Rhs, - bool Expected) { - EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs)); - - if (Lhs) - EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs)); - else - EXPECT_EQ(Expected, OperatorT::apply(std::nullopt, Rhs)); - - if (Rhs) - EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs)); - else - EXPECT_EQ(Expected, OperatorT::apply(Lhs, std::nullopt)); -} - -struct EqualityMock {}; -const Optional NoneEq, EqualityLhs((EqualityMock())), - EqualityRhs((EqualityMock())); -bool IsEqual; - -bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) { - EXPECT_EQ(&*EqualityLhs, &Lhs); - EXPECT_EQ(&*EqualityRhs, &Rhs); - return IsEqual; -} - -TEST(OptionalTest, OperatorEqual) { - CheckRelation(NoneEq, NoneEq, true); - CheckRelation(NoneEq, EqualityRhs, false); - CheckRelation(EqualityLhs, NoneEq, false); - - IsEqual = false; - CheckRelation(EqualityLhs, EqualityRhs, IsEqual); - IsEqual = true; - CheckRelation(EqualityLhs, EqualityRhs, IsEqual); -} - -TEST(OptionalTest, OperatorNotEqual) { - CheckRelation(NoneEq, NoneEq, false); - CheckRelation(NoneEq, EqualityRhs, true); - CheckRelation(EqualityLhs, NoneEq, true); - - IsEqual = false; - CheckRelation(EqualityLhs, EqualityRhs, !IsEqual); - IsEqual = true; - CheckRelation(EqualityLhs, EqualityRhs, !IsEqual); -} - -struct InequalityMock {}; -const Optional NoneIneq, InequalityLhs((InequalityMock())), - InequalityRhs((InequalityMock())); -bool IsLess; - -bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) { - EXPECT_EQ(&*InequalityLhs, &Lhs); - EXPECT_EQ(&*InequalityRhs, &Rhs); - return IsLess; -} - -TEST(OptionalTest, OperatorLess) { - CheckRelation(NoneIneq, NoneIneq, false); - CheckRelation(NoneIneq, InequalityRhs, true); - CheckRelation(InequalityLhs, NoneIneq, false); - - IsLess = false; - CheckRelation(InequalityLhs, InequalityRhs, IsLess); - IsLess = true; - CheckRelation(InequalityLhs, InequalityRhs, IsLess); -} - -TEST(OptionalTest, OperatorGreater) { - CheckRelation(NoneIneq, NoneIneq, false); - CheckRelation(NoneIneq, InequalityRhs, false); - CheckRelation(InequalityLhs, NoneIneq, true); - - IsLess = false; - CheckRelation(InequalityRhs, InequalityLhs, IsLess); - IsLess = true; - CheckRelation(InequalityRhs, InequalityLhs, IsLess); -} - -TEST(OptionalTest, OperatorLessEqual) { - CheckRelation(NoneIneq, NoneIneq, true); - CheckRelation(NoneIneq, InequalityRhs, true); - CheckRelation(InequalityLhs, NoneIneq, false); - - IsLess = false; - CheckRelation(InequalityRhs, InequalityLhs, !IsLess); - IsLess = true; - CheckRelation(InequalityRhs, InequalityLhs, !IsLess); -} - -TEST(OptionalTest, OperatorGreaterEqual) { - CheckRelation(NoneIneq, NoneIneq, true); - CheckRelation(NoneIneq, InequalityRhs, false); - CheckRelation(InequalityLhs, NoneIneq, true); - - IsLess = false; - CheckRelation(InequalityLhs, InequalityRhs, !IsLess); - IsLess = true; - CheckRelation(InequalityLhs, InequalityRhs, !IsLess); -} - -struct ComparableAndStreamable { - friend bool operator==(ComparableAndStreamable, - ComparableAndStreamable) LLVM_ATTRIBUTE_USED { - return true; - } - - friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) { - return OS << "ComparableAndStreamable"; - } - - static Optional get() { - return ComparableAndStreamable(); - } -}; - -TEST(OptionalTest, StreamOperator) { - auto to_string = [](Optional O) { - SmallString<16> S; - raw_svector_ostream OS(S); - OS << O; - return S; - }; - EXPECT_EQ("ComparableAndStreamable", - to_string(ComparableAndStreamable::get())); - EXPECT_EQ("None", to_string(std::nullopt)); -} - -struct Comparable { - friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED { - return true; - } - static Optional get() { return Comparable(); } -}; - -TEST(OptionalTest, UseInUnitTests) { - // Test that we invoke the streaming operators when pretty-printing values in - // EXPECT macros. - EXPECT_NONFATAL_FAILURE( - EXPECT_EQ(std::nullopt, ComparableAndStreamable::get()), - "Expected equality of these values:\n" - " std::nullopt\n" - " Which is: None\n" - " ComparableAndStreamable::get()\n" - " Which is: ComparableAndStreamable"); - - // Test that it is still possible to compare objects which do not have a - // custom streaming operator. - EXPECT_NONFATAL_FAILURE(EXPECT_EQ(std::nullopt, Comparable::get()), "object"); -} - -TEST(OptionalTest, HashValue) { - // Check that None, false, and true all hash differently. - Optional B, B0 = false, B1 = true; - EXPECT_NE(hash_value(B0), hash_value(B)); - EXPECT_NE(hash_value(B1), hash_value(B)); - EXPECT_NE(hash_value(B1), hash_value(B0)); - - // Check that None, 0, and 1 all hash differently. - Optional I, I0 = 0, I1 = 1; - EXPECT_NE(hash_value(I0), hash_value(I)); - EXPECT_NE(hash_value(I1), hash_value(I)); - EXPECT_NE(hash_value(I1), hash_value(I0)); - - // Check None hash the same way regardless of type. - EXPECT_EQ(hash_value(B), hash_value(I)); -} - -struct NotTriviallyCopyable { - NotTriviallyCopyable(); // Constructor out-of-line. - virtual ~NotTriviallyCopyable() = default; - Optional MO; -}; - -TEST(OptionalTest, GCCIsTriviallyMoveConstructibleCompat) { - Optional V; - EXPECT_FALSE(V); -} - -TEST(OptionalTest, DeductionGuide) { - Optional V = MoveOnly(1); - EXPECT_TRUE(V); - EXPECT_EQ(V->val, 1); -} - -static_assert( - std::is_same_v, decltype(Optional(MoveOnly(1)))>); - -} // end anonymous namespace diff --git a/llvm/unittests/Support/TypeTraitsTest.cpp b/llvm/unittests/Support/TypeTraitsTest.cpp index 734e50afa2db3..845c38d21182b 100644 --- a/llvm/unittests/Support/TypeTraitsTest.cpp +++ b/llvm/unittests/Support/TypeTraitsTest.cpp @@ -118,7 +118,10 @@ TEST(Triviality, ADT) { TrivialityTester(); TrivialityTester, true, true>(); TrivialityTester, true, true>(); +#if defined(_LIBCPP_VERSION) || \ + (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 8) TrivialityTester, true, true>(); +#endif } } // namespace triviality diff --git a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h index 564425b9beb2c..38c547078bfcd 100644 --- a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h +++ b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h @@ -35,9 +35,6 @@ namespace py = pybind11; namespace pybind11 { namespace detail { -template -struct type_caster> : optional_caster> {}; - /// Helper to convert a presumed MLIR API object to a capsule, accepting either /// an explicit Capsule (which can happen when two C APIs are communicating /// directly via Python) or indirectly by querying the MLIR_PYTHON_CAPI_PTR_ATTR diff --git a/mlir/include/mlir/Support/LLVM.h b/mlir/include/mlir/Support/LLVM.h index a389392301a00..7acf97b5a2531 100644 --- a/mlir/include/mlir/Support/LLVM.h +++ b/mlir/include/mlir/Support/LLVM.h @@ -58,8 +58,7 @@ class DenseSet; class MallocAllocator; template class MutableArrayRef; -template -class Optional; +template using Optional = std::optional; template class PointerUnion; template diff --git a/mlir/lib/Bindings/Python/PybindUtils.h b/mlir/lib/Bindings/Python/PybindUtils.h index 5356cbd54ff48..d039a8acdca39 100644 --- a/mlir/lib/Bindings/Python/PybindUtils.h +++ b/mlir/lib/Bindings/Python/PybindUtils.h @@ -94,9 +94,6 @@ struct MlirDefaultingCaster { return pybind11::cast(src, policy); } }; - -template -struct type_caster> : optional_caster> {}; } // namespace detail } // namespace pybind11 diff --git a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp index 860d5d7d60800..692c1e8fb3bf4 100644 --- a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp +++ b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp @@ -179,7 +179,7 @@ SerializeToHsacoPass::loadLibraries(SmallVectorImpl &path, ret.push_back(std::move(library)); } - return ret; + return std::move(ret); } std::unique_ptr