summaryrefslogtreecommitdiff
path: root/absl/types
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2022-03-03 06:35:20 -0800
committerGravatar dinord <dino.radakovich@gmail.com>2022-03-03 09:43:16 -0500
commitec33f404bb16564a9aea3044cd8504d6885165b0 (patch)
tree42df609290f44528dff6d780261cf849cc8e5fee /absl/types
parentdfc3fa9b5ae8b204ac83e3f06e4e8626f9bb2bc2 (diff)
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.h31
-rw-r--r--absl/types/optional_test.cc26
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 {