Index: libstdc++-v3/include/std/variant
===================================================================
--- libstdc++-v3/include/std/variant	(revision 242337)
+++ libstdc++-v3/include/std/variant	(working copy)
@@ -136,42 +136,11 @@
     struct __reserved_type_map_impl<const volatile _From, _To>
     { using type = add_cv_t<__reserved_type_map<_From, _To>>; };
 
-  // Stores a reference alternative as a... well, reference.
-  template<typename _Reference>
-    struct _Reference_storage
-    {
-      static_assert(is_reference_v<_Reference>,
-		    "BUG: _Reference should be a reference");
-
-      _Reference_storage(_Reference __ref) noexcept : _M_storage(__ref) { }
-
-      operator _Reference() noexcept
-      { return static_cast<_Reference>(_M_storage); }
-
-      _Reference _M_storage;
-    };
-
-  // Stores a void alternative, because it is not a regular type.
-  template<typename _Void>
-    struct _Void_storage { };
-
-  // Map from the alternative type to a non-qualified storage type.
-  template<typename _Alternative, typename = void>
-    struct __storage_type
-    { using type = _Alternative; };
-
+  // This abstraction might be useful for future features,
+  // e.g. boost::recursive_wrapper.
   template<typename _Alternative>
-    struct __storage_type<_Alternative,
-			  enable_if_t<is_reference_v<_Alternative>>>
-    { using type = _Reference_storage<_Alternative>; };
+    using __storage = _Alternative;
 
-  template<typename _Alternative>
-    struct __storage_type<_Alternative, enable_if_t<is_void_v<_Alternative>>>
-    { using type = _Void_storage<_Alternative>; };
-
-  template<typename _Type>
-    using __storage = typename __storage_type<_Type>::type;
-
   template<typename _Type, bool __is_literal = std::is_literal_type_v<_Type>>
     struct _Uninitialized;
 
@@ -201,37 +170,15 @@
 	  _M_storage;
     };
 
-  // Reverse mapping of __storage_type.
-  template<typename _Storage_type>
-    struct __alternative_type
-    {
-      static_assert(!is_reference_v<_Storage_type>,
-		    "BUG: _Storage_type should not be reference");
-      using type = _Storage_type;
-    };
-
-  template<typename _Reference>
-    struct __alternative_type<_Reference_storage<_Reference>>
-    { using type = _Reference; };
-
-  template<typename _Void>
-    struct __alternative_type<_Void_storage<_Void>>
-    { using type = _Void; };
-
   // Given a qualified storage type, return the desired reference.
-  // The qualified storage type is supposed to carry the variant object's
-  // qualifications and reference information, and the designated alternative's
-  // storage type.
-  // Returns the qualification-collapsed alternative references.
-  //
-  // For example, __get_alternative<_Reference_storage<int&&>&> returns int&.
+  // For example, variant<int>&& stores the int as __storage<int>, and
+  // _Qualified_storage will be __storage<int>&&.
   template<typename _Qualified_storage>
     decltype(auto)
     __get_alternative(void* __ptr)
     {
       using _Storage = decay_t<_Qualified_storage>;
-      using _Alternative = typename __alternative_type<_Storage>::type;
-      return __reserved_type_map<_Qualified_storage, _Alternative>(
+      return __reserved_type_map<_Qualified_storage, _Storage>(
 	*static_cast<_Storage*>(__ptr));
     }
 
@@ -969,6 +916,13 @@
 	variant<_Types...>>
     {
     private:
+      static_assert(sizeof...(_Types) > 0,
+		    "variant must have at least one alternative");
+      static_assert(!(std::is_reference_v<_Types> || ...),
+		    "variant must have no reference alternative");
+      static_assert(!(std::is_void_v<_Types> || ...),
+		    "variant must have no void alternative");
+
       using _Base = __detail::__variant::_Variant_base<_Types...>;
       using _Default_ctor_enabler =
 	_Enable_default_constructor<
@@ -1264,11 +1218,6 @@
         __get_storage(_Vp&& __v);
     };
 
-  // To honor algebraic data type, variant<> should be a bottom type, which
-  // is 0 (as opposed to a void type, which is 1). Use incomplete type to model
-  // bottom type.
-  template<> class variant<>;
-
   template<size_t _Np, typename... _Types>
     variant_alternative_t<_Np, variant<_Types...>>&
     get(variant<_Types...>& __v)
Index: libstdc++-v3/testsuite/20_util/variant/compile.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/variant/compile.cc	(revision 242337)
+++ libstdc++-v3/testsuite/20_util/variant/compile.cc	(working copy)
@@ -55,7 +55,6 @@
 {
   static_assert(is_default_constructible_v<variant<int, string>>, "");
   static_assert(is_default_constructible_v<variant<string, string>>, "");
-  static_assert(!is_default_constructible_v<variant<>>, "");
   static_assert(!is_default_constructible_v<variant<AllDeleted, string>>, "");
   static_assert(is_default_constructible_v<variant<string, AllDeleted>>, "");
 
@@ -124,14 +123,6 @@
   variant<int> a(allocator_arg, alloc);
   static_assert(!is_constructible_v<variant<AllDeleted>, allocator_arg_t, std::allocator<char>>, "");
   {
-    variant<int> b(allocator_arg, alloc, a);
-    static_assert(!is_constructible_v<variant<void>, allocator_arg_t, std::allocator<char>, const variant<void>&>, "");
-  }
-  {
-    variant<int> b(allocator_arg, alloc, std::move(a));
-    static_assert(!is_constructible_v<variant<void>, allocator_arg_t, std::allocator<char>, variant<void>&&>, "");
-  }
-  {
     variant<string, int> b(allocator_arg, alloc, "a");
     static_assert(!is_constructible_v<variant<string, string>, allocator_arg_t, std::allocator<char>, const char*>, "");
   }
@@ -169,12 +160,6 @@
     variant<DefaultNoexcept> a;
     static_assert(!noexcept(a = a), "");
   }
-
-  {
-    float f1 = 1.0f, f2 = 2.0f;
-    std::variant<float&> v1(f1);
-    v1 = f2;
-  }
 }
 
 void move_assign()
@@ -203,103 +188,13 @@
 
 void test_get()
 {
-  {
-    static_assert(is_same<decltype(get<0>(variant<int, string>())), int&&>::value, "");
-    static_assert(is_same<decltype(get<1>(variant<int, string>())), string&&>::value, "");
-    static_assert(is_same<decltype(get<1>(variant<int, string&>())), string&>::value, "");
-    static_assert(is_same<decltype(get<1>(variant<int, string&&>())), string&&>::value, "");
-    static_assert(is_same<decltype(get<1>(variant<int, const string>())), const string&&>::value, "");
-    static_assert(is_same<decltype(get<1>(variant<int, const string&>())), const string&>::value, "");
-    static_assert(is_same<decltype(get<1>(variant<int, const string&&>())), const string&&>::value, "");
+  static_assert(is_same<decltype(get<0>(variant<int, string>())), int&&>::value, "");
+  static_assert(is_same<decltype(get<1>(variant<int, string>())), string&&>::value, "");
+  static_assert(is_same<decltype(get<1>(variant<int, const string>())), const string&&>::value, "");
 
-    static_assert(is_same<decltype(get<int>(variant<int, string>())), int&&>::value, "");
-    static_assert(is_same<decltype(get<string>(variant<int, string>())), string&&>::value, "");
-    static_assert(is_same<decltype(get<string&>(variant<int, string&>())), string&>::value, "");
-    static_assert(is_same<decltype(get<string&&>(variant<int, string&&>())), string&&>::value, "");
-    static_assert(is_same<decltype(get<const string>(variant<int, const string>())), const string&&>::value, "");
-    static_assert(is_same<decltype(get<const string&>(variant<int, const string&>())), const string&>::value, "");
-    static_assert(is_same<decltype(get<const string&&>(variant<int, const string&&>())), const string&&>::value, "");
-  }
-  {
-    variant<int, string> a;
-    variant<int, string&> b;
-    variant<int, string&&> c;
-    variant<int, const string> d;
-    variant<int, const string&> e;
-    variant<int, const string&&> f;
-
-    static_assert(is_same<decltype(get<0>(a)), int&>::value, "");
-    static_assert(is_same<decltype(get<1>(a)), string&>::value, "");
-    static_assert(is_same<decltype(get<1>(b)), string&>::value, "");
-    static_assert(is_same<decltype(get<1>(c)), string&>::value, "");
-    static_assert(is_same<decltype(get<1>(e)), const string&>::value, "");
-    static_assert(is_same<decltype(get<1>(e)), const string&>::value, "");
-    static_assert(is_same<decltype(get<1>(f)), const string&>::value, "");
-
-    static_assert(is_same<decltype(get<int>(a)), int&>::value, "");
-    static_assert(is_same<decltype(get<string>(a)), string&>::value, "");
-    static_assert(is_same<decltype(get<string&>(b)), string&>::value, "");
-    static_assert(is_same<decltype(get<string&&>(c)), string&>::value, "");
-    static_assert(is_same<decltype(get<const string>(e)), const string&>::value, "");
-    static_assert(is_same<decltype(get<const string&>(e)), const string&>::value, "");
-    static_assert(is_same<decltype(get<const string&&>(f)), const string&>::value, "");
-
-    static_assert(is_same<decltype(get_if<0>(&a)), int*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&a)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&b)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&c)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&e)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&e)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&f)), const string*>::value, "");
-
-    static_assert(is_same<decltype(get_if<int>(&a)), int*>::value, "");
-    static_assert(is_same<decltype(get_if<string>(&a)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<string&>(&b)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<string&&>(&c)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<const string>(&e)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<const string&>(&e)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<const string&&>(&f)), const string*>::value, "");
-  }
-  {
-    const variant<int, string> a;
-    const variant<int, string&> b;
-    const variant<int, string&&> c;
-    const variant<int, const string> d;
-    const variant<int, const string&> e;
-    const variant<int, const string&&> f;
-
-    static_assert(is_same<decltype(get<0>(a)), const int&>::value, "");
-    static_assert(is_same<decltype(get<1>(a)), const string&>::value, "");
-    static_assert(is_same<decltype(get<1>(b)), string&>::value, "");
-    static_assert(is_same<decltype(get<1>(c)), string&>::value, "");
-    static_assert(is_same<decltype(get<1>(d)), const string&>::value, "");
-    static_assert(is_same<decltype(get<1>(e)), const string&>::value, "");
-    static_assert(is_same<decltype(get<1>(f)), const string&>::value, "");
-
-    static_assert(is_same<decltype(get<int>(a)), const int&>::value, "");
-    static_assert(is_same<decltype(get<string>(a)), const string&>::value, "");
-    static_assert(is_same<decltype(get<string&>(b)), string&>::value, "");
-    static_assert(is_same<decltype(get<string&&>(c)), string&>::value, "");
-    static_assert(is_same<decltype(get<const string>(d)), const string&>::value, "");
-    static_assert(is_same<decltype(get<const string&>(e)), const string&>::value, "");
-    static_assert(is_same<decltype(get<const string&&>(f)), const string&>::value, "");
-
-    static_assert(is_same<decltype(get_if<0>(&a)), const int*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&a)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&b)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&c)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&d)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&e)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<1>(&f)), const string*>::value, "");
-
-    static_assert(is_same<decltype(get_if<int>(&a)), const int*>::value, "");
-    static_assert(is_same<decltype(get_if<string>(&a)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<string&>(&b)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<string&&>(&c)), string*>::value, "");
-    static_assert(is_same<decltype(get_if<const string>(&d)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<const string&>(&e)), const string*>::value, "");
-    static_assert(is_same<decltype(get_if<const string&&>(&f)), const string*>::value, "");
-  }
+  static_assert(is_same<decltype(get<int>(variant<int, string>())), int&&>::value, "");
+  static_assert(is_same<decltype(get<string>(variant<int, string>())), string&&>::value, "");
+  static_assert(is_same<decltype(get<const string>(variant<int, const string>())), const string&&>::value, "");
 }
 
 void test_relational()
@@ -344,16 +239,6 @@
       void operator()(monostate) const {}
       void operator()(const int&) const {}
     };
-    variant<monostate, int&, const int&, int&&, const int&&> a;
-    const variant<monostate, int&, const int&, int&&, const int&&> b;
-    Visitor v;
-    const CVisitor u;
-    static_assert(is_same<void, decltype(visit(Visitor(), a))>::value, "");
-    static_assert(is_same<void, decltype(visit(Visitor(), b))>::value, "");
-    static_assert(is_same<void, decltype(visit(v, a))>::value, "");
-    static_assert(is_same<void, decltype(visit(v, b))>::value, "");
-    static_assert(is_same<void, decltype(visit(u, a))>::value, "");
-    static_assert(is_same<void, decltype(visit(u, b))>::value, "");
   }
   {
     struct Visitor
@@ -397,19 +282,6 @@
   }
 }
 
-void test_void()
-{
-  static_assert(is_same<int&&, decltype(get<int>(variant<int, void>()))>::value, "");
-  static_assert(!is_default_constructible_v<variant<void, int>>, "");
-  static_assert(!is_copy_constructible_v<variant<int, void>>, "");
-  static_assert(!is_move_constructible_v<variant<int, void>>, "");
-  static_assert(!is_copy_assignable_v<variant<int, void>>, "");
-  static_assert(!is_move_assignable_v<variant<int, void>>, "");
-  variant<int, void, string> v;
-  v = 3;
-  v = "asdf";
-}
-
 void test_pr77641()
 {
   struct X {
@@ -457,11 +329,4 @@
    variant<X> v7{allocator_arg, a, in_place<0>, il, x};
    variant<X> v8{allocator_arg, a, in_place<X>, il, x};
    variant<X> v9{allocator_arg, a, in_place<X>, 1};
-
-   std::variant<X&> vr0(x);
-   vr0 = x;
-   variant<X&> vr1{in_place<0>, x};
-   variant<X&> vr2{in_place<X&>, x};
-   variant<X&> vr3{allocator_arg, a, in_place<0>, x};
-   variant<X&> vr4{allocator_arg, a, in_place<X&>, x};
 }
