Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 222448)
+++ gcc/cp/call.c	(working copy)
@@ -824,9 +824,16 @@ build_list_conv (tree type, tree ctor, int flags,
   /* But no narrowing conversions.  */
   flags |= LOOKUP_NO_NARROWING;
 
+  /* Rvalue references are metadata, not part of the array. */
+  if (TREE_CODE (elttype) == REFERENCE_TYPE)
+    {
+      if (cxx_dialect >= cxx1z && TYPE_REF_IS_RVALUE (elttype))
+	elttype = TREE_TYPE (elttype);
+      else
+	return NULL;
+    }
   /* Can't make an array of these types.  */
-  if (TREE_CODE (elttype) == REFERENCE_TYPE
-      || TREE_CODE (elttype) == FUNCTION_TYPE
+  if (TREE_CODE (elttype) == FUNCTION_TYPE
       || VOID_TYPE_P (elttype))
     return NULL;
 
@@ -6338,12 +6345,12 @@ convert_like_real (conversion *convs, tree expr, t
 
     case ck_list:
       {
-	/* Conversion to std::initializer_list<T>.  */
+	/* Conversion to std::initializer_list<T> or <T&&>.  */
 	tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
+	bool own = TREE_CODE (elttype) == REFERENCE_TYPE;
 	tree new_ctor = build_constructor (init_list_type_node, NULL);
 	unsigned len = CONSTRUCTOR_NELTS (expr);
-	tree array, val, field;
-	vec<constructor_elt, va_gc> *vec = NULL;
+	tree array, val;
 	unsigned ix;
 
 	/* Convert all the elements.  */
@@ -6361,10 +6368,22 @@ convert_like_real (conversion *convs, tree expr, t
 	      TREE_CONSTANT (new_ctor) = false;
 	  }
 	/* Build up the array.  */
-	elttype = cp_build_qualified_type
-	  (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
-	array = build_array_of_n_type (elttype, len);
+	if (own)
+	  {
+	    elttype = TREE_TYPE (elttype);
+	    /* Don't let initializer_list<const T&&> lose ownership.  */
+	    array = cv_unqualified (elttype);
+	  }
+	else
+	  array = cp_build_qualified_type
+	    (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
+	array = build_array_of_n_type (array, len);
 	array = finish_compound_literal (array, new_ctor, complain);
+	/* If static, array is a trivially-destructible DECL, not a TARGET_EXPR.  */
+	if (own && TREE_STATIC (array)) gcc_assert (TYPE_HAS_TRIVIAL_DESTRUCTOR(elttype));
+	if (own && !TREE_STATIC (array))
+	  TARGET_EXPR_CLEANUP (array) = NULL; /* The library will handle destruction.  */
+
 	/* Take the address explicitly rather than via decay_conversion
 	   to avoid the error about taking the address of a temporary.  */
 	array = cp_build_addr_expr (array, complain);
@@ -6374,12 +6393,23 @@ convert_like_real (conversion *convs, tree expr, t
 
 	/* Build up the initializer_list object.  */
 	totype = complete_type (totype);
-	field = next_initializable_field (TYPE_FIELDS (totype));
-	CONSTRUCTOR_APPEND_ELT (vec, field, array);
-	field = next_initializable_field (DECL_CHAIN (field));
-	CONSTRUCTOR_APPEND_ELT (vec, field, size_int (len));
-	new_ctor = build_constructor (totype, vec);
-	return get_target_expr_sfinae (new_ctor, complain);
+	
+	for (new_ctor = lookup_fnfields_slot (totype, complete_ctor_identifier);
+	     new_ctor; new_ctor = OVL_NEXT (new_ctor))
+	  {
+	    tree parm = FUNCTION_FIRST_USER_PARM (OVL_CURRENT (new_ctor));
+	    if (parm && TREE_CODE (TREE_TYPE (parm)) == POINTER_TYPE)
+	      break;
+	  }
+	gcc_assert (new_ctor);
+	new_ctor = OVL_CURRENT (new_ctor);
+	maybe_instantiate_noexcept (new_ctor);
+	new_ctor = build_call_n (new_ctor, 3, build_this (build_dummy_object (totype)),
+	                         array, size_int (len));
+	new_ctor = build_cplus_new (totype, new_ctor, complain);
+	if (TYPE_HAS_TRIVIAL_DESTRUCTOR (elttype))
+	  TARGET_EXPR_CLEANUP (new_ctor) = NULL; /* Trivialize destruction of the list object.  */
+	return new_ctor;
       }
 
     case ck_aggr:
@@ -8449,7 +8479,31 @@ compare_ics (conversion *ics1, conversion *ics2)
     return 1;
   if (ics2->kind == ck_list && ics1->kind != ck_list)
     return -1;
+  /* Prefer conversion to an owning or non-owning list depending on
+     availability of move semantics.  */
+  if (cxx_dialect >= cxx1z && ics1->kind == ck_list && ics2->kind == ck_list)
+    {
+      tree t1 = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (ics1->type), 0);
+      tree t2 = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (ics2->type), 0);
+      
+      if ((TREE_CODE (t1) == REFERENCE_TYPE)
+          != (TREE_CODE (t2) == REFERENCE_TYPE))
+	{
+	  bool type1_ref = TREE_CODE (t1) == REFERENCE_TYPE;
+    	  tree r = type1_ref? t1 : t2;
+    	  tree e = type1_ref? t2 : t1;
 
+    	  if (same_type_p (TREE_TYPE (r),e) && TYPE_REF_IS_RVALUE(r))
+    	    {
+	      if ((!CP_TYPE_CONST_P (e) && TYPE_HAS_COMPLEX_MOVE_CTOR (e))
+	          == type1_ref)
+	        return 1;
+	      else
+	        return -1;
+	    }
+	}
+    }
+
   /* [over.ics.rank]
 
      When  comparing  the  basic forms of implicit conversion sequences (as
@@ -9649,13 +9703,12 @@ set_up_extended_ref_temp (tree decl, tree expr, ve
     {
       add_decl_expr (var);
 
-      if (TREE_STATIC (var))
-	init = add_stmt_to_compound (init, register_dtor_fn (var));
-      else
+      if (TARGET_EXPR_CLEANUP (expr))
 	{
-	  tree cleanup = cxx_maybe_build_cleanup (var, tf_warning_or_error);
-	  if (cleanup)
-	    vec_safe_push (*cleanups, cleanup);
+	  if (TREE_STATIC (var))
+	    init = add_stmt_to_compound (init, register_dtor_fn (var));
+	  else
+	    vec_safe_push (*cleanups, build_cleanup (var));
 	}
 
       /* We must be careful to destroy the temporary only
@@ -9680,7 +9733,7 @@ set_up_extended_ref_temp (tree decl, tree expr, ve
   else
     {
       rest_of_decl_compilation (var, /*toplev=*/1, at_eof);
-      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+      if (TARGET_EXPR_CLEANUP (expr))
 	{
 	  if (DECL_THREAD_LOCAL_P (var))
 	    tls_aggregates = tree_cons (NULL_TREE, var,
@@ -9797,23 +9850,26 @@ tree
 extend_ref_init_temps (tree decl, tree init, vec<tree, va_gc> **cleanups)
 {
   tree type = TREE_TYPE (init);
+  tree ctor = init;
   if (processing_template_decl)
     return init;
-  if (TREE_CODE (type) == REFERENCE_TYPE)
+  if (TREE_CODE (ctor) == TARGET_EXPR)
+    ctor = TARGET_EXPR_INITIAL (ctor);
+  else if (TREE_CODE (type) == REFERENCE_TYPE)
     init = extend_ref_init_temps_1 (decl, init, cleanups);
-  else if (is_std_init_list (type))
+  if (TREE_CODE (ctor) == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (ctor)
+      && aggr_init_expr_nargs(ctor) == 3)
     {
       /* The temporary array underlying a std::initializer_list
 	 is handled like a reference temporary.  */
-      tree ctor = init;
-      if (TREE_CODE (ctor) == TARGET_EXPR)
-	ctor = TARGET_EXPR_INITIAL (ctor);
-      if (TREE_CODE (ctor) == CONSTRUCTOR)
-	{
-	  tree array = CONSTRUCTOR_ELT (ctor, 0)->value;
+      tree il_this = AGGR_INIT_EXPR_ARG (ctor, 0);
+      if (TREE_CODE (TREE_TYPE (il_this)) == POINTER_TYPE
+          && is_std_init_list (TREE_TYPE (TREE_TYPE (il_this))))
+        {
+	  tree array = AGGR_INIT_EXPR_ARG (ctor, 1);
 	  array = extend_ref_init_temps_1 (decl, array, cleanups);
-	  CONSTRUCTOR_ELT (ctor, 0)->value = array;
-	}
+	  AGGR_INIT_EXPR_ARG (ctor, 1) = array;
+        }
     }
   else if (TREE_CODE (init) == CONSTRUCTOR)
     {
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	(revision 222448)
+++ gcc/cp/class.c	(working copy)
@@ -6883,16 +6883,23 @@ finish_struct (tree t, tree attributes)
       /* People keep complaining that the compiler crashes on an invalid
 	 definition of initializer_list, so I guess we should explicitly
 	 reject it.  What the compiler internals care about is that it's a
-	 template and has a pointer field followed by an integer field.  */
+	 template and has a pointer field followed by an integer field,
+	 or that it's derived from a preexisting initializer_list.  */
       bool ok = false;
       if (processing_template_decl)
 	{
-	  tree f = next_initializable_field (TYPE_FIELDS (t));
-	  if (f && TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE)
+	  tree f = TYPE_BINFO (t);
+	  if (BINFO_N_BASE_BINFOS (f) == 1)
+	    ok = is_std_init_list (BINFO_TYPE (BINFO_BASE_BINFO (f, 0)));
+	  else
 	    {
-	      f = next_initializable_field (DECL_CHAIN (f));
-	      if (f && same_type_p (TREE_TYPE (f), size_type_node))
-		ok = true;
+	      f = next_initializable_field (TYPE_FIELDS (t));
+	      if (f && TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE)
+		{
+		  f = next_initializable_field (DECL_CHAIN (f));
+		  if (f && same_type_p (TREE_TYPE (f), size_type_node))
+		    ok = true;
+		}
 	    }
 	}
       if (!ok)
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 222448)
+++ gcc/cp/decl.c	(working copy)
@@ -6655,9 +6655,17 @@ cp_finish_decl (tree decl, tree init, bool init_co
 	   so that we can decide later to emit debug info for them.  */
 	record_types_used_by_current_var_decl (decl);
     }
-  else if (TREE_CODE (decl) == FIELD_DECL
-	   && TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
-    error ("non-static data member %qD has Java class type", decl);
+  else if (TREE_CODE (decl) == FIELD_DECL)
+    {
+      if (TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
+	error ("non-static data member %qD has Java class type", decl);
+      if (cxx_dialect >= cxx1z && is_std_init_list (TREE_TYPE (decl)))
+	{
+	  tree il_arg = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (TREE_TYPE (decl)), 0);
+	  if (TREE_CODE (il_arg) == REFERENCE_TYPE && TYPE_REF_IS_RVALUE (il_arg))
+	    error ("non-static data member %qD cannot own an initializer list", decl);
+	}
+    }
 
   /* Add this declaration to the statement-tree.  This needs to happen
      after the call to check_initializer so that the DECL_EXPR for a
Index: gcc/cp/init.c
===================================================================
--- gcc/cp/init.c	(revision 222448)
+++ gcc/cp/init.c	(working copy)
@@ -662,15 +662,15 @@ perform_member_init (tree member, tree init)
 	}
     }
   else if (init
-	   && (TREE_CODE (type) == REFERENCE_TYPE
+	   && (is_std_init_list (type)
+	       ||TREE_CODE (type) == REFERENCE_TYPE
 	       /* Pre-digested NSDMI.  */
 	       || (((TREE_CODE (init) == CONSTRUCTOR
 		     && TREE_TYPE (init) == type)
 		    /* { } mem-initializer.  */
 		    || (TREE_CODE (init) == TREE_LIST
 			&& DIRECT_LIST_INIT_P (TREE_VALUE (init))))
-		   && (CP_AGGREGATE_TYPE_P (type)
-		       || is_std_init_list (type)))))
+		   && CP_AGGREGATE_TYPE_P (type))))
     {
       /* With references and list-initialization, we need to deal with
 	 extending temporary lifetimes.  12.2p5: "A temporary bound to a
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 222448)
+++ gcc/cp/pt.c	(working copy)
@@ -17850,6 +17850,8 @@ unify (tree tparms, tree targs, tree parm, tree ar
       else
 	{
 	  elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
+	  if (TREE_CODE (elttype) == REFERENCE_TYPE)
+	    elttype = TREE_TYPE (elttype);
 	  /* Deduction is defined in terms of a single type, so just punt
 	     on the (bizarre) std::initializer_list<T...>.  */
 	  if (PACK_EXPANSION_P (elttype))
Index: gcc/cp/search.c
===================================================================
--- gcc/cp/search.c	(revision 222448)
+++ gcc/cp/search.c	(working copy)
@@ -935,6 +935,11 @@ accessible_p (tree type, tree decl, bool consider_
       /* Now, loop through the classes of which we are a friend.  */
       if (!protected_ok)
 	protected_ok = friend_accessible_p (scope, decl, binfo);
+
+      /* Give initializer_list a free pass to call all destructors.
+	 Actual destructor access is checked at the point of array creation.  */
+      if (!protected_ok && ct && is_std_init_list (ct))
+        return 1;
     }
 
   /* Standardize the binfo that access_in_type will use.  We don't
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 222448)
+++ gcc/cp/semantics.c	(working copy)
@@ -7477,6 +7477,15 @@ trait_expr_value (cp_trait_kind kind, tree type1,
 
     case CPTK_HAS_TRIVIAL_DESTRUCTOR:
       type1 = strip_array_types (type1);
+      if (is_std_init_list (type1))
+        {
+          type1 = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (type1), 0);
+          if (TREE_CODE (type1) == REFERENCE_TYPE && TYPE_REF_IS_RVALUE (type1))
+            /* An owning initializer_list is trivially-destructible if its sequence is.  */
+            return trait_expr_value (CPTK_HAS_TRIVIAL_DESTRUCTOR, TREE_TYPE (type1), type2);
+          else
+            return true; /* Non-owning initializer lists are trivially-destructible.  */
+        }
       return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
 	      || (CLASS_TYPE_P (type1)
 		  && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 222448)
+++ gcc/cp/typeck.c	(working copy)
@@ -8570,8 +8570,16 @@ check_return_expr (tree retval, bool *no_warning)
        value.  */
     current_function_returns_null = 1;
   else
-    /* Remember that this function did return a value.  */
-    current_function_returns_value = 1;
+    {
+      if (cxx_dialect >= cxx1z && is_std_init_list (valtype))
+        {
+          tree il_arg = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (valtype), 0);
+	  if (TREE_CODE (il_arg) == REFERENCE_TYPE && TYPE_REF_IS_RVALUE (il_arg))
+	    error ("return value of owning initializer list type %qT", valtype);
+	}
+      /* Remember that this function did return a value.  */
+      current_function_returns_value = 1;
+    }
 
   /* Check for erroneous operands -- but after giving ourselves a
      chance to provide an error about returning a value from a void
Index: gcc/testsuite/g++.dg/cpp0x/pr57101.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/pr57101.C	(revision 222448)
+++ gcc/testsuite/g++.dg/cpp0x/pr57101.C	(working copy)
@@ -174,6 +174,9 @@ namespace std
     typedef _E *iterator;
     iterator _M_array;
     size_type _M_len;
+
+    explicit initializer_list (_E *i, size_t l)
+      : _M_array(i), _M_len(l) {}
   };
   template
     <
Index: gcc/testsuite/g++.dg/cpp1z/initlist-owned.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1z/initlist-owned.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp1z/initlist-owned.C	(working copy)
@@ -0,0 +1,90 @@
+// {dg-do run}
+// {dg-options -c++1z -pedantic}
+
+#include <initializer_list>
+extern "C" void exit( int );
+template< typename t >
+t && move( t & o ) { return static_cast< t && >( o ); }
+
+#include <iostream>
+
+static unsigned long long check = 0, expect = 0;
+
+struct final_result {
+    ~final_result() {
+    	std::cout << '\n';
+        exit( check ^ expect );
+    }
+} g;
+
+struct checkpoint {
+    int n;
+    char c = '_';
+    
+    checkpoint( int inn, char inc = '_' ) : n( inn ), c( inc ) {}
+    
+    ~checkpoint() {
+        std::cout << c;
+        
+        check *= 4;
+        expect *= 4;
+        expect += n;
+    }
+};
+
+struct checkobj {
+    char c = '-';
+    
+    checkobj( char inc = '-' ) : c( inc ) {}
+    
+    ~checkobj() { std::cout << c; check += 1; }
+};
+
+#if __cplusplus > 201402
+typedef checkobj && checkobjrr;
+#else
+typedef checkobj checkobjrr;
+#endif
+
+std::initializer_list< checkobjrr > s1 { {'B'}, {'B'}, {'B'} };
+checkpoint c1 { 0, 'a' };
+
+std::initializer_list< checkobjrr > s2( move( s1 ) );
+checkpoint c2 { 3, 'b' };
+
+struct {
+    std::initializer_list< checkobjrr > && s4;
+    checkpoint c4;
+    std::initializer_list< std::initializer_list< checkobjrr > > && s5;
+    checkpoint c5;
+} cs { { {'C'}, {'C'} }, {2, 'c'}, { { {'D'}, {'D'} }, { {'D'} } }, {3, 'd'} };
+
+struct {
+    std::initializer_list< checkobjrr > && s6 = { {'Z'} };
+    checkpoint && c6 = {1, 'z'};
+} cx;
+
+void fn( std::initializer_list< checkobjrr > s, int n ) {
+    if ( n ) fn( move( s ), n - 1 );
+    checkpoint { n? 0 : (int) s.size() };
+}
+
+void fr( std::initializer_list< checkobjrr > const & ) {}
+
+void fv( std::initializer_list< checkobj > ) {}
+
+template< typename e >
+void ft( std::initializer_list< e > ) {}
+
+int main() {
+    fn( { {} }, 1 );
+    
+    std::initializer_list< checkobjrr > s7 { {}, {} };
+    checkpoint c7 { 0 };
+    
+    fr( move( s7 ) );
+    checkpoint { 0 }; // 7
+    fv( move( s7 ) );
+    checkpoint { 2 }; // 8
+    ft( move( s7 ) );
+}

Property changes on: gcc/testsuite/g++.dg/cpp1z/initlist-owned.C
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: libstdc++-v3/libsupc++/initializer_list
===================================================================
--- libstdc++-v3/libsupc++/initializer_list	(revision 222448)
+++ libstdc++-v3/libsupc++/initializer_list	(working copy)
@@ -54,18 +54,24 @@ namespace std
       typedef const _E* 	iterator;
       typedef const _E* 	const_iterator;
 
-    private:
-      iterator			_M_array;
+    protected:
+      _E*			_M_array;
       size_type			_M_len;
 
       // The compiler can call a private constructor.
-      constexpr initializer_list(const_iterator __a, size_type __l)
+      constexpr initializer_list(_E *__a, size_type __l) noexcept
       : _M_array(__a), _M_len(__l) { }
 
     public:
       constexpr initializer_list() noexcept
       : _M_array(0), _M_len(0) { }
 
+      constexpr initializer_list(initializer_list &&) noexcept = default;
+      constexpr initializer_list(const initializer_list &) noexcept = default;
+      
+      initializer_list &operator = (initializer_list &) = delete;
+      initializer_list &operator = (initializer_list &&) = delete;
+
       // Number of elements.
       constexpr size_type
       size() const noexcept { return _M_len; }
@@ -98,6 +104,87 @@ namespace std
     constexpr const _Tp*
     end(initializer_list<_Tp> __ils) noexcept
     { return __ils.end(); }
+
+#if __cplusplus > 201402
+  template<class _E>
+    class initializer_list<_E &&>
+    : public initializer_list<_E>
+    {
+    private:
+      using initializer_list<_E>::initializer_list;
+
+    public:
+      typedef _E& 		reference;
+      typedef _E*	 	iterator;
+
+      constexpr initializer_list() noexcept = default;
+
+      // This class supports moving but not copying.
+      constexpr initializer_list(initializer_list &&__o) noexcept
+      : initializer_list<_E>(__o)
+      { __o._M_len = 0; }
+
+      initializer_list(const initializer_list &) = delete;
+
+      ~initializer_list() noexcept(noexcept(iterator()->~_E()))
+      {
+	for (iterator __i = end(); __i != begin(); --__i)
+	  __i[-1].~_E();
+      }
+
+      // Add write access to the base accessor interface.
+      using initializer_list<_E>::begin;
+      
+      constexpr iterator
+      begin() noexcept { return this->_M_array; }
+
+      using initializer_list<_E>::end;
+      
+      constexpr iterator
+      end() noexcept { return begin() + this->size(); }
+    };
+
+  /**
+   *  @brief  Return an iterator pointing to the first element of
+   *          the initializer_list.
+   *  @param  __ils  Initializer list.
+   */
+  template<class _Tp>
+    constexpr _Tp*
+    begin(initializer_list<_Tp &&> &__ils) noexcept
+    { return __ils.begin(); }
+
+  template<class _Tp>
+    constexpr _Tp*
+    begin(initializer_list<_Tp &&> &&__ils) noexcept
+    { return __ils.begin(); }
+
+  template<class _Tp>
+    constexpr const _Tp*
+    begin(const initializer_list<_Tp &&> &__ils) noexcept
+    { return __ils.begin(); }
+
+  /**
+   *  @brief  Return an iterator pointing to one past the last element
+   *          of the initializer_list.
+   *  @param  __ils  Initializer list.
+   */
+  template<class _Tp>
+    constexpr _Tp*
+    end(initializer_list<_Tp &&> &__ils) noexcept
+    { return __ils.end(); }
+
+  template<class _Tp>
+    constexpr _Tp*
+    end(initializer_list<_Tp &&> &&__ils) noexcept
+    { return __ils.end(); }
+
+  template<class _Tp>
+    constexpr const _Tp*
+    end(const initializer_list<_Tp &&> &__ils) noexcept
+    { return __ils.end(); }
+#endif
+
 }
 
 #pragma GCC visibility pop
Index: libstdc++-v3/testsuite/20_util/is_assignable/value.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/is_assignable/value.cc	(revision 222448)
+++ libstdc++-v3/testsuite/20_util/is_assignable/value.cc	(working copy)
@@ -186,19 +186,34 @@ static_assert(!std::is_assignable<void*&, bool>::v
 static_assert(!std::is_assignable<E&, bool>::value, "Error");
 static_assert(!std::is_assignable<SE&, bool>::value, "Error");
 
-static_assert(std::is_assignable<std::initializer_list<int>&,
+static_assert(!std::is_assignable<std::initializer_list<int>&,
 std::initializer_list<int>>::value, "Error");
-static_assert(std::is_assignable<std::initializer_list<int>&,
+static_assert(!std::is_assignable<std::initializer_list<int>&,
 std::initializer_list<int>&&>::value, "Error");
-static_assert(std::is_assignable<std::initializer_list<int>&, const
+static_assert(!std::is_assignable<std::initializer_list<int>&, const
 std::initializer_list<int>&&>::value, "Error");
-static_assert(std::is_assignable<std::initializer_list<int>&,
+static_assert(!std::is_assignable<std::initializer_list<int>&,
 std::initializer_list<int>&>::value, "Error");
-static_assert(std::is_assignable<std::initializer_list<int>&, const
+static_assert(!std::is_assignable<std::initializer_list<int>&, const
 std::initializer_list<int>&>::value, "Error");
 static_assert(!std::is_assignable<const std::initializer_list<int>&,
 std::initializer_list<int>>::value, "Error");
 
+#if __cplusplus > 201402
+static_assert(std::is_assignable<std::initializer_list<int&&>&,
+std::initializer_list<int&&>>::value, "Error");
+static_assert(std::is_assignable<std::initializer_list<int&&>&,
+std::initializer_list<int&&>&&>::value, "Error");
+static_assert(!std::is_assignable<std::initializer_list<int&&>&, const
+std::initializer_list<int&&>&&>::value, "Error");
+static_assert(!std::is_assignable<std::initializer_list<int&&>&,
+std::initializer_list<int&&>&>::value, "Error");
+static_assert(!std::is_assignable<std::initializer_list<int&&>&, const
+std::initializer_list<int&&>&>::value, "Error");
+static_assert(!std::is_assignable<const std::initializer_list<int&&>&,
+std::initializer_list<int&&>>::value, "Error");
+#endif
+
 static_assert(!std::is_assignable<const AnyAssign&, int>::value, "Error");
 static_assert(!std::is_assignable<AnyAssign&, void>::value, "Error");
 
Index: libstdc++-v3/testsuite/util/testsuite_random.h
===================================================================
--- libstdc++-v3/testsuite/util/testsuite_random.h	(revision 222448)
+++ libstdc++-v3/testsuite/util/testsuite_random.h	(working copy)
@@ -111,10 +111,10 @@ namespace __gnu_test
 #endif
 
   inline double
-  discrete_pdf(int k, std::initializer_list<double> wl)
+  discrete_pdf(int k, std::initializer_list<double> inw)
   {
-    if (!wl.size())
-      wl = { 1.0 };
+    static std::initializer_list<double> w1 = { 1.0 };
+    std::initializer_list<double> wl = inw.size()? inw : w1;
 
     if (k < 0 || (std::size_t)k >= wl.size())
       return 0.0;
