diff options
author | Abseil Team <absl-team@google.com> | 2022-03-03 06:35:20 -0800 |
---|---|---|
committer | dinord <dino.radakovich@gmail.com> | 2022-03-03 09:43:16 -0500 |
commit | ec33f404bb16564a9aea3044cd8504d6885165b0 (patch) | |
tree | 42df609290f44528dff6d780261cf849cc8e5fee /absl/types | |
parent | dfc3fa9b5ae8b204ac83e3f06e4e8626f9bb2bc2 (diff) | |
download | abseil-ec33f404bb16564a9aea3044cd8504d6885165b0.tar.gz abseil-ec33f404bb16564a9aea3044cd8504d6885165b0.tar.bz2 abseil-ec33f404bb16564a9aea3044cd8504d6885165b0.zip |
Export of internal Abseil changes
--
f2ffea8ae1c1b152b63bf561375cfb6eb6b9dbe5 by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 432180490
Change-Id: I5e318e1d06fe26eee08920fe39f8a6285eb8e217
--
e5d0de4b3293833eab3f77252a091ac4ed74b210 by Derek Mauro <dmauro@google.com>:
absl::optional - Add a workaround for an internal compiler error in GCC5 though GCC10
PiperOrigin-RevId: 432047437
Change-Id: I524a9098dadc116d8a423dd66f7ec5ee894f2874
GitOrigin-RevId: f2ffea8ae1c1b152b63bf561375cfb6eb6b9dbe5
Diffstat (limited to 'absl/types')
-rw-r--r-- | absl/types/optional.h | 31 | ||||
-rw-r--r-- | absl/types/optional_test.cc | 26 |
2 files changed, 43 insertions, 14 deletions
diff --git a/absl/types/optional.h b/absl/types/optional.h index 61540cfd..134b2aff 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h @@ -282,15 +282,16 @@ class optional : private optional_internal::optional_data<T>, optional& operator=(optional&& src) = default; // Value assignment operators - template < - typename U = T, - typename = typename std::enable_if<absl::conjunction< - absl::negation< - std::is_same<optional<T>, typename std::decay<U>::type>>, - absl::negation< - absl::conjunction<std::is_scalar<T>, - std::is_same<T, typename std::decay<U>::type>>>, - std::is_constructible<T, U>, std::is_assignable<T&, U>>::value>::type> + template <typename U = T, + int&..., // Workaround an internal compiler error in GCC 5 to 10. + typename = typename std::enable_if<absl::conjunction< + absl::negation< + std::is_same<optional<T>, typename std::decay<U>::type> >, + absl::negation<absl::conjunction< + std::is_scalar<T>, + std::is_same<T, typename std::decay<U>::type> > >, + std::is_constructible<T, U>, + std::is_assignable<T&, U> >::value>::type> optional& operator=(U&& v) { this->assign(std::forward<U>(v)); return *this; @@ -298,13 +299,14 @@ class optional : private optional_internal::optional_data<T>, template < typename U, + int&..., // Workaround an internal compiler error in GCC 5 to 10. typename = typename std::enable_if<absl::conjunction< - absl::negation<std::is_same<T, U>>, + absl::negation<std::is_same<T, U> >, std::is_constructible<T, const U&>, std::is_assignable<T&, const U&>, absl::negation< optional_internal:: is_constructible_convertible_assignable_from_optional< - T, U>>>::value>::type> + T, U> > >::value>::type> optional& operator=(const optional<U>& rhs) { if (rhs) { this->assign(*rhs); @@ -315,13 +317,14 @@ class optional : private optional_internal::optional_data<T>, } template <typename U, + int&..., // Workaround an internal compiler error in GCC 5 to 10. typename = typename std::enable_if<absl::conjunction< - absl::negation<std::is_same<T, U>>, std::is_constructible<T, U>, - std::is_assignable<T&, U>, + absl::negation<std::is_same<T, U> >, + std::is_constructible<T, U>, std::is_assignable<T&, U>, absl::negation< optional_internal:: is_constructible_convertible_assignable_from_optional< - T, U>>>::value>::type> + T, U> > >::value>::type> optional& operator=(optional<U>&& rhs) { if (rhs) { this->assign(std::move(*rhs)); diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index 7ef142cb..1846e695 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc @@ -27,6 +27,32 @@ #include "absl/meta/type_traits.h" #include "absl/strings/string_view.h" +// The following types help test an internal compiler error in GCC5 though +// GCC10. The case OptionalTest.InternalCompilerErrorInGcc5ToGcc10 crashes the +// compiler without a workaround. This test case should remain at the beginning +// of the file as the internal compiler error is sensitive to other constructs +// in this file. +template <class T, class...> +using GccIceHelper1 = T; +template <typename T> +struct GccIceHelper2 {}; +template <typename T> +class GccIce { + template <typename U, + typename SecondTemplateArgHasToExistForSomeReason = void, + typename DependentType = void, + typename = std::is_assignable<GccIceHelper1<T, DependentType>&, U>> + GccIce& operator=(GccIceHelper2<U> const&) {} +}; + +TEST(OptionalTest, InternalCompilerErrorInGcc5ToGcc10) { + GccIce<int> instantiate_ice_with_same_type_as_optional; + static_cast<void>(instantiate_ice_with_same_type_as_optional); + absl::optional<int> val1; + absl::optional<int> val2; + val1 = val2; +} + struct Hashable {}; namespace std { |