Commit ec33f404 by Abseil Team Committed by dinord

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
parent dfc3fa9b
...@@ -282,15 +282,16 @@ class optional : private optional_internal::optional_data<T>, ...@@ -282,15 +282,16 @@ class optional : private optional_internal::optional_data<T>,
optional& operator=(optional&& src) = default; optional& operator=(optional&& src) = default;
// Value assignment operators // Value assignment operators
template < template <typename U = T,
typename U = T, int&..., // Workaround an internal compiler error in GCC 5 to 10.
typename = typename std::enable_if<absl::conjunction< typename = typename std::enable_if<absl::conjunction<
absl::negation< absl::negation<
std::is_same<optional<T>, typename std::decay<U>::type>>, std::is_same<optional<T>, typename std::decay<U>::type> >,
absl::negation< absl::negation<absl::conjunction<
absl::conjunction<std::is_scalar<T>, std::is_scalar<T>,
std::is_same<T, typename std::decay<U>::type>>>, std::is_same<T, typename std::decay<U>::type> > >,
std::is_constructible<T, U>, std::is_assignable<T&, U>>::value>::type> std::is_constructible<T, U>,
std::is_assignable<T&, U> >::value>::type>
optional& operator=(U&& v) { optional& operator=(U&& v) {
this->assign(std::forward<U>(v)); this->assign(std::forward<U>(v));
return *this; return *this;
...@@ -298,13 +299,14 @@ class optional : private optional_internal::optional_data<T>, ...@@ -298,13 +299,14 @@ class optional : private optional_internal::optional_data<T>,
template < template <
typename U, typename U,
int&..., // Workaround an internal compiler error in GCC 5 to 10.
typename = typename std::enable_if<absl::conjunction< 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&>, std::is_constructible<T, const U&>, std::is_assignable<T&, const U&>,
absl::negation< absl::negation<
optional_internal:: optional_internal::
is_constructible_convertible_assignable_from_optional< is_constructible_convertible_assignable_from_optional<
T, U>>>::value>::type> T, U> > >::value>::type>
optional& operator=(const optional<U>& rhs) { optional& operator=(const optional<U>& rhs) {
if (rhs) { if (rhs) {
this->assign(*rhs); this->assign(*rhs);
...@@ -315,13 +317,14 @@ class optional : private optional_internal::optional_data<T>, ...@@ -315,13 +317,14 @@ class optional : private optional_internal::optional_data<T>,
} }
template <typename U, template <typename U,
int&..., // Workaround an internal compiler error in GCC 5 to 10.
typename = typename std::enable_if<absl::conjunction< typename = typename std::enable_if<absl::conjunction<
absl::negation<std::is_same<T, U>>, std::is_constructible<T, U>, absl::negation<std::is_same<T, U> >,
std::is_assignable<T&, U>, std::is_constructible<T, U>, std::is_assignable<T&, U>,
absl::negation< absl::negation<
optional_internal:: optional_internal::
is_constructible_convertible_assignable_from_optional< is_constructible_convertible_assignable_from_optional<
T, U>>>::value>::type> T, U> > >::value>::type>
optional& operator=(optional<U>&& rhs) { optional& operator=(optional<U>&& rhs) {
if (rhs) { if (rhs) {
this->assign(std::move(*rhs)); this->assign(std::move(*rhs));
......
...@@ -27,6 +27,32 @@ ...@@ -27,6 +27,32 @@
#include "absl/meta/type_traits.h" #include "absl/meta/type_traits.h"
#include "absl/strings/string_view.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 {}; struct Hashable {};
namespace std { namespace std {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment