From 8af2fec40bfd6889ab47b47d0a9cfaa5102c2507 Mon Sep 17 00:00:00 2001
From: Russell Yanofsky <russ@yanofsky.org>
Date: Thu, 31 May 2007 01:18:22 +0000
Subject: [PATCH] re PR c++/7412 ([DR 106] References to references)

2007-05-30  Russell Yanofsky <russ@yanofsky.org>
            Douglas Gregor <doug.gregor@gmail.com>
            Pedro Lamarao <pedro.lamarao@mndfck.org>
            Howard Hinnant <howard.hinnant@gmail.com>

	PR c++/7412
	PR c++/29939
        * g++.dg/cpp0x/rv8p.C: New.
        * g++.dg/cpp0x/temp-constructor-bug.C: New.
        * g++.dg/cpp0x/cast-bug.C: New.
        * g++.dg/cpp0x/elision_weak.C: New.
        * g++.dg/cpp0x/collapse-bug.C: New.
        * g++.dg/cpp0x/rv3p.C: New.
        * g++.dg/cpp0x/rv7n.C: New.
        * g++.dg/cpp0x/overload-conv-1.C: New.
        * g++.dg/cpp0x/rv2n.C: New.
        * g++.dg/cpp0x/deduce.C: New.
        * g++.dg/cpp0x/temp-va-arg-bug.C: New.
        * g++.dg/cpp0x/rv6p.C: New.
        * g++.dg/cpp0x/template_deduction.C: New.
        * g++.dg/cpp0x/implicit-copy.C: New.
        * g++.dg/cpp0x/rv1p.C: New.
        * g++.dg/cpp0x/cast.C: New.
        * g++.dg/cpp0x/rv5n.C: New.
        * g++.dg/cpp0x/collapse.C: New.
        * g++.dg/cpp0x/overload-conv-2.C: New.
        * g++.dg/cpp0x/rv4p.C: New.
	* g++.dg/cpp0x/rvo.C: New.
        * g++.dg/cpp0x/iop.C: New.
        * g++.dg/cpp0x/rv3n.C: New.
        * g++.dg/cpp0x/rv7p.C: New.
        * g++.dg/cpp0x/reference_collapsing.C: New.
        * g++.dg/cpp0x/overload.C: New.
        * g++.dg/cpp0x/named.C: New.
        * g++.dg/cpp0x/rv2p.C: New.
        * g++.dg/cpp0x/rv6n.C: New.
        * g++.dg/cpp0x/not_special.C: New.
        * g++.dg/cpp0x/bind.C: New.
        * g++.dg/cpp0x/rv1n.C: New.
        * g++.dg/cpp0x/rv5p.C: New.
        * g++.dg/cpp0x/elision.C: New.
        * g++.dg/cpp0x/named_refs.C: New.
        * g++.dg/cpp0x/unnamed_refs.C: New.
        * g++.dg/cpp0x/rv4n.C: New.
        * g++.dg/cpp0x/elision_neg.C: New.
        * g++.dg/init/copy7.C: Run in C++98 mode.
        * g++.dg/overload/arg1.C: Ditto.
        * g++.dg/overload/arg4.C: Ditto.

2007-05-30  Russell Yanofsky <russ@yanofsky.org>
            Douglas Gregor <doug.gregor@gmail.com>
            Pedro Lamarao <pedro.lamarao@mndfck.org>
            Howard Hinnant <howard.hinnant@gmail.com>

	PR c++/7412
	PR c++/29939
	* typeck.c (comptypes): Don't consider rvalue and lvalue
	reference types to be equivalent.
	(check_return_expr): Move from certain lvalues when returning
	them.
	* decl.c (grokdeclarator): Implement reference collapsing.
	(copy_fn_p): Don't consider constructors taking rvalue references
	to be copy constructors.
	(move_fn_p): New.
        * call.c (conversion): New "rvaluedness_matches_p" member.
	(convert_class_to_reference): Require reference type as first
	parameter instead of base type.
	(reference_binding): Add logic to handle rvalue references.
	(implicit_conversion): Update inaccurate comment.
	(convert_like_real): Disable creation of temporaries that are
	impossible to initialize for types with move constructors.
	(build_over_call): Elide move constructors when possible.
	(maybe_handle_implicit_object): Set "rvaluedness_matches_p".
	(maybe_handle_ref_bind): Return conversion instead of type node.
	(compare_ics): Add logic to use "rvaluedness_matches_p" values to
	determine preferred conversion sequences.
	* cp-tree.h (TYPE_REF_IS_RVALUE): New.
	(LOOKUP_PREFER_RVALUE): New.
	(DECL_MOVE_CONSTRUCTOR_P): New.
	(struct cp_declarator): Add "reference" member for reference
	types, with new "rvalue_ref" flag.
	(cp_build_reference_type): Declare.
	(move_fn_p): Declare.
	* error.c (dump_type_prefix): Format rvalue reference types
	correctly in error messages.
	* except.c (build_throw): Move from certain lvalues when
	throwing.
	* mangle.c (write_type): Mangle rvalue references differently
	than regular references.
	* parser.c (make_reference_declarator): Add boolean parameter for
	rvalue references.
	(cp_parser_make_indirect_declarator): New.
	(cp_parser_new_declarator_opt): Call
	cp_parser_make_indirect_declarator.
	(cp_parser_conversion_declarator_opt): Ditto.
	(cp_parser_declarator): Ditto.
	(cp_parser_ptr_operator): Parse "&&" tokens into rvalue reference
	declarators.
	* pt.c (tsubst): Implement reference collapsing.
	(maybe_adjust_types_for_deduction): Implement special template
	parameter deduction rule for rvalue references.
	(type_unification_real): Update calls to
	maybe_adjust_types_for_deduction.
	(try_one_overload): Ditto.
	(unify_pack_expansion): Ditto.
	* tree.c (lvalue_p_1): Handle rvalue reference types.
	(cp_build_reference_type): New.

From-SVN: r125211
---
 ChangeLog                                     |    1 +
 gcc/cp/ChangeLog                              |   59 +
 gcc/cp/call.c                                 |  110 +-
 gcc/cp/cp-tree.h                              |   23 +-
 gcc/cp/decl.c                                 |  107 +-
 gcc/cp/error.c                                |   10 +-
 gcc/cp/except.c                               |   15 +-
 gcc/cp/mangle.c                               |    6 +
 gcc/cp/parser.c                               |   98 +-
 gcc/cp/pt.c                                   |   55 +-
 gcc/cp/tree.c                                 |   69 +-
 gcc/cp/typeck.c                               |   52 +-
 gcc/testsuite/ChangeLog                       |   49 +
 gcc/testsuite/g++.dg/cpp0x/bind.C             |    8 +
 gcc/testsuite/g++.dg/cpp0x/cast-bug.C         |   14 +
 gcc/testsuite/g++.dg/cpp0x/cast.C             |   30 +
 gcc/testsuite/g++.dg/cpp0x/collapse-bug.C     |   16 +
 gcc/testsuite/g++.dg/cpp0x/collapse.C         |   38 +
 gcc/testsuite/g++.dg/cpp0x/deduce.C           |   36 +
 gcc/testsuite/g++.dg/cpp0x/elision.C          |   76 +
 gcc/testsuite/g++.dg/cpp0x/elision_neg.C      |   44 +
 gcc/testsuite/g++.dg/cpp0x/elision_weak.C     |   19 +
 gcc/testsuite/g++.dg/cpp0x/implicit-copy.C    |   15 +
 gcc/testsuite/g++.dg/cpp0x/iop.C              |   41 +
 gcc/testsuite/g++.dg/cpp0x/named.C            |   35 +
 gcc/testsuite/g++.dg/cpp0x/named_refs.C       |   28 +
 gcc/testsuite/g++.dg/cpp0x/not_special.C      |   54 +
 gcc/testsuite/g++.dg/cpp0x/overload-conv-1.C  |   29 +
 gcc/testsuite/g++.dg/cpp0x/overload-conv-2.C  |   17 +
 gcc/testsuite/g++.dg/cpp0x/overload.C         |  703 ++++++++
 .../g++.dg/cpp0x/reference_collapsing.C       |  175 ++
 gcc/testsuite/g++.dg/cpp0x/rv1n.C             |  149 ++
 gcc/testsuite/g++.dg/cpp0x/rv1p.C             |  154 ++
 gcc/testsuite/g++.dg/cpp0x/rv2n.C             |  370 ++++
 gcc/testsuite/g++.dg/cpp0x/rv2p.C             |  536 ++++++
 gcc/testsuite/g++.dg/cpp0x/rv3n.C             |  627 +++++++
 gcc/testsuite/g++.dg/cpp0x/rv3p.C             | 1120 ++++++++++++
 gcc/testsuite/g++.dg/cpp0x/rv4n.C             |  735 ++++++++
 gcc/testsuite/g++.dg/cpp0x/rv4p.C             | 1497 +++++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/rv5n.C             |  575 +++++++
 gcc/testsuite/g++.dg/cpp0x/rv5p.C             | 1283 ++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/rv6n.C             |  281 ++++
 gcc/testsuite/g++.dg/cpp0x/rv6p.C             |  695 ++++++++
 gcc/testsuite/g++.dg/cpp0x/rv7n.C             |   90 +
 gcc/testsuite/g++.dg/cpp0x/rv7p.C             |  234 +++
 gcc/testsuite/g++.dg/cpp0x/rv8p.C             |   62 +
 gcc/testsuite/g++.dg/cpp0x/rvo.C              |   25 +
 .../g++.dg/cpp0x/temp-constructor-bug.C       |   15 +
 gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C  |   10 +
 .../g++.dg/cpp0x/template_deduction.C         |   68 +
 gcc/testsuite/g++.dg/cpp0x/unnamed_refs.C     |   30 +
 gcc/testsuite/g++.dg/init/copy7.C             |    1 +
 gcc/testsuite/g++.dg/overload/arg1.C          |    1 +
 gcc/testsuite/g++.dg/overload/arg4.C          |    1 +
 54 files changed, 10486 insertions(+), 105 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/bind.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/cast-bug.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/cast.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/collapse-bug.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/collapse.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/deduce.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision_neg.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision_weak.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/implicit-copy.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/iop.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/named.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/named_refs.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/not_special.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/overload-conv-1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/overload-conv-2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/overload.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/reference_collapsing.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv1n.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv1p.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv2n.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv2p.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv3n.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv3p.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv4n.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv4p.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv5n.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv5p.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv6n.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv6p.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv7n.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv7p.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv8p.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rvo.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/temp-constructor-bug.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/template_deduction.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/unnamed_refs.C

diff --git a/ChangeLog b/ChangeLog
index 30a5c973815d..447556e95dc3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -457,6 +457,7 @@
 	install-gcc.
 	* Makefile.in: Regenerate.
 
+>>>>>>> .merge-right.r70
 2006-12-04  Richard Guenther  <rguenther@suse.de>
 
 	* MAINTAINERS (Non-Algorithmic Maintainers): New section.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c3d6b0b14e21..22171e4e347a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,62 @@
+2007-05-30  Russell Yanofsky <russ@yanofsky.org>
+            Douglas Gregor <doug.gregor@gmail.com>
+            Pedro Lamarao <pedro.lamarao@mndfck.org>
+            Howard Hinnant <howard.hinnant@gmail.com>
+
+	PR c++/7412
+	PR c++/29939
+	* typeck.c (comptypes): Don't consider rvalue and lvalue
+	reference types to be equivalent.
+	(check_return_expr): Move from certain lvalues when returning
+	them.
+	* decl.c (grokdeclarator): Implement reference collapsing.
+	(copy_fn_p): Don't consider constructors taking rvalue references
+	to be copy constructors.
+	(move_fn_p): New.
+        * call.c (conversion): New "rvaluedness_matches_p" member.
+	(convert_class_to_reference): Require reference type as first
+	parameter instead of base type.
+	(reference_binding): Add logic to handle rvalue references.
+	(implicit_conversion): Update inaccurate comment.
+	(convert_like_real): Disable creation of temporaries that are
+	impossible to initialize for types with move constructors.
+	(build_over_call): Elide move constructors when possible.
+	(maybe_handle_implicit_object): Set "rvaluedness_matches_p".
+	(maybe_handle_ref_bind): Return conversion instead of type node.
+	(compare_ics): Add logic to use "rvaluedness_matches_p" values to
+	determine preferred conversion sequences.
+	* cp-tree.h (TYPE_REF_IS_RVALUE): New.
+	(LOOKUP_PREFER_RVALUE): New.
+	(DECL_MOVE_CONSTRUCTOR_P): New.
+	(struct cp_declarator): Add "reference" member for reference
+	types, with new "rvalue_ref" flag.
+	(cp_build_reference_type): Declare.
+	(move_fn_p): Declare.
+	* error.c (dump_type_prefix): Format rvalue reference types
+	correctly in error messages.
+	* except.c (build_throw): Move from certain lvalues when
+	throwing.
+	* mangle.c (write_type): Mangle rvalue references differently
+	than regular references.
+	* parser.c (make_reference_declarator): Add boolean parameter for
+	rvalue references.
+	(cp_parser_make_indirect_declarator): New.
+	(cp_parser_new_declarator_opt): Call
+	cp_parser_make_indirect_declarator. 
+	(cp_parser_conversion_declarator_opt): Ditto.
+	(cp_parser_declarator): Ditto.
+	(cp_parser_ptr_operator): Parse "&&" tokens into rvalue reference
+	declarators.
+	* pt.c (tsubst): Implement reference collapsing.
+	(maybe_adjust_types_for_deduction): Implement special template
+	parameter deduction rule for rvalue references.
+	(type_unification_real): Update calls to
+	maybe_adjust_types_for_deduction.
+	(try_one_overload): Ditto.
+	(unify_pack_expansion): Ditto.
+	* tree.c (lvalue_p_1): Handle rvalue reference types.
+	(cp_build_reference_type): New.
+
 2007-05-30  Jakub Jelinek  <jakub@redhat.com>
 
 	PR c++/31809
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index abccb4e7e4e3..bf565fcb5eb2 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -97,6 +97,10 @@ struct conversion {
   /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion
      from a pointer-to-derived to pointer-to-base is being performed.  */
   BOOL_BITFIELD base_p : 1;
+  /* If KIND is ck_ref_bind, true when either an lvalue reference is
+     being bound to an lvalue expression or an rvalue reference is
+     being bound to an rvalue expression. */
+  BOOL_BITFIELD rvaluedness_matches_p: 1;
   /* The type of the expression resulting from the conversion.  */
   tree type;
   union {
@@ -176,7 +180,7 @@ static conversion *standard_conversion (tree, tree, tree, bool, int);
 static conversion *reference_binding (tree, tree, tree, bool, int);
 static conversion *build_conv (conversion_kind, tree, conversion *);
 static bool is_subseq (conversion *, conversion *);
-static tree maybe_handle_ref_bind (conversion **);
+static conversion *maybe_handle_ref_bind (conversion **);
 static void maybe_handle_implicit_object (conversion **);
 static struct z_candidate *add_candidate
 	(struct z_candidate **, tree, tree, size_t,
@@ -918,12 +922,12 @@ reference_compatible_p (tree t1, tree t2)
    converted to T as in [over.match.ref].  */
 
 static conversion *
-convert_class_to_reference (tree t, tree s, tree expr)
+convert_class_to_reference (tree reference_type, tree s, tree expr)
 {
   tree conversions;
   tree arglist;
   conversion *conv;
-  tree reference_type;
+  tree t;
   struct z_candidate *candidates;
   struct z_candidate *cand;
   bool any_viable_p;
@@ -957,7 +961,7 @@ convert_class_to_reference (tree t, tree s, tree expr)
   arglist = build_int_cst (build_pointer_type (s), 0);
   arglist = build_tree_list (NULL_TREE, arglist);
 
-  reference_type = build_reference_type (t);
+  t = TREE_TYPE (reference_type);
 
   while (conversions)
     {
@@ -1020,6 +1024,9 @@ convert_class_to_reference (tree t, tree s, tree expr)
 	      cand->second_conv
 		= (direct_reference_binding
 		   (reference_type, identity_conv));
+	      cand->second_conv->rvaluedness_matches_p
+		= TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn)))
+		  == TYPE_REF_IS_RVALUE (reference_type);
 	      cand->second_conv->bad_p |= cand->convs[0]->bad_p;
 	    }
 	}
@@ -1146,7 +1153,16 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
     to = build_qualified_type (to, cp_type_quals (from));
   compatible_p = reference_compatible_p (to, from);
 
-  if (lvalue_p && compatible_p)
+  /* Directly bind reference when target expression's type is compatible with
+     the reference and expression is an lvalue. In C++0x, the wording in
+     [8.5.3/5 dcl.init.ref] is changed to also allow direct bindings for const
+     and rvalue references to rvalues of compatible class type, as part of
+     DR391. */
+  if (compatible_p
+      && (lvalue_p
+	  || (flag_cpp0x
+	      && (CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto))
+	      && CLASS_TYPE_P (from))))
     {
       /* [dcl.init.ref]
 
@@ -1159,6 +1175,15 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
 	 lvalue.  */
       conv = build_identity_conv (from, expr);
       conv = direct_reference_binding (rto, conv);
+
+      if (flags & LOOKUP_PREFER_RVALUE)
+	/* The top-level caller requested that we pretend that the lvalue
+	   be treated as an rvalue.  */
+	conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
+      else
+	conv->rvaluedness_matches_p 
+          = (TYPE_REF_IS_RVALUE (rto) == !lvalue_p);
+
       if ((lvalue_p & clk_bitfield) != 0
 	  || ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to)))
 	/* For the purposes of overload resolution, we ignore the fact
@@ -1191,7 +1216,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
 
 	the reference is bound to the lvalue result of the conversion
 	in the second case.  */
-      conv = convert_class_to_reference (to, from, expr);
+      conv = convert_class_to_reference (rto, from, expr);
       if (conv)
 	return conv;
     }
@@ -1214,8 +1239,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
 
   /* [dcl.init.ref]
 
-     Otherwise, the reference shall be to a non-volatile const type.  */
-  if (!CP_TYPE_CONST_NON_VOLATILE_P (to))
+     Otherwise, the reference shall be to a non-volatile const type.
+
+     Under C++0x, [8.5.3/5 dcl.init.ref] it may also be an rvalue reference */
+  if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto))
     return NULL;
 
   /* [dcl.init.ref]
@@ -1238,6 +1265,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
     {
       conv = build_identity_conv (from, expr);
       conv = direct_reference_binding (rto, conv);
+      conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
       if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE))
 	conv->u.next->check_copy_constructor_p = true;
       return conv;
@@ -1262,6 +1290,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   /* This reference binding, unlike those above, requires the
      creation of a temporary.  */
   conv->need_temporary_p = true;
+  conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
 
   return conv;
 }
@@ -1303,7 +1332,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
 	conv = cand->second_conv;
 
       /* We used to try to bind a reference to a temporary here, but that
-	 is now handled by the recursive call to this function at the end
+	 is now handled after the recursive call to this function at the end
 	 of reference_binding.  */
       return conv;
     }
@@ -4448,13 +4477,22 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       {
 	tree ref_type = totype;
 
-	/* If necessary, create a temporary.  */
-	if (convs->need_temporary_p || !lvalue_p (expr))
+	/* If necessary, create a temporary. 
+
+           VA_ARG_EXPR and CONSTRUCTOR expressions are special cases
+           that need temporaries, even when their types are reference
+           compatible with the type of reference being bound, so the
+           upcoming call to build_unary_op (ADDR_EXPR, expr, ...)
+           doesn't fail.  */
+	if (convs->need_temporary_p
+	    || TREE_CODE (expr) == CONSTRUCTOR
+	    || TREE_CODE (expr) == VA_ARG_EXPR)
 	  {
 	    tree type = convs->u.next->type;
 	    cp_lvalue_kind lvalue = real_lvalue_p (expr);
 
-	    if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
+	    if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type))
+		&& !TYPE_REF_IS_RVALUE (ref_type))
 	      {
 		/* If the reference is volatile or non-const, we
 		   cannot create a temporary.  */
@@ -4963,7 +5001,9 @@ build_over_call (struct z_candidate *cand, int flags)
 
   if (! flag_elide_constructors)
     /* Do things the hard way.  */;
-  else if (cand->num_convs == 1 && DECL_COPY_CONSTRUCTOR_P (fn))
+  else if (cand->num_convs == 1 
+           && (DECL_COPY_CONSTRUCTOR_P (fn) 
+               || DECL_MOVE_CONSTRUCTOR_P (fn)))
     {
       tree targ;
       arg = argarray[num_artificial_parms_for (fn)];
@@ -5697,28 +5737,28 @@ maybe_handle_implicit_object (conversion **ics)
 	t = t->u.next;
       t = build_identity_conv (TREE_TYPE (t->type), NULL_TREE);
       t = direct_reference_binding (reference_type, t);
+      t->rvaluedness_matches_p = 1;
       *ics = t;
     }
 }
 
 /* If *ICS is a REF_BIND set *ICS to the remainder of the conversion,
-   and return the type to which the reference refers.  Otherwise,
-   leave *ICS unchanged and return NULL_TREE.  */
+   and return the initial reference binding conversion. Otherwise,
+   leave *ICS unchanged and return NULL.  */
 
-static tree
+static conversion *
 maybe_handle_ref_bind (conversion **ics)
 {
   if ((*ics)->kind == ck_ref_bind)
     {
       conversion *old_ics = *ics;
-      tree type = TREE_TYPE (old_ics->type);
       *ics = old_ics->u.next;
       (*ics)->user_conv_p = old_ics->user_conv_p;
       (*ics)->bad_p = old_ics->bad_p;
-      return type;
+      return old_ics;
     }
 
-  return NULL_TREE;
+  return NULL;
 }
 
 /* Compare two implicit conversion sequences according to the rules set out in
@@ -5742,18 +5782,18 @@ compare_ics (conversion *ics1, conversion *ics2)
   conversion_rank rank1, rank2;
 
   /* REF_BINDING is nonzero if the result of the conversion sequence
-     is a reference type.   In that case TARGET_TYPE is the
-     type referred to by the reference.  */
-  tree target_type1;
-  tree target_type2;
+     is a reference type.   In that case REF_CONV is the reference
+     binding conversion. */
+  conversion *ref_conv1;
+  conversion *ref_conv2;
 
   /* Handle implicit object parameters.  */
   maybe_handle_implicit_object (&ics1);
   maybe_handle_implicit_object (&ics2);
 
   /* Handle reference parameters.  */
-  target_type1 = maybe_handle_ref_bind (&ics1);
-  target_type2 = maybe_handle_ref_bind (&ics2);
+  ref_conv1 = maybe_handle_ref_bind (&ics1);
+  ref_conv2 = maybe_handle_ref_bind (&ics2);
 
   /* [over.ics.rank]
 
@@ -6044,15 +6084,31 @@ compare_ics (conversion *ics1, conversion *ics2)
 
   /* [over.ics.rank]
 
+     --S1 and S2 are reference bindings (_dcl.init.ref_) and neither refers
+     to an implicit object parameter, and either S1 binds an lvalue reference
+     to an lvalue and S2 binds an rvalue reference or S1 binds an rvalue
+     reference to an rvalue and S2 binds an lvalue reference
+     (C++0x draft standard, 13.3.3.2)
+
      --S1 and S2 are reference bindings (_dcl.init.ref_), and the
      types to which the references refer are the same type except for
      top-level cv-qualifiers, and the type to which the reference
      initialized by S2 refers is more cv-qualified than the type to
      which the reference initialized by S1 refers */
 
-  if (target_type1 && target_type2
+  if (ref_conv1 && ref_conv2
       && same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2))
-    return comp_cv_qualification (target_type2, target_type1);
+    {
+      if (ref_conv1->rvaluedness_matches_p
+	  && !ref_conv2->rvaluedness_matches_p)
+	return 1;
+      else if (!ref_conv1->rvaluedness_matches_p
+	  && ref_conv2->rvaluedness_matches_p)
+	return -1;
+
+      return comp_cv_qualification (TREE_TYPE (ref_conv2->type),
+				    TREE_TYPE (ref_conv1->type));
+    }
 
   /* Neither conversion sequence is better than the other.  */
   return 0;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 413b2241ed68..5e5cc9ee0aea 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -57,6 +57,7 @@ struct diagnostic_context;
       BASELINK_QUALIFIED_P (in BASELINK)
       TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR)
       TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX)
+      TYPE_REF_IS_RVALUE (in REFERENCE_TYPE)
    1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
       TI_PENDING_TEMPLATE_FLAG.
       TEMPLATE_PARMS_FOR_INLINE.
@@ -1759,6 +1760,10 @@ struct lang_decl GTY(())
 #define DECL_COPY_CONSTRUCTOR_P(NODE) \
   (DECL_CONSTRUCTOR_P (NODE) && copy_fn_p (NODE) > 0)
 
+/* Nonzero if NODE (a FUNCTION_DECL) is a move constructor.  */
+#define DECL_MOVE_CONSTRUCTOR_P(NODE) \
+  (DECL_CONSTRUCTOR_P (NODE) && move_fn_p (NODE))
+
 /* Nonzero if NODE is a destructor.  */
 #define DECL_DESTRUCTOR_P(NODE)				\
   (DECL_LANG_SPECIFIC (NODE)->decl_flags.destructor_attr)
@@ -2813,6 +2818,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define TYPE_REF_OBJ_P(NODE)					\
   (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE)))
 
+/* True if reference type NODE is an rvalue reference */
+#define TYPE_REF_IS_RVALUE(NODE) \
+  TREE_LANG_FLAG_0 (REFERENCE_TYPE_CHECK (NODE))
+
 /* Returns true if NODE is a pointer to an object, or a pointer to
    void.  Keep these checks in ascending tree code order.  */
 #define TYPE_PTROBV_P(NODE)					\
@@ -3687,6 +3696,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
    (Normally, these entities are registered in the symbol table, but
    not found by lookup.)  */
 #define LOOKUP_HIDDEN (LOOKUP_CONSTRUCTOR_CALLABLE << 1)
+/* Prefer that the lvalue be treated as an rvalue.  */
+#define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1)
 
 #define LOOKUP_NAMESPACES_ONLY(F)  \
   (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
@@ -4007,13 +4018,21 @@ struct cp_declarator {
       /* The bounds to the array.  */
       tree bounds;
     } array;
-    /* For cdk_pointer, cdk_reference, and cdk_ptrmem.  */
+    /* For cdk_pointer and cdk_ptrmem.  */
     struct {
       /* The cv-qualifiers for the pointer.  */
       cp_cv_quals qualifiers;
       /* For cdk_ptrmem, the class type containing the member.  */
       tree class_type;
     } pointer;
+    /* For cdk_reference */
+    struct {
+      /* The cv-qualifiers for the reference.  These qualifiers are
+         only used to diagnose ill-formed code.  */
+      cp_cv_quals qualifiers;
+      /* Whether this is an rvalue reference */
+      bool rvalue_ref;
+    } reference;
   } u;
 };
 
@@ -4176,6 +4195,7 @@ extern tree build_ptrmem_type			(tree, tree);
 /* the grokdeclarator prototype is in decl.h */
 extern tree build_this_parm			(tree, cp_cv_quals);
 extern int copy_fn_p				(tree);
+extern bool move_fn_p                           (tree);
 extern tree get_scope_of_declarator		(const cp_declarator *);
 extern void grok_special_member_properties	(tree);
 extern int grok_ctor_properties			(tree, tree);
@@ -4684,6 +4704,7 @@ extern int is_dummy_object			(tree);
 extern const struct attribute_spec cxx_attribute_table[];
 extern tree make_ptrmem_cst			(tree, tree);
 extern tree cp_build_type_attribute_variant     (tree, tree);
+extern tree cp_build_reference_type		(tree, bool);
 extern tree cp_build_qualified_type_real	(tree, int, tsubst_flags_t);
 #define cp_build_qualified_type(TYPE, QUALS) \
   cp_build_qualified_type_real ((TYPE), (QUALS), tf_warning_or_error)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c637f9ff8822..f28ab092703d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7794,10 +7794,24 @@ grokdeclarator (const cp_declarator *declarator,
 
 	  if (TREE_CODE (type) == REFERENCE_TYPE)
 	    {
-	      error (declarator->kind == cdk_reference
-		     ? "cannot declare reference to %q#T"
-		     : "cannot declare pointer to %q#T", type);
-	      type = TREE_TYPE (type);
+	      if (declarator->kind != cdk_reference)
+		{
+		  error ("cannot declare pointer to %q#T", type);
+		  type = TREE_TYPE (type);
+		}
+
+	      /* In C++0x, we allow reference to reference declarations
+		 that occur indirectly through typedefs [7.1.3/8 dcl.typedef]
+		 and template type arguments [14.3.1/4 temp.arg.type]. The
+		 check for direct reference to reference declarations, which
+		 are still forbidden, occurs below. Reasoning behind the change
+		 can be found in DR106, DR540, and the rvalue reference
+		 proposals. */
+	      else if (!flag_cpp0x)
+		{
+		  error ("cannot declare reference to %q#T", type);
+		  type = TREE_TYPE (type);
+		}
 	    }
 	  else if (VOID_TYPE_P (type))
 	    {
@@ -7823,8 +7837,39 @@ grokdeclarator (const cp_declarator *declarator,
 
 	  if (declarator->kind == cdk_reference)
 	    {
+	      /* In C++0x, the type we are creating a reference to might be
+		 a typedef which is itself a reference type. In that case,
+		 we follow the reference collapsing rules in
+		 [7.1.3/8 dcl.typedef] to create the final reference type:
+
+		 "If a typedef TD names a type that is a reference to a type
+		 T, an attempt to create the type 'lvalue reference to cv TD'
+		 creates the type 'lvalue reference to T,' while an attempt
+		 to create the type "rvalue reference to cv TD' creates the
+		 type TD."
+              */
 	      if (!VOID_TYPE_P (type))
-		type = build_reference_type (type);
+		type = cp_build_reference_type
+		       ((TREE_CODE (type) == REFERENCE_TYPE
+			 ? TREE_TYPE (type) : type),
+			(declarator->u.reference.rvalue_ref
+			 && (TREE_CODE(type) != REFERENCE_TYPE
+			     || TYPE_REF_IS_RVALUE (type))));
+
+	      /* In C++0x, we need this check for direct reference to
+		 reference declarations, which are forbidden by
+		 [8.3.2/5 dcl.ref]. Reference to reference declarations
+		 are only allowed indirectly through typedefs and template
+		 type arguments. Example:
+
+		   void foo(int & &);      // invalid ref-to-ref decl
+
+		   typedef int & int_ref;
+		   void foo(int_ref &);    // valid ref-to-ref decl
+	      */
+	      if (inner_declarator && inner_declarator->kind == cdk_reference)
+		error ("cannot declare reference to %q#T, which is not "
+		       "a typedef or a template type argument", type);
 	    }
 	  else if (TREE_CODE (type) == METHOD_TYPE)
 	    type = build_ptrmemfunc_type (build_pointer_type (type));
@@ -9075,6 +9120,7 @@ copy_fn_p (tree d)
       result = -1;
     }
   else if (TREE_CODE (arg_type) == REFERENCE_TYPE
+	   && !TYPE_REF_IS_RVALUE (arg_type)
 	   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)) == DECL_CONTEXT (d))
     {
       if (CP_TYPE_CONST_P (TREE_TYPE (arg_type)))
@@ -9092,6 +9138,57 @@ copy_fn_p (tree d)
   return result;
 }
 
+/* D is a constructor or overloaded `operator='.
+
+   Let T be the class in which D is declared. Then, this function
+   returns true when D is a move constructor or move assignment
+   operator, false otherwise.  */
+
+bool
+move_fn_p (tree d)
+{
+  tree args;
+  tree arg_type;
+  bool result = false;
+
+  gcc_assert (DECL_FUNCTION_MEMBER_P (d));
+
+  if (!flag_cpp0x)
+    /* There are no move constructors if we aren't in C++0x mode.  */
+    return false;
+
+  if (TREE_CODE (d) == TEMPLATE_DECL
+      || (DECL_TEMPLATE_INFO (d)
+         && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))))
+    /* Instantiations of template member functions are never copy
+       functions.  Note that member functions of templated classes are
+       represented as template functions internally, and we must
+       accept those as copy functions.  */
+    return 0;
+
+  args = FUNCTION_FIRST_USER_PARMTYPE (d);
+  if (!args)
+    return 0;
+
+  arg_type = TREE_VALUE (args);
+  if (arg_type == error_mark_node)
+    return 0;
+
+  if (TREE_CODE (arg_type) == REFERENCE_TYPE
+      && TYPE_REF_IS_RVALUE (arg_type)
+      && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)),
+                      DECL_CONTEXT (d)))
+    result = true;
+
+  args = TREE_CHAIN (args);
+
+  if (args && args != void_list_node && !TREE_PURPOSE (args))
+    /* There are more non-optional args.  */
+    return false;
+
+  return result;
+}
+
 /* Remember any special properties of member function DECL.  */
 
 void grok_special_member_properties (tree decl)
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index fcc7b08946eb..6121436a7949 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -542,7 +542,15 @@ dump_type_prefix (tree t, int flags)
 	    pp_cxx_whitespace (cxx_pp);
 	    pp_cxx_left_paren (cxx_pp);
 	  }
-	pp_character (cxx_pp, "&*"[TREE_CODE (t) == POINTER_TYPE]);
+	if (TREE_CODE (t) == POINTER_TYPE)
+	  pp_character(cxx_pp, '*');
+	else if (TREE_CODE (t) == REFERENCE_TYPE)
+	{
+	  if (TYPE_REF_IS_RVALUE (t))
+	    pp_string (cxx_pp, "&&");
+	  else
+	    pp_character (cxx_pp, '&');
+	}
 	pp_base (cxx_pp)->padding = pp_before;
 	pp_cxx_cv_qualifier_seq (cxx_pp, t);
       }
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index f500437e9701..059754f36cdf 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -709,12 +709,25 @@ build_throw (tree exp)
       /* And initialize the exception object.  */
       if (CLASS_TYPE_P (temp_type))
 	{
+	  int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
+
+	  /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
+	     treated as an rvalue for the purposes of overload resolution
+	     to favor move constructors over copy constructors.  */
+	  if (/* Must be a local, automatic variable.  */
+	      TREE_CODE (exp) == VAR_DECL
+	      && DECL_CONTEXT (exp) == current_function_decl
+	      && ! TREE_STATIC (exp)
+	      /* The variable must not have the `volatile' qualifier.  */
+	      && !(cp_type_quals (TREE_TYPE (exp)) & TYPE_QUAL_VOLATILE))
+	    flags = flags | LOOKUP_PREFER_RVALUE;
+
 	  /* Call the copy constructor.  */
 	  exp = (build_special_member_call
 		 (object, complete_ctor_identifier,
 		  build_tree_list (NULL_TREE, exp),
 		  TREE_TYPE (object),
-		  LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING));
+		  flags));
 	  if (exp == error_mark_node)
 	    {
 	      error ("  in thrown expression");
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 3ec02ed73939..5a66b4603845 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1541,6 +1541,10 @@ write_local_name (const tree function, const tree local_entity,
 	    ::= G <type>    # imaginary (C 2000)     [not supported]
 	    ::= U <source-name> <type>   # vendor extended type qualifier
 
+   C++0x extensions
+
+     <type> ::= RR <type>   # rvalue reference-to
+
    TYPE is a type node.  */
 
 static void
@@ -1635,6 +1639,8 @@ write_type (tree type)
 	  break;
 
 	case REFERENCE_TYPE:
+	  if (TYPE_REF_IS_RVALUE (type))
+            write_char('R');
 	  write_char ('R');
 	  write_type (TREE_TYPE (type));
 	  break;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e7b90b251589..c1a3276bb8ea 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -858,7 +858,7 @@ static cp_declarator *make_array_declarator
 static cp_declarator *make_pointer_declarator
   (cp_cv_quals, cp_declarator *);
 static cp_declarator *make_reference_declarator
-  (cp_cv_quals, cp_declarator *);
+  (cp_cv_quals, cp_declarator *, bool);
 static cp_parameter_declarator *make_parameter_declarator
   (cp_decl_specifier_seq *, cp_declarator *, tree);
 static cp_declarator *make_ptrmem_declarator
@@ -960,14 +960,15 @@ make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target)
 /* Like make_pointer_declarator -- but for references.  */
 
 cp_declarator *
-make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target)
+make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
+			   bool rvalue_ref)
 {
   cp_declarator *declarator;
 
   declarator = make_declarator (cdk_reference);
   declarator->declarator = target;
-  declarator->u.pointer.qualifiers = cv_qualifiers;
-  declarator->u.pointer.class_type = NULL_TREE;
+  declarator->u.reference.qualifiers = cv_qualifiers;
+  declarator->u.reference.rvalue_ref = rvalue_ref;
   if (target)
     {
       declarator->parameter_pack_p = target->parameter_pack_p;
@@ -2015,6 +2016,8 @@ static bool cp_parser_is_keyword
   (cp_token *, enum rid);
 static tree cp_parser_make_typename_type
   (cp_parser *, tree, tree);
+static cp_declarator * cp_parser_make_indirect_declarator
+  (enum tree_code, tree, cp_cv_quals, cp_declarator *);
 
 /* Returns nonzero if we are parsing tentatively.  */
 
@@ -2689,6 +2692,27 @@ cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id)
   return make_typename_type (scope, id, typename_type, tf_error);
 }
 
+/* This is a wrapper around the
+   make_{pointer,ptrmem,reference}_declarator functions that decides
+   which one to call based on the CODE and CLASS_TYPE arguments. The
+   CODE argument should be one of the values returned by
+   cp_parser_ptr_operator. */
+static cp_declarator *
+cp_parser_make_indirect_declarator (enum tree_code code, tree class_type,
+				    cp_cv_quals cv_qualifiers,
+				    cp_declarator *target)
+{
+  if (code == INDIRECT_REF)
+    if (class_type == NULL_TREE)
+      return make_pointer_declarator (cv_qualifiers, target);
+    else
+      return make_ptrmem_declarator (cv_qualifiers, class_type, target);
+  else if (code == ADDR_EXPR && class_type == NULL_TREE)
+    return make_reference_declarator (cv_qualifiers, target, false);
+  else if (code == NON_LVALUE_EXPR && class_type == NULL_TREE)
+    return make_reference_declarator (cv_qualifiers, target, true);
+  gcc_unreachable ();
+}
 
 /* Create a new C++ parser.  */
 
@@ -5532,15 +5556,8 @@ cp_parser_new_declarator_opt (cp_parser* parser)
       /* Parse another optional declarator.  */
       declarator = cp_parser_new_declarator_opt (parser);
 
-      /* Create the representation of the declarator.  */
-      if (type)
-	declarator = make_ptrmem_declarator (cv_quals, type, declarator);
-      else if (code == INDIRECT_REF)
-	declarator = make_pointer_declarator (cv_quals, declarator);
-      else
-	declarator = make_reference_declarator (cv_quals, declarator);
-
-      return declarator;
+      return cp_parser_make_indirect_declarator
+	(code, type, cv_quals, declarator);
     }
 
   /* If the next token is a `[', there is a direct-new-declarator.  */
@@ -8460,16 +8477,8 @@ cp_parser_conversion_declarator_opt (cp_parser* parser)
       /* Parse another optional declarator.  */
       declarator = cp_parser_conversion_declarator_opt (parser);
 
-      /* Create the representation of the declarator.  */
-      if (class_type)
-	declarator = make_ptrmem_declarator (cv_quals, class_type,
-					     declarator);
-      else if (code == INDIRECT_REF)
-	declarator = make_pointer_declarator (cv_quals, declarator);
-      else
-	declarator = make_reference_declarator (cv_quals, declarator);
-
-      return declarator;
+      return cp_parser_make_indirect_declarator
+	(code, class_type, cv_quals, declarator);
    }
 
   return NULL;
@@ -12072,15 +12081,8 @@ cp_parser_declarator (cp_parser* parser,
 	  && !cp_parser_parse_definitely (parser))
 	declarator = NULL;
 
-      /* Build the representation of the ptr-operator.  */
-      if (class_type)
-	declarator = make_ptrmem_declarator (cv_quals,
-					     class_type,
-					     declarator);
-      else if (code == INDIRECT_REF)
-	declarator = make_pointer_declarator (cv_quals, declarator);
-      else
-	declarator = make_reference_declarator (cv_quals, declarator);
+      declarator = cp_parser_make_indirect_declarator
+	(code, class_type, cv_quals, declarator);
     }
   /* Everything else is a direct-declarator.  */
   else
@@ -12558,12 +12560,15 @@ cp_parser_direct_declarator (cp_parser* parser,
      & cv-qualifier-seq [opt]
 
    Returns INDIRECT_REF if a pointer, or pointer-to-member, was used.
-   Returns ADDR_EXPR if a reference was used.  In the case of a
-   pointer-to-member, *TYPE is filled in with the TYPE containing the
-   member.  *CV_QUALS is filled in with the cv-qualifier-seq, or
-   TYPE_UNQUALIFIED, if there are no cv-qualifiers.  Returns
-   ERROR_MARK if an error occurred.  */
-
+   Returns ADDR_EXPR if a reference was used, or NON_LVALUE_EXPR for
+   an rvalue reference. In the case of a pointer-to-member, *TYPE is
+   filled in with the TYPE containing the member.  *CV_QUALS is
+   filled in with the cv-qualifier-seq, or TYPE_UNQUALIFIED, if there
+   are no cv-qualifiers.  Returns ERROR_MARK if an error occurred.
+   Note that the tree codes returned by this function have nothing
+   to do with the types of trees that will be eventually be created
+   to represent the pointer or reference type being parsed. They are
+   just constants with suggestive names. */
 static enum tree_code
 cp_parser_ptr_operator (cp_parser* parser,
 			tree* type,
@@ -12579,13 +12584,18 @@ cp_parser_ptr_operator (cp_parser* parser,
 
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
-  /* If it's a `*' or `&' we have a pointer or reference.  */
-  if (token->type == CPP_MULT || token->type == CPP_AND)
-    {
-      /* Remember which ptr-operator we were processing.  */
-      code = (token->type == CPP_AND ? ADDR_EXPR : INDIRECT_REF);
 
-      /* Consume the `*' or `&'.  */
+  /* If it's a `*', `&' or `&&' we have a pointer or reference.  */
+  if (token->type == CPP_MULT)
+    code = INDIRECT_REF;
+  else if (token->type == CPP_AND)
+    code = ADDR_EXPR;
+  else if (flag_cpp0x && token->type == CPP_AND_AND) /* C++0x only */
+    code = NON_LVALUE_EXPR;
+
+  if (code != ERROR_MARK)
+    {
+      /* Consume the `*', `&' or `&&'.  */
       cp_lexer_consume_token (parser->lexer);
 
       /* A `*' can be followed by a cv-qualifier-seq, and so can a
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 584e6cfa611a..47f3c0de05b2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -114,7 +114,8 @@ static void tsubst_enum	(tree, tree, tree);
 static tree add_to_template_args (tree, tree);
 static tree add_outermost_template_args (tree, tree);
 static bool check_instantiated_args (tree, tree, tsubst_flags_t);
-static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*);
+static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
+					     tree);
 static int  type_unification_real (tree, tree, tree, tree,
 				   int, unification_kind_t, int);
 static void note_template_header (int);
@@ -8729,8 +8730,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
 	   -- Attempting to create a pointer to reference type.
 	   -- Attempting to create a reference to a reference type or
-	      a reference to void.  */
-	if (TREE_CODE (type) == REFERENCE_TYPE
+	      a reference to void.
+
+	  Core issue 106 says that creating a reference to a reference
+	  during instantiation is no longer a cause for failure. We
+	  only enforce this check in strict C++98 mode.  */
+	if ((TREE_CODE (type) == REFERENCE_TYPE
+	     && ((!flag_cpp0x && flag_iso) || code != REFERENCE_TYPE))
 	    || (code == REFERENCE_TYPE && TREE_CODE (type) == VOID_TYPE))
 	  {
 	    static location_t last_loc;
@@ -8764,8 +8770,22 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	    if (TREE_CODE (type) == METHOD_TYPE)
 	      r = build_ptrmemfunc_type (r);
 	  }
+	else if (TREE_CODE (type) == REFERENCE_TYPE)
+	  /* In C++0x, during template argument substitution, when there is an
+	     attempt to create a reference to a reference type, reference
+	     collapsing is applied as described in [14.3.1/4 temp.arg.type]:
+
+	     "If a template-argument for a template-parameter T names a type
+	     that is a reference to a type A, an attempt to create the type
+	     'lvalue reference to cv T' creates the type 'lvalue reference to
+	     A,' while an attempt to create the type type rvalue reference to
+	     cv T' creates the type T"
+	  */
+	  r = cp_build_reference_type
+	      (TREE_TYPE (type),
+	       TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type));
 	else
-	  r = build_reference_type (type);
+	  r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
 	r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
 
 	if (r != error_mark_node)
@@ -11231,12 +11251,14 @@ fn_type_unification (tree fn,
    sections are symmetric.  PARM is the type of a function parameter
    or the return type of the conversion function.  ARG is the type of
    the argument passed to the call, or the type of the value
-   initialized with the result of the conversion function.  */
+   initialized with the result of the conversion function.
+   ARG_EXPR is the original argument expression, which may be null.  */
 
 static int
 maybe_adjust_types_for_deduction (unification_kind_t strict,
 				  tree* parm,
-				  tree* arg)
+				  tree* arg,
+				  tree arg_expr)
 {
   int result = 0;
 
@@ -11290,6 +11312,16 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
 	*arg = TYPE_MAIN_VARIANT (*arg);
     }
 
+  /* From C++0x [14.8.2.1/3 temp.deduct.call] (after DR606), "If P is
+     of the form T&&, where T is a template parameter, and the argument
+     is an lvalue, T is deduced as A& */
+  if (TREE_CODE (*parm) == REFERENCE_TYPE
+      && TYPE_REF_IS_RVALUE (*parm)
+      && TREE_CODE (TREE_TYPE (*parm)) == TEMPLATE_TYPE_PARM
+      && cp_type_quals (TREE_TYPE (*parm)) == TYPE_UNQUALIFIED
+      && arg_expr && real_lvalue_p (arg_expr))
+    *arg = build_reference_type (*arg);
+
   /* [temp.deduct.call]
 
      If P is a cv-qualified type, the top level cv-qualifiers
@@ -11326,7 +11358,7 @@ type_unification_real (tree tparms,
 		       unification_kind_t strict,
 		       int flags)
 {
-  tree parm, arg;
+  tree parm, arg, arg_expr;
   int i;
   int ntparms = TREE_VEC_LENGTH (tparms);
   int sub_strict;
@@ -11371,6 +11403,7 @@ type_unification_real (tree tparms,
       parms = TREE_CHAIN (parms);
       arg = TREE_VALUE (args);
       args = TREE_CHAIN (args);
+      arg_expr = NULL;
 
       if (arg == error_mark_node)
 	return 1;
@@ -11419,6 +11452,7 @@ type_unification_real (tree tparms,
 		return 1;
 	      continue;
 	    }
+	  arg_expr = arg;
 	  arg = unlowered_expr_type (arg);
 	  if (arg == error_mark_node)
 	    return 1;
@@ -11428,7 +11462,8 @@ type_unification_real (tree tparms,
 	int arg_strict = sub_strict;
 
 	if (!subr)
-	  arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
+	  arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg,
+							  arg_expr);
 
 	if (unify (tparms, targs, parm, arg, arg_strict))
 	  return 1;
@@ -11678,7 +11713,7 @@ try_one_overload (tree tparms,
   else if (addr_p)
     arg = build_pointer_type (arg);
 
-  sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
+  sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg, NULL);
 
   /* We don't copy orig_targs for this because if we have already deduced
      some template args from previous args, unify would complain when we
@@ -12014,7 +12049,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
 
             if (!subr)
               arg_strict |= 
-                maybe_adjust_types_for_deduction (strict, &parm, &arg);
+                maybe_adjust_types_for_deduction (strict, &parm, &arg, NULL);
           }
 
         if (!skip_arg_p)
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 848c3407673d..dceb3f9fff27 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -64,8 +64,28 @@ lvalue_p_1 (tree ref,
   cp_lvalue_kind op1_lvalue_kind = clk_none;
   cp_lvalue_kind op2_lvalue_kind = clk_none;
 
+  /* Expressions of reference type are sometimes wrapped in
+     INDIRECT_REFs.  INDIRECT_REFs are just internal compiler
+     representation, not part of the language, so we have to look
+     through them.  */
+  if (TREE_CODE (ref) == INDIRECT_REF
+      && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0)))
+	  == REFERENCE_TYPE)
+    return lvalue_p_1 (TREE_OPERAND (ref, 0),
+                       treat_class_rvalues_as_lvalues);
+
   if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
-    return clk_ordinary;
+    {
+      /* unnamed rvalue references are rvalues */
+      if (TYPE_REF_IS_RVALUE (TREE_TYPE (ref))
+	  && TREE_CODE (ref) != PARM_DECL
+	  && TREE_CODE (ref) != VAR_DECL
+	  && TREE_CODE (ref) != COMPONENT_REF)
+	return clk_none;
+
+      /* lvalue references and named rvalue refences are lvalues */
+      return clk_ordinary;
+    }
 
   if (ref == current_class_ptr)
     return clk_none;
@@ -588,6 +608,53 @@ build_cplus_array_type (tree elt_type, tree index_type)
 
   return t;
 }
+
+/* Return a reference type node referring to TO_TYPE.  If RVAL is
+   true, return an rvalue reference type, otherwise return an lvalue
+   reference type.  If a type node exists, reuse it, otherwise create
+   a new one.  */
+tree
+cp_build_reference_type (tree to_type, bool rval)
+{
+  tree lvalue_ref, t;
+  lvalue_ref = build_reference_type (to_type);
+  if (!rval)
+    return lvalue_ref;
+
+  /* This code to create rvalue reference types is based on and tied
+     to the code creating lvalue reference types in the middle-end
+     functions build_reference_type_for_mode and build_reference_type.
+
+     It works by putting the rvalue reference type nodes after the
+     lvalue reference nodes in the TYPE_NEXT_REF_TO linked list, so
+     they will effectively be ignored by the middle end.  */
+
+  for (t = lvalue_ref; (t = TYPE_NEXT_REF_TO (t)); )
+    if (TYPE_REF_IS_RVALUE (t))
+      return t;
+
+  t = copy_node (lvalue_ref);
+
+  TYPE_REF_IS_RVALUE (t) = true;
+  TYPE_NEXT_REF_TO (t) = TYPE_NEXT_REF_TO (lvalue_ref);
+  TYPE_NEXT_REF_TO (lvalue_ref) = t;
+  TYPE_MAIN_VARIANT (t) = t;
+
+  if (TYPE_STRUCTURAL_EQUALITY_P (to_type))
+    SET_TYPE_STRUCTURAL_EQUALITY (t);
+  else if (TYPE_CANONICAL (to_type) != to_type)
+    TYPE_CANONICAL (t) 
+      = cp_build_reference_type (TYPE_CANONICAL (to_type), rval);
+  else
+    TYPE_CANONICAL (t) = t;
+
+  layout_type (t);
+
+  return t;
+
+}
+
+
 
 /* Make a variant of TYPE, qualified with the TYPE_QUALS.  Handles
    arrays correctly.  In particular, if TYPE is an array of T's, and
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index af2133085eda..5712ba810c18 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1026,8 +1026,12 @@ structural_comptypes (tree t1, tree t2, int strict)
 	return false;
       break;
 
-    case POINTER_TYPE:
     case REFERENCE_TYPE:
+      if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2))
+	return false;
+      /* fall through to checks for pointer types */
+
+    case POINTER_TYPE:
       if (TYPE_MODE (t1) != TYPE_MODE (t2)
 	  || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2)
 	  || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
@@ -6532,6 +6536,7 @@ check_return_expr (tree retval, bool *no_warning)
      promotions.  */
   tree valtype;
   int fn_returns_value_p;
+  bool named_return_value_okay_p;
 
   *no_warning = false;
 
@@ -6680,20 +6685,26 @@ check_return_expr (tree retval, bool *no_warning)
 
      See finish_function and finalize_nrv for the rest of this optimization.  */
 
+  named_return_value_okay_p = 
+    (retval != NULL_TREE
+     /* Must be a local, automatic variable.  */
+     && TREE_CODE (retval) == VAR_DECL
+     && DECL_CONTEXT (retval) == current_function_decl
+     && ! TREE_STATIC (retval)
+     && (DECL_ALIGN (retval)
+         >= DECL_ALIGN (DECL_RESULT (current_function_decl)))
+     /* The cv-unqualified type of the returned value must be the
+        same as the cv-unqualified return type of the
+        function.  */
+     && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
+                     (TYPE_MAIN_VARIANT
+                      (TREE_TYPE (TREE_TYPE (current_function_decl))))));
+     
   if (fn_returns_value_p && flag_elide_constructors)
     {
-      if (retval != NULL_TREE
-	  && (current_function_return_value == NULL_TREE
-	      || current_function_return_value == retval)
-	  && TREE_CODE (retval) == VAR_DECL
-	  && DECL_CONTEXT (retval) == current_function_decl
-	  && ! TREE_STATIC (retval)
-	  && (DECL_ALIGN (retval)
-	      >= DECL_ALIGN (DECL_RESULT (current_function_decl)))
-	  && same_type_p ((TYPE_MAIN_VARIANT
-			   (TREE_TYPE (retval))),
-			  (TYPE_MAIN_VARIANT
-			   (TREE_TYPE (TREE_TYPE (current_function_decl))))))
+      if (named_return_value_okay_p
+          && (current_function_return_value == NULL_TREE
+              || current_function_return_value == retval))
 	current_function_return_value = retval;
       else
 	current_function_return_value = error_mark_node;
@@ -6712,18 +6723,29 @@ check_return_expr (tree retval, bool *no_warning)
     {
       /* The type the function is declared to return.  */
       tree functype = TREE_TYPE (TREE_TYPE (current_function_decl));
+      int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
 
       /* The functype's return type will have been set to void, if it
 	 was an incomplete type.  Just treat this as 'return;' */
       if (VOID_TYPE_P (functype))
 	return error_mark_node;
 
+      /* Under C++0x [12.8/16 class.copy], a returned lvalue is sometimes
+	 treated as an rvalue for the purposes of overload resolution to
+	 favor move constructors over copy constructors.  */
+      if (flag_cpp0x 
+          && named_return_value_okay_p
+          /* The variable must not have the `volatile' qualifier.  */
+	  && !(cp_type_quals (TREE_TYPE (retval)) & TYPE_QUAL_VOLATILE)
+	  /* The return type must be a class type.  */
+	  && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
+	flags = flags | LOOKUP_PREFER_RVALUE;
+
       /* First convert the value to the function's return type, then
 	 to the type of return value's location to handle the
 	 case that functype is smaller than the valtype.  */
       retval = convert_for_initialization
-	(NULL_TREE, functype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
-	 "return", NULL_TREE, 0);
+	(NULL_TREE, functype, retval, flags, "return", NULL_TREE, 0);
       retval = convert (valtype, retval);
 
       /* If the conversion failed, treat this just like `return;'.  */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d962250780b5..4ebf00277420 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,52 @@
+2007-05-30  Russell Yanofsky <russ@yanofsky.org>
+            Douglas Gregor <doug.gregor@gmail.com>
+            Pedro Lamarao <pedro.lamarao@mndfck.org>
+            Howard Hinnant <howard.hinnant@gmail.com>
+
+	PR c++/7412
+	PR c++/29939
+        * g++.dg/cpp0x/rv8p.C: New.
+        * g++.dg/cpp0x/temp-constructor-bug.C: New.
+        * g++.dg/cpp0x/cast-bug.C: New.
+        * g++.dg/cpp0x/elision_weak.C: New.
+        * g++.dg/cpp0x/collapse-bug.C: New.
+        * g++.dg/cpp0x/rv3p.C: New.
+        * g++.dg/cpp0x/rv7n.C: New.
+        * g++.dg/cpp0x/overload-conv-1.C: New.
+        * g++.dg/cpp0x/rv2n.C: New.
+        * g++.dg/cpp0x/deduce.C: New.
+        * g++.dg/cpp0x/temp-va-arg-bug.C: New.
+        * g++.dg/cpp0x/rv6p.C: New.
+        * g++.dg/cpp0x/template_deduction.C: New.
+        * g++.dg/cpp0x/implicit-copy.C: New.
+        * g++.dg/cpp0x/rv1p.C: New.
+        * g++.dg/cpp0x/cast.C: New.
+        * g++.dg/cpp0x/rv5n.C: New.
+        * g++.dg/cpp0x/collapse.C: New.
+        * g++.dg/cpp0x/overload-conv-2.C: New.
+        * g++.dg/cpp0x/rv4p.C: New.
+	* g++.dg/cpp0x/rvo.C: New.
+        * g++.dg/cpp0x/iop.C: New.
+        * g++.dg/cpp0x/rv3n.C: New.
+        * g++.dg/cpp0x/rv7p.C: New.
+        * g++.dg/cpp0x/reference_collapsing.C: New.
+        * g++.dg/cpp0x/overload.C: New.
+        * g++.dg/cpp0x/named.C: New.
+        * g++.dg/cpp0x/rv2p.C: New.
+        * g++.dg/cpp0x/rv6n.C: New.
+        * g++.dg/cpp0x/not_special.C: New.
+        * g++.dg/cpp0x/bind.C: New.
+        * g++.dg/cpp0x/rv1n.C: New.
+        * g++.dg/cpp0x/rv5p.C: New.
+        * g++.dg/cpp0x/elision.C: New.
+        * g++.dg/cpp0x/named_refs.C: New.
+        * g++.dg/cpp0x/unnamed_refs.C: New.
+        * g++.dg/cpp0x/rv4n.C: New.
+        * g++.dg/cpp0x/elision_neg.C: New.
+        * g++.dg/init/copy7.C: Run in C++98 mode.
+        * g++.dg/overload/arg1.C: Ditto.
+        * g++.dg/overload/arg4.C: Ditto.
+
 2007-05-30  Jakub Jelinek  <jakub@redhat.com>
 
 	PR c++/31809
diff --git a/gcc/testsuite/g++.dg/cpp0x/bind.C b/gcc/testsuite/g++.dg/cpp0x/bind.C
new file mode 100644
index 000000000000..42a2ac203dba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/bind.C
@@ -0,0 +1,8 @@
+// { dg-options "--std=c++0x" }
+struct S{};
+void f(S&&);
+
+int main()
+{
+  f(S());
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/cast-bug.C b/gcc/testsuite/g++.dg/cpp0x/cast-bug.C
new file mode 100644
index 000000000000..211f88b2b194
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/cast-bug.C
@@ -0,0 +1,14 @@
+// { dg-options "--std=c++0x" }
+struct S
+{
+  S();
+  S(S &&);
+private:
+  S(S &);
+};
+
+S f()
+{
+  S s;
+  return static_cast<S&&>(s);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/cast.C b/gcc/testsuite/g++.dg/cpp0x/cast.C
new file mode 100644
index 000000000000..4cc7f2edcf85
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/cast.C
@@ -0,0 +1,30 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test cast from lvalue to rvalue
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+
+struct A {};
+
+one foo(const A&) {return one();}
+two foo(A&&)      {return two();}
+
+int test1()
+{
+    A a;
+    sa<sizeof(foo(a)) == 1> t1;
+    sa<sizeof(foo(static_cast<A&&>(a))) == 2> t2;
+    return 0;
+}
+
+int main()
+{
+    return test1();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/collapse-bug.C b/gcc/testsuite/g++.dg/cpp0x/collapse-bug.C
new file mode 100644
index 000000000000..02a59cd1d21f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/collapse-bug.C
@@ -0,0 +1,16 @@
+// { dg-options "--std=c++0x" }
+template<typename T, typename U> struct same_type;
+template<typename T> struct same_type<T, T> {};
+
+template <typename T>
+struct S
+{
+  typedef T const (&type)();
+};
+
+void f()
+{
+  // initial implementation didn't ignore const qualifier on
+  // reference, resulting in a typedef of 'const int& (&)()'
+  same_type<S<int &>::type, int&(&)()>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/collapse.C b/gcc/testsuite/g++.dg/cpp0x/collapse.C
new file mode 100644
index 000000000000..96c32732461f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/collapse.C
@@ -0,0 +1,38 @@
+// { dg-options "--std=c++0x" }
+template<typename T, typename U> struct same_type;
+template<typename T> struct same_type<T, T> {};
+
+typedef int & lref;
+typedef int const & clref;
+typedef int && rref;
+typedef int const && crref;
+
+template<typename T>
+struct S
+{
+  typedef T & lref;
+  typedef T const & clref;
+  typedef T && rref;
+  typedef T const && crref;
+};
+
+void f()
+{
+  same_type<lref &, int &>();
+  same_type<lref &&, int &>();
+  same_type<rref &, int &>();
+  same_type<rref &&, int &&>();
+
+  same_type<rref const &, int &>();
+  same_type<crref volatile &&, int const &&>();
+  same_type<clref const &&, int const &>();
+
+  same_type<S<int &>::lref &, int &>();
+  same_type<S<int &&>::lref &&, int &>();
+  same_type<S<int &>::rref &, int &>();
+  same_type<S<int &&>::rref &&, int &&>();
+
+  same_type<S<int const &>::rref, int const &>();
+  same_type<S<int volatile &&>::crref, int volatile &&>();
+  same_type<S<int const &&>::clref, int const &>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/deduce.C b/gcc/testsuite/g++.dg/cpp0x/deduce.C
new file mode 100644
index 000000000000..6bd05160898e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/deduce.C
@@ -0,0 +1,36 @@
+// { dg-options "--std=c++0x" }
+template<typename T, typename U> struct same_type;
+template<typename T> struct same_type<T, T> {};
+
+int lval_int;
+int rval_int();
+int const lval_const_int=0;
+int const rval_const_int();
+
+template <typename T> void deduce_lval_int(T && t)
+{
+  same_type<T, int &>();
+}
+
+template <typename T> void deduce_rval_int(T && t)
+{
+  same_type<T, int>();
+}
+
+template <typename T> void deduce_lval_const_int(T && t)
+{
+  same_type<T, const int &>();
+}
+
+template <typename T> void deduce_rval_const_int(T && t)
+{
+  same_type<T, const int>();
+}
+
+void f()
+{
+  deduce_lval_int(lval_int);
+  deduce_rval_int(rval_int());
+  deduce_lval_const_int(lval_const_int);
+  deduce_rval_const_int(rval_const_int());
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/elision.C b/gcc/testsuite/g++.dg/cpp0x/elision.C
new file mode 100644
index 000000000000..35d5e4b02fb4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/elision.C
@@ -0,0 +1,76 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test: Implicit cast to rvalue when eliding copy
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+
+class move_only
+{
+    move_only(const move_only&);
+    move_only& operator=(const move_only&);
+public:
+    move_only() {}
+    move_only(move_only&&) {}
+    move_only& operator=(move_only&&) {return *this;}
+};
+
+move_only
+test1()
+{
+    return move_only();
+}
+
+move_only
+test2()
+{
+    move_only x;
+    return x;
+}
+
+move_only
+test3(bool b)
+{
+    move_only x1;
+    if (b)
+    {
+        move_only x2;
+        return x2;
+    }
+    return x1;
+}
+
+void
+test4(bool b)
+{
+    if (!b)
+        throw move_only();
+}
+
+void
+test5(bool b)
+{
+    move_only x;
+    if (!b)
+        throw x;
+}
+
+extern bool b;
+
+int main()
+{
+    move_only t1 = test1();
+    move_only t2 = test2();
+    move_only t3 = test3(b);
+    test4(b);
+    test5(b);
+    return 0;
+}
+
+bool b = true;
diff --git a/gcc/testsuite/g++.dg/cpp0x/elision_neg.C b/gcc/testsuite/g++.dg/cpp0x/elision_neg.C
new file mode 100644
index 000000000000..78feac72a5be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/elision_neg.C
@@ -0,0 +1,44 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test: Implicit cast to rvalue when eliding copy
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+
+class move_only
+{
+    move_only(const move_only&); // { dg-error "is private" }
+    move_only& operator=(const move_only&);
+public:
+    move_only() {}
+    move_only(move_only&&) {}
+    move_only& operator=(move_only&&) {return *this;}
+};
+
+move_only
+test1()
+{
+    static move_only x;
+    return x;  //  { dg-error "within this context" }
+}
+
+move_only
+test2(move_only&& x)
+{
+    return x;  //  { dg-error "within this context" }
+}
+
+int main()
+{
+    move_only t1 = test1();
+    move_only t2 = test2(move_only());
+    return 0;
+}
+
+bool b = true;
diff --git a/gcc/testsuite/g++.dg/cpp0x/elision_weak.C b/gcc/testsuite/g++.dg/cpp0x/elision_weak.C
new file mode 100644
index 000000000000..e8ba7551d84e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/elision_weak.C
@@ -0,0 +1,19 @@
+// { dg-do compile }
+
+struct S
+{
+  S() {}
+  S(S&) {}
+};
+
+S f()
+{
+  S s;
+  return s;
+}
+
+void g()
+{
+  S s;
+  throw s;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit-copy.C b/gcc/testsuite/g++.dg/cpp0x/implicit-copy.C
new file mode 100644
index 000000000000..ea680a8961b1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/implicit-copy.C
@@ -0,0 +1,15 @@
+// { dg-options "--std=c++0x" }
+struct S
+{
+  S();
+private:
+  S(S const &&);
+  S & operator=(S const &&);
+};
+
+void f()
+{
+  S a;
+  S b(a);
+  a = b;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/iop.C b/gcc/testsuite/g++.dg/cpp0x/iop.C
new file mode 100644
index 000000000000..5aecf9f504e6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/iop.C
@@ -0,0 +1,41 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test that the implicit object parameter is *not* an rvalue reference, but is instead
+//   identical to that specified in C++03.  That is, the implicit object parameter is
+//   an lvalue reference that can bind to an rvalue. :-\
+//   See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html under the
+//   section "Revision 1 Summary and Rationale" for more details.
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+
+struct os
+{
+    one operator<<(int);
+};
+
+struct A
+{
+    A(int);
+};
+
+two operator<<(os&, const A&);
+
+void test()
+{
+    os o;
+    sa<sizeof(o << 1) == 1> t1;  // Calls os::operator<<(int)
+                                 // Would be ambiguous if the implicit object parameter
+                                 // was an rvalue reference.
+}
+
+int main()
+{
+    return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/named.C b/gcc/testsuite/g++.dg/cpp0x/named.C
new file mode 100644
index 000000000000..b91e6989425f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/named.C
@@ -0,0 +1,35 @@
+// { dg-options "--std=c++0x" }
+// { dg-do link }
+
+struct S {};
+struct T
+{
+  T(S && s_) : s(s_) {}
+  S && get() { return s; }
+  operator S&&() { return s; }
+  S && s;
+};
+
+void named(S const &) {}
+void named(S&&);
+
+void unnamed(S const &);
+void unnamed(S&&) {}
+
+void f(S && p)
+{
+  S && s(p);
+  T t(s);
+
+  named(s);                          // variable reference
+  named(p);                          // parameter reference
+  named(t.s);                        // class member access
+
+  unnamed(t.get());                  // function return
+  unnamed(t);                        // implicit conversion
+  unnamed(static_cast<S&&>(s));      // cast to rvalue
+}
+
+int main()
+{
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/named_refs.C b/gcc/testsuite/g++.dg/cpp0x/named_refs.C
new file mode 100644
index 000000000000..96d7e787f060
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/named_refs.C
@@ -0,0 +1,28 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test: Named rvalue references are treated as lvalues.
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+
+struct A {};
+
+one foo(const A&) {return one();}
+two foo(A&&)      {return two();}
+
+int test1(A&& a)
+{
+    sa<sizeof(foo(a)) == 1> t1;
+    return 0;
+}
+
+int main()
+{
+    return test1(A());
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/not_special.C b/gcc/testsuite/g++.dg/cpp0x/not_special.C
new file mode 100644
index 000000000000..f94b82a0c1a3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/not_special.C
@@ -0,0 +1,54 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test that move constructor and move assignement are not special.
+//   That is, their presence should not inhibit compiler generated
+//   copy ctor or assignment.  Rather they should overload with the
+//   compiler generated special members.
+
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <assert.h>
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+
+int copy = 0;
+int assign = 0;
+
+struct base
+{
+    base() {}
+    base(const base&) {++copy;}
+    base& operator=(const base&) {++assign; return *this;}
+};
+
+struct derived
+    : base
+{
+    derived() {}
+    derived(derived&&) {}
+    derived& operator=(derived&&) {return *this;}
+};
+
+int test1()
+{
+    derived d;
+    derived d2(static_cast<derived&&>(d));  // should not call base::(const base&)
+    assert(copy == 0);
+    derived d3(d);                          // should     call base::(const base&)
+    assert(copy == 1);
+    d2 = static_cast<derived&&>(d);         // should not call base::operator=
+    assert(assign == 0);
+    d3 = d;                                 // should     call base::operator=
+    assert(assign == 1);
+    return 0;
+}
+
+int main()
+{
+    return test1();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/overload-conv-1.C b/gcc/testsuite/g++.dg/cpp0x/overload-conv-1.C
new file mode 100644
index 000000000000..778111283ff5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/overload-conv-1.C
@@ -0,0 +1,29 @@
+// { dg-options "--std=c++0x" }
+// { dg-do link }
+
+struct S {};
+
+struct T
+{
+  operator S() { return S(); }
+};
+
+struct U
+{
+  operator S&() { return *static_cast<S*>(0); }
+};
+
+void f(const S&);
+void f(S&&) {}
+
+void g(const S&) {}
+void g(S&&);
+
+int main()
+{
+  T t;
+  f(t);
+
+  U u;
+  g(u);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/overload-conv-2.C b/gcc/testsuite/g++.dg/cpp0x/overload-conv-2.C
new file mode 100644
index 000000000000..0e622bcacb25
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/overload-conv-2.C
@@ -0,0 +1,17 @@
+// { dg-options "--std=c++0x" }
+// { dg-do link }
+
+struct T {};
+struct S
+{
+  S(T const &) {}
+};
+
+void f(const S&);
+void f(S&&) {}
+
+int main()
+{
+  T t;
+  f(t);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/overload.C b/gcc/testsuite/g++.dg/cpp0x/overload.C
new file mode 100644
index 000000000000..945860cddb1a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/overload.C
@@ -0,0 +1,703 @@
+// { dg-options "--std=c++0x" }
+// { dg-do link }
+// Generated by overload.py
+
+struct S{};
+
+S l;                             // lvalue (l)
+S const cl = l;                  // const lvalue (cl)
+S r() { return l; }              // rvalue (r)
+S const cr() { return l; }       // const rvalue (cr)
+S & nl = l;                      // named lvalue reference (nl)
+S const & ncl = l;               // named const lvalue reference (ncl)
+S && nr = l;                     // named rvalue reference (nr)
+S const && ncr = l;              // named const rvalue reference (ncr)
+S & ul() { return l; }           // unnamed lvalue reference (ul)
+S const & ucl() { return l; }    // unnamed const lvalue reference (ucl)
+S && ur() { return l; }          // unnamed rvalue reference (ur)
+S const && ucr() { return l; }   // unnamed const rvalue reference (ucr)
+
+void l0001(const S&&) {}
+
+void l0010(S&&) {}
+
+void l0011(S&&) {}
+void l0011(const S&&);
+
+void l0100(const S&) {}
+
+void l0101(const S&) {}
+void l0101(const S&&);
+
+void l0110(const S&) {}
+void l0110(S&&);
+
+void l0111(const S&) {}
+void l0111(S&&);
+void l0111(const S&&);
+
+void l1000(S&) {}
+
+void l1001(S&) {}
+void l1001(const S&&);
+
+void l1010(S&) {}
+void l1010(S&&);
+
+void l1011(S&) {}
+void l1011(S&&);
+void l1011(const S&&);
+
+void l1100(S&) {}
+void l1100(const S&);
+
+void l1101(S&) {}
+void l1101(const S&);
+void l1101(const S&&);
+
+void l1110(S&) {}
+void l1110(const S&);
+void l1110(S&&);
+
+void l1111(S&) {}
+void l1111(const S&);
+void l1111(S&&);
+void l1111(const S&&);
+
+void cl0001(const S&&) {}
+
+void cl0011(S&&);
+void cl0011(const S&&) {}
+
+void cl0100(const S&) {}
+
+void cl0101(const S&) {}
+void cl0101(const S&&);
+
+void cl0110(const S&) {}
+void cl0110(S&&);
+
+void cl0111(const S&) {}
+void cl0111(S&&);
+void cl0111(const S&&);
+
+void cl1001(S&);
+void cl1001(const S&&) {}
+
+void cl1011(S&);
+void cl1011(S&&);
+void cl1011(const S&&) {}
+
+void cl1100(S&);
+void cl1100(const S&) {}
+
+void cl1101(S&);
+void cl1101(const S&) {}
+void cl1101(const S&&);
+
+void cl1110(S&);
+void cl1110(const S&) {}
+void cl1110(S&&);
+
+void cl1111(S&);
+void cl1111(const S&) {}
+void cl1111(S&&);
+void cl1111(const S&&);
+
+void r0001(const S&&) {}
+
+void r0010(S&&) {}
+
+void r0011(S&&) {}
+void r0011(const S&&);
+
+void r0100(const S&) {}
+
+void r0101(const S&);
+void r0101(const S&&) {}
+
+void r0110(const S&);
+void r0110(S&&) {}
+
+void r0111(const S&);
+void r0111(S&&) {}
+void r0111(const S&&);
+
+void r1001(S&);
+void r1001(const S&&) {}
+
+void r1010(S&);
+void r1010(S&&) {}
+
+void r1011(S&);
+void r1011(S&&) {}
+void r1011(const S&&);
+
+void r1100(S&);
+void r1100(const S&) {}
+
+void r1101(S&);
+void r1101(const S&);
+void r1101(const S&&) {}
+
+void r1110(S&);
+void r1110(const S&);
+void r1110(S&&) {}
+
+void r1111(S&);
+void r1111(const S&);
+void r1111(S&&) {}
+void r1111(const S&&);
+
+void cr0001(const S&&) {}
+
+void cr0011(S&&);
+void cr0011(const S&&) {}
+
+void cr0100(const S&) {}
+
+void cr0101(const S&);
+void cr0101(const S&&) {}
+
+void cr0110(const S&) {}
+void cr0110(S&&);
+
+void cr0111(const S&);
+void cr0111(S&&);
+void cr0111(const S&&) {}
+
+void cr1001(S&);
+void cr1001(const S&&) {}
+
+void cr1011(S&);
+void cr1011(S&&);
+void cr1011(const S&&) {}
+
+void cr1100(S&);
+void cr1100(const S&) {}
+
+void cr1101(S&);
+void cr1101(const S&);
+void cr1101(const S&&) {}
+
+void cr1110(S&);
+void cr1110(const S&) {}
+void cr1110(S&&);
+
+void cr1111(S&);
+void cr1111(const S&);
+void cr1111(S&&);
+void cr1111(const S&&) {}
+
+void nl0001(const S&&) {}
+
+void nl0010(S&&) {}
+
+void nl0011(S&&) {}
+void nl0011(const S&&);
+
+void nl0100(const S&) {}
+
+void nl0101(const S&) {}
+void nl0101(const S&&);
+
+void nl0110(const S&) {}
+void nl0110(S&&);
+
+void nl0111(const S&) {}
+void nl0111(S&&);
+void nl0111(const S&&);
+
+void nl1000(S&) {}
+
+void nl1001(S&) {}
+void nl1001(const S&&);
+
+void nl1010(S&) {}
+void nl1010(S&&);
+
+void nl1011(S&) {}
+void nl1011(S&&);
+void nl1011(const S&&);
+
+void nl1100(S&) {}
+void nl1100(const S&);
+
+void nl1101(S&) {}
+void nl1101(const S&);
+void nl1101(const S&&);
+
+void nl1110(S&) {}
+void nl1110(const S&);
+void nl1110(S&&);
+
+void nl1111(S&) {}
+void nl1111(const S&);
+void nl1111(S&&);
+void nl1111(const S&&);
+
+void ncl0001(const S&&) {}
+
+void ncl0011(S&&);
+void ncl0011(const S&&) {}
+
+void ncl0100(const S&) {}
+
+void ncl0101(const S&) {}
+void ncl0101(const S&&);
+
+void ncl0110(const S&) {}
+void ncl0110(S&&);
+
+void ncl0111(const S&) {}
+void ncl0111(S&&);
+void ncl0111(const S&&);
+
+void ncl1001(S&);
+void ncl1001(const S&&) {}
+
+void ncl1011(S&);
+void ncl1011(S&&);
+void ncl1011(const S&&) {}
+
+void ncl1100(S&);
+void ncl1100(const S&) {}
+
+void ncl1101(S&);
+void ncl1101(const S&) {}
+void ncl1101(const S&&);
+
+void ncl1110(S&);
+void ncl1110(const S&) {}
+void ncl1110(S&&);
+
+void ncl1111(S&);
+void ncl1111(const S&) {}
+void ncl1111(S&&);
+void ncl1111(const S&&);
+
+void nr0001(const S&&) {}
+
+void nr0010(S&&) {}
+
+void nr0011(S&&) {}
+void nr0011(const S&&);
+
+void nr0100(const S&) {}
+
+void nr0101(const S&) {}
+void nr0101(const S&&);
+
+void nr0110(const S&) {}
+void nr0110(S&&);
+
+void nr0111(const S&) {}
+void nr0111(S&&);
+void nr0111(const S&&);
+
+void nr1000(S&) {}
+
+void nr1001(S&) {}
+void nr1001(const S&&);
+
+void nr1010(S&) {}
+void nr1010(S&&);
+
+void nr1011(S&) {}
+void nr1011(S&&);
+void nr1011(const S&&);
+
+void nr1100(S&) {}
+void nr1100(const S&);
+
+void nr1101(S&) {}
+void nr1101(const S&);
+void nr1101(const S&&);
+
+void nr1110(S&) {}
+void nr1110(const S&);
+void nr1110(S&&);
+
+void nr1111(S&) {}
+void nr1111(const S&);
+void nr1111(S&&);
+void nr1111(const S&&);
+
+void ncr0001(const S&&) {}
+
+void ncr0011(S&&);
+void ncr0011(const S&&) {}
+
+void ncr0100(const S&) {}
+
+void ncr0101(const S&) {}
+void ncr0101(const S&&);
+
+void ncr0110(const S&) {}
+void ncr0110(S&&);
+
+void ncr0111(const S&) {}
+void ncr0111(S&&);
+void ncr0111(const S&&);
+
+void ncr1001(S&);
+void ncr1001(const S&&) {}
+
+void ncr1011(S&);
+void ncr1011(S&&);
+void ncr1011(const S&&) {}
+
+void ncr1100(S&);
+void ncr1100(const S&) {}
+
+void ncr1101(S&);
+void ncr1101(const S&) {}
+void ncr1101(const S&&);
+
+void ncr1110(S&);
+void ncr1110(const S&) {}
+void ncr1110(S&&);
+
+void ncr1111(S&);
+void ncr1111(const S&) {}
+void ncr1111(S&&);
+void ncr1111(const S&&);
+
+void ul0001(const S&&) {}
+
+void ul0010(S&&) {}
+
+void ul0011(S&&) {}
+void ul0011(const S&&);
+
+void ul0100(const S&) {}
+
+void ul0101(const S&) {}
+void ul0101(const S&&);
+
+void ul0110(const S&) {}
+void ul0110(S&&);
+
+void ul0111(const S&) {}
+void ul0111(S&&);
+void ul0111(const S&&);
+
+void ul1000(S&) {}
+
+void ul1001(S&) {}
+void ul1001(const S&&);
+
+void ul1010(S&) {}
+void ul1010(S&&);
+
+void ul1011(S&) {}
+void ul1011(S&&);
+void ul1011(const S&&);
+
+void ul1100(S&) {}
+void ul1100(const S&);
+
+void ul1101(S&) {}
+void ul1101(const S&);
+void ul1101(const S&&);
+
+void ul1110(S&) {}
+void ul1110(const S&);
+void ul1110(S&&);
+
+void ul1111(S&) {}
+void ul1111(const S&);
+void ul1111(S&&);
+void ul1111(const S&&);
+
+void ucl0001(const S&&) {}
+
+void ucl0011(S&&);
+void ucl0011(const S&&) {}
+
+void ucl0100(const S&) {}
+
+void ucl0101(const S&) {}
+void ucl0101(const S&&);
+
+void ucl0110(const S&) {}
+void ucl0110(S&&);
+
+void ucl0111(const S&) {}
+void ucl0111(S&&);
+void ucl0111(const S&&);
+
+void ucl1001(S&);
+void ucl1001(const S&&) {}
+
+void ucl1011(S&);
+void ucl1011(S&&);
+void ucl1011(const S&&) {}
+
+void ucl1100(S&);
+void ucl1100(const S&) {}
+
+void ucl1101(S&);
+void ucl1101(const S&) {}
+void ucl1101(const S&&);
+
+void ucl1110(S&);
+void ucl1110(const S&) {}
+void ucl1110(S&&);
+
+void ucl1111(S&);
+void ucl1111(const S&) {}
+void ucl1111(S&&);
+void ucl1111(const S&&);
+
+void ur0001(const S&&) {}
+
+void ur0010(S&&) {}
+
+void ur0011(S&&) {}
+void ur0011(const S&&);
+
+void ur0100(const S&) {}
+
+void ur0101(const S&);
+void ur0101(const S&&) {}
+
+void ur0110(const S&);
+void ur0110(S&&) {}
+
+void ur0111(const S&);
+void ur0111(S&&) {}
+void ur0111(const S&&);
+
+void ur1001(S&);
+void ur1001(const S&&) {}
+
+void ur1010(S&);
+void ur1010(S&&) {}
+
+void ur1011(S&);
+void ur1011(S&&) {}
+void ur1011(const S&&);
+
+void ur1100(S&);
+void ur1100(const S&) {}
+
+void ur1101(S&);
+void ur1101(const S&);
+void ur1101(const S&&) {}
+
+void ur1110(S&);
+void ur1110(const S&);
+void ur1110(S&&) {}
+
+void ur1111(S&);
+void ur1111(const S&);
+void ur1111(S&&) {}
+void ur1111(const S&&);
+
+void ucr0001(const S&&) {}
+
+void ucr0011(S&&);
+void ucr0011(const S&&) {}
+
+void ucr0100(const S&) {}
+
+void ucr0101(const S&);
+void ucr0101(const S&&) {}
+
+void ucr0110(const S&) {}
+void ucr0110(S&&);
+
+void ucr0111(const S&);
+void ucr0111(S&&);
+void ucr0111(const S&&) {}
+
+void ucr1001(S&);
+void ucr1001(const S&&) {}
+
+void ucr1011(S&);
+void ucr1011(S&&);
+void ucr1011(const S&&) {}
+
+void ucr1100(S&);
+void ucr1100(const S&) {}
+
+void ucr1101(S&);
+void ucr1101(const S&);
+void ucr1101(const S&&) {}
+
+void ucr1110(S&);
+void ucr1110(const S&) {}
+void ucr1110(S&&);
+
+void ucr1111(S&);
+void ucr1111(const S&);
+void ucr1111(S&&);
+void ucr1111(const S&&) {}
+
+
+int main()
+{
+  l0001(l);
+  l0010(l);
+  l0011(l);
+  l0100(l);
+  l0101(l);
+  l0110(l);
+  l0111(l);
+  l1000(l);
+  l1001(l);
+  l1010(l);
+  l1011(l);
+  l1100(l);
+  l1101(l);
+  l1110(l);
+  l1111(l);
+  cl0001(cl);
+  cl0011(cl);
+  cl0100(cl);
+  cl0101(cl);
+  cl0110(cl);
+  cl0111(cl);
+  cl1001(cl);
+  cl1011(cl);
+  cl1100(cl);
+  cl1101(cl);
+  cl1110(cl);
+  cl1111(cl);
+  r0001(r());
+  r0010(r());
+  r0011(r());
+  r0100(r());
+  r0101(r());
+  r0110(r());
+  r0111(r());
+  r1001(r());
+  r1010(r());
+  r1011(r());
+  r1100(r());
+  r1101(r());
+  r1110(r());
+  r1111(r());
+  cr0001(cr());
+  cr0011(cr());
+  cr0100(cr());
+  cr0101(cr());
+  cr0110(cr());
+  cr0111(cr());
+  cr1001(cr());
+  cr1011(cr());
+  cr1100(cr());
+  cr1101(cr());
+  cr1110(cr());
+  cr1111(cr());
+  nl0001(nl);
+  nl0010(nl);
+  nl0011(nl);
+  nl0100(nl);
+  nl0101(nl);
+  nl0110(nl);
+  nl0111(nl);
+  nl1000(nl);
+  nl1001(nl);
+  nl1010(nl);
+  nl1011(nl);
+  nl1100(nl);
+  nl1101(nl);
+  nl1110(nl);
+  nl1111(nl);
+  ncl0001(ncl);
+  ncl0011(ncl);
+  ncl0100(ncl);
+  ncl0101(ncl);
+  ncl0110(ncl);
+  ncl0111(ncl);
+  ncl1001(ncl);
+  ncl1011(ncl);
+  ncl1100(ncl);
+  ncl1101(ncl);
+  ncl1110(ncl);
+  ncl1111(ncl);
+  nr0001(nr);
+  nr0010(nr);
+  nr0011(nr);
+  nr0100(nr);
+  nr0101(nr);
+  nr0110(nr);
+  nr0111(nr);
+  nr1000(nr);
+  nr1001(nr);
+  nr1010(nr);
+  nr1011(nr);
+  nr1100(nr);
+  nr1101(nr);
+  nr1110(nr);
+  nr1111(nr);
+  ncr0001(ncr);
+  ncr0011(ncr);
+  ncr0100(ncr);
+  ncr0101(ncr);
+  ncr0110(ncr);
+  ncr0111(ncr);
+  ncr1001(ncr);
+  ncr1011(ncr);
+  ncr1100(ncr);
+  ncr1101(ncr);
+  ncr1110(ncr);
+  ncr1111(ncr);
+  ul0001(ul());
+  ul0010(ul());
+  ul0011(ul());
+  ul0100(ul());
+  ul0101(ul());
+  ul0110(ul());
+  ul0111(ul());
+  ul1000(ul());
+  ul1001(ul());
+  ul1010(ul());
+  ul1011(ul());
+  ul1100(ul());
+  ul1101(ul());
+  ul1110(ul());
+  ul1111(ul());
+  ucl0001(ucl());
+  ucl0011(ucl());
+  ucl0100(ucl());
+  ucl0101(ucl());
+  ucl0110(ucl());
+  ucl0111(ucl());
+  ucl1001(ucl());
+  ucl1011(ucl());
+  ucl1100(ucl());
+  ucl1101(ucl());
+  ucl1110(ucl());
+  ucl1111(ucl());
+  ur0001(ur());
+  ur0010(ur());
+  ur0011(ur());
+  ur0100(ur());
+  ur0101(ur());
+  ur0110(ur());
+  ur0111(ur());
+  ur1001(ur());
+  ur1010(ur());
+  ur1011(ur());
+  ur1100(ur());
+  ur1101(ur());
+  ur1110(ur());
+  ur1111(ur());
+  ucr0001(ucr());
+  ucr0011(ucr());
+  ucr0100(ucr());
+  ucr0101(ucr());
+  ucr0110(ucr());
+  ucr0111(ucr());
+  ucr1001(ucr());
+  ucr1011(ucr());
+  ucr1100(ucr());
+  ucr1101(ucr());
+  ucr1110(ucr());
+  ucr1111(ucr());
+
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/reference_collapsing.C b/gcc/testsuite/g++.dg/cpp0x/reference_collapsing.C
new file mode 100644
index 000000000000..5b682e304598
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/reference_collapsing.C
@@ -0,0 +1,175 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test the reference collapsing rules.  Note that there are recent differences
+//    for how cv-qualifications are applied to reference types. 7.1.3, 14.3.1
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+template <class T, T v>
+struct integral_constant
+{
+	static const T                  value = v;
+	typedef T                       value_type;
+	typedef integral_constant<T, v> type;
+};
+
+typedef integral_constant<bool, true>  true_type;
+typedef integral_constant<bool, false> false_type;
+
+template <class T> struct is_lvalue_reference     : public integral_constant<bool, false> {};
+template <class T> struct is_lvalue_reference<T&> : public integral_constant<bool, true> {};
+
+template <class T> struct is_rvalue_reference      : public integral_constant<bool, false> {};
+template <class T> struct is_rvalue_reference<T&&> : public integral_constant<bool, true> {};
+
+template <class T> struct remove_reference      {typedef T type;};
+template <class T> struct remove_reference<T&>  {typedef T type;};
+template <class T> struct remove_reference<T&&> {typedef T type;};
+
+template <class T> struct is_const          : public integral_constant<bool, false> {};
+template <class T> struct is_const<T const> : public integral_constant<bool, true> {};
+
+template <class T> struct is_volatile             : public integral_constant<bool, false> {};
+template <class T> struct is_volatile<T volatile> : public integral_constant<bool, true> {};
+
+struct A {};
+
+typedef A& Alref;
+typedef const A& cAlref;
+typedef volatile A& vAlref;
+typedef const volatile A& cvAlref;
+
+typedef A&& Arref;
+typedef const A&& cArref;
+typedef volatile A&& vArref;
+typedef const volatile A&& cvArref;
+
+template <class T, bool is_lvalue_ref, bool is_rvalue_ref, bool s_const, bool s_volatile>
+void test()
+{
+    sa<is_lvalue_reference<T>::value == is_lvalue_ref> t1;
+    sa<is_rvalue_reference<T>::value == is_rvalue_ref> t2;
+    sa<is_const   <typename remove_reference<T>::type>::value == s_const>    t3;
+    sa<is_volatile<typename remove_reference<T>::type>::value == s_volatile> t4;
+    sa<is_const   <typename remove_reference<const          T>::type>::value == s_const   > t5;
+    sa<is_volatile<typename remove_reference<      volatile T>::type>::value == s_volatile> t6;
+}
+
+int main()
+{
+    // sanity check
+    test<               A&,   true, false, false, false>();
+    test<const          A&,   true, false,  true, false>();
+    test<      volatile A&,   true, false, false,  true>();
+    test<const volatile A&,   true, false,  true,  true>();
+    test<               A&&, false,  true, false, false>();
+    test<const          A&&, false,  true,  true, false>();
+    test<      volatile A&&, false,  true, false,  true>();
+    test<const volatile A&&, false,  true,  true,  true>();
+
+// lvalue reference test
+
+    // Alref
+    test<               Alref&,  true, false, false, false>();
+    test<const          Alref&,  true, false, false, false>();
+    test<      volatile Alref&,  true, false, false, false>();
+    test<const volatile Alref&,  true, false, false, false>();
+
+    // cAlref
+    test<               cAlref&,  true, false,  true, false>();
+    test<const          cAlref&,  true, false,  true, false>();
+    test<      volatile cAlref&,  true, false,  true, false>();
+    test<const volatile cAlref&,  true, false,  true, false>();
+
+    // vAlref
+    test<               vAlref&,  true, false, false,  true>();
+    test<const          vAlref&,  true, false, false,  true>();
+    test<      volatile vAlref&,  true, false, false,  true>();
+    test<const volatile vAlref&,  true, false, false,  true>();
+
+    // cvAlref
+    test<               cvAlref&,  true, false,  true,  true>();
+    test<const          cvAlref&,  true, false,  true,  true>();
+    test<      volatile cvAlref&,  true, false,  true,  true>();
+    test<const volatile cvAlref&,  true, false,  true,  true>();
+
+    // Arref
+    test<               Arref&,  true, false, false, false>();
+    test<const          Arref&,  true, false, false, false>();
+    test<      volatile Arref&,  true, false, false, false>();
+    test<const volatile Arref&,  true, false, false, false>();
+
+    // cArref
+    test<               cArref&,  true, false,  true, false>();
+    test<const          cArref&,  true, false,  true, false>();
+    test<      volatile cArref&,  true, false,  true, false>();
+    test<const volatile cArref&,  true, false,  true, false>();
+
+    // vArref
+    test<               vArref&,  true, false, false,  true>();
+    test<const          vArref&,  true, false, false,  true>();
+    test<      volatile vArref&,  true, false, false,  true>();
+    test<const volatile vArref&,  true, false, false,  true>();
+
+    // vArref
+    test<               cvArref&,  true, false,  true,  true>();
+    test<const          cvArref&,  true, false,  true,  true>();
+    test<      volatile cvArref&,  true, false,  true,  true>();
+    test<const volatile cvArref&,  true, false,  true,  true>();
+
+// rvalue reference test
+
+    // Alref
+    test<               Alref&&,  true, false, false, false>();
+    test<const          Alref&&,  true, false, false, false>();
+    test<      volatile Alref&&,  true, false, false, false>();
+    test<const volatile Alref&&,  true, false, false, false>();
+
+    // cAlref
+    test<               cAlref&&,  true, false,  true, false>();
+    test<const          cAlref&&,  true, false,  true, false>();
+    test<      volatile cAlref&&,  true, false,  true, false>();
+    test<const volatile cAlref&&,  true, false,  true, false>();
+
+    // vAlref
+    test<               vAlref&&,  true, false, false,  true>();
+    test<const          vAlref&&,  true, false, false,  true>();
+    test<      volatile vAlref&&,  true, false, false,  true>();
+    test<const volatile vAlref&&,  true, false, false,  true>();
+
+    // cvAlref
+    test<               cvAlref&&,  true, false,  true,  true>();
+    test<const          cvAlref&&,  true, false,  true,  true>();
+    test<      volatile cvAlref&&,  true, false,  true,  true>();
+    test<const volatile cvAlref&&,  true, false,  true,  true>();
+
+    // Arref
+    test<               Arref&&, false,  true, false, false>();
+    test<const          Arref&&, false,  true, false, false>();
+    test<      volatile Arref&&, false,  true, false, false>();
+    test<const volatile Arref&&, false,  true, false, false>();
+
+    // cArref
+    test<               cArref&&, false,  true,  true, false>();
+    test<const          cArref&&, false,  true,  true, false>();
+    test<      volatile cArref&&, false,  true,  true, false>();
+    test<const volatile cArref&&, false,  true,  true, false>();
+
+    // vArref
+    test<               vArref&&, false,  true, false,  true>();
+    test<const          vArref&&, false,  true, false,  true>();
+    test<      volatile vArref&&, false,  true, false,  true>();
+    test<const volatile vArref&&, false,  true, false,  true>();
+
+    // cvArref
+    test<               cvArref&&, false,  true,  true,  true>();
+    test<const          cvArref&&, false,  true,  true,  true>();
+    test<      volatile cvArref&&, false,  true,  true,  true>();
+    test<const volatile cvArref&&, false,  true,  true,  true>();
+
+    return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv1n.C b/gcc/testsuite/g++.dg/cpp0x/rv1n.C
new file mode 100644
index 000000000000..10b5dc256b4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv1n.C
@@ -0,0 +1,149 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 1 at a time
+
+one   sink_1_1(               A&);  // { dg-error "" }
+
+int test1_1()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_1_1(ca);           // { dg-error "invalid initialization" }
+    sink_1_1(va);           // { dg-error "invalid initialization" }
+    sink_1_1(cva);          // { dg-error "invalid initialization" }
+    sink_1_1(source());     // { dg-error "invalid initialization" }
+    sink_1_1(c_source());   // { dg-error "invalid initialization" }
+    sink_1_1(v_source());   // { dg-error "invalid initialization" }
+    sink_1_1(cv_source());  // { dg-error "invalid initialization" }
+    return 0;
+}
+
+two   sink_1_2(const          A&);  // { dg-error "" }
+
+int test1_2()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_1_2(va);           // { dg-error "invalid initialization" }
+    sink_1_2(cva);          // { dg-error "invalid initialization" }
+    sink_1_2(v_source());   // { dg-error "invalid initialization" }
+    sink_1_2(cv_source());  // { dg-error "invalid initialization" }
+    return 0;
+}
+
+three sink_1_3(volatile       A&);  // { dg-error "" }
+
+int test1_3()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_1_3(ca);           // { dg-error "invalid initialization" }
+    sink_1_3(cva);          // { dg-error "invalid initialization" }
+    sink_1_3(source());     // { dg-error "invalid initialization" }
+    sink_1_3(c_source());   // { dg-error "invalid initialization" }
+    sink_1_3(v_source());   // { dg-error "invalid initialization" }
+    sink_1_3(cv_source());  // { dg-error "invalid initialization" }
+    return 0;
+}
+
+four  sink_1_4(const volatile A&);  // { dg-error "" }
+
+int test1_4()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_1_4(source());     // { dg-error "invalid initialization" }
+    sink_1_4(c_source());   // { dg-error "invalid initialization" }
+    sink_1_4(v_source());   // { dg-error "invalid initialization" }
+    sink_1_4(cv_source());  // { dg-error "invalid initialization" }
+    return 0;
+}
+
+five  sink_1_5(               A&&);  // { dg-error "" }
+
+int test1_5()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_1_5(ca);           // { dg-error "invalid initialization" }
+    sink_1_5(va);           // { dg-error "invalid initialization" }
+    sink_1_5(cva);          // { dg-error "invalid initialization" }
+    sink_1_5(c_source());   // { dg-error "invalid initialization" }
+    sink_1_5(v_source());   // { dg-error "invalid initialization" }
+    sink_1_5(cv_source());  // { dg-error "invalid initialization" }
+    return 0;
+}
+
+six   sink_1_6(const          A&&);  // { dg-error "" }
+
+int test1_6()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_1_6(va);           // { dg-error "invalid initialization" }
+    sink_1_6(cva);          // { dg-error "invalid initialization" }
+    sink_1_6(v_source());   // { dg-error "invalid initialization" }
+    sink_1_6(cv_source());  // { dg-error "invalid initialization" }
+    return 0;
+}
+
+seven sink_1_7(volatile       A&&);  // { dg-error "" }
+
+int test1_7()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_1_7(ca);           // { dg-error "invalid initialization" }
+    sink_1_7(cva);          // { dg-error "invalid initialization" }
+    sink_1_7(c_source());   // { dg-error "invalid initialization" }
+    sink_1_7(cv_source());  // { dg-error "invalid initialization" }
+    return 0;
+}
+
+int main()
+{
+    return test1_1() + test1_2() + test1_3() + test1_5() +
+           test1_6() + test1_7();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv1p.C b/gcc/testsuite/g++.dg/cpp0x/rv1p.C
new file mode 100644
index 000000000000..6241885654ec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv1p.C
@@ -0,0 +1,154 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 1 at a time
+
+one   sink_1_1(               A&);
+
+int test1_1()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_1_1(a))           == 1> t1;
+    return 0;
+}
+
+two   sink_1_2(const          A&);
+
+int test1_2()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_1_2(a))           == 2> t1;
+    sa<sizeof(sink_1_2(ca))          == 2> t2;
+    sa<sizeof(sink_1_2(source()))    == 2> t5;
+    sa<sizeof(sink_1_2(c_source()))  == 2> t6;
+    return 0;
+}
+
+three sink_1_3(volatile       A&);
+
+int test1_3()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_1_3(a))           == 3> t1;
+    sa<sizeof(sink_1_3(va))          == 3> t3;
+    return 0;
+}
+
+four  sink_1_4(const volatile A&);
+
+int test1_4()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_1_4(a))           == 4> t1;
+    sa<sizeof(sink_1_4(ca))          == 4> t2;
+    sa<sizeof(sink_1_4(va))          == 4> t3;
+    sa<sizeof(sink_1_4(cva))         == 4> t4;
+    return 0;
+}
+
+five  sink_1_5(               A&&);
+
+int test1_5()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_1_5(a))           == 5> t1;
+    sa<sizeof(sink_1_5(source()))    == 5> t5;
+    return 0;
+}
+
+six   sink_1_6(const          A&&);
+
+int test1_6()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_1_6(a))           == 6> t1;
+    sa<sizeof(sink_1_6(ca))          == 6> t2;
+    sa<sizeof(sink_1_6(source()))    == 6> t5;
+    sa<sizeof(sink_1_6(c_source()))  == 6> t6;
+    return 0;
+}
+
+seven sink_1_7(volatile       A&&);
+
+int test1_7()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_1_7(a))           == 7> t1;
+    sa<sizeof(sink_1_7(va))          == 7> t3;
+    sa<sizeof(sink_1_7(source()))    == 7> t5;
+    sa<sizeof(sink_1_7(v_source()))  == 7> t7;
+    return 0;
+}
+
+eight sink_1_8(const volatile A&&);
+
+int test1_8()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_1_8(a))           == 8> t1;
+    sa<sizeof(sink_1_8(ca))          == 8> t2;
+    sa<sizeof(sink_1_8(va))          == 8> t3;
+    sa<sizeof(sink_1_8(cva))         == 8> t4;
+    sa<sizeof(sink_1_8(source()))    == 8> t5;
+    sa<sizeof(sink_1_8(c_source()))  == 8> t6;
+    sa<sizeof(sink_1_8(v_source()))  == 8> t7;
+    sa<sizeof(sink_1_8(cv_source())) == 8> t8;
+    return 0;
+}
+
+int main()
+{
+    return test1_1() + test1_2() + test1_3() + test1_4() +
+           test1_5() + test1_6() + test1_7() + test1_8();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv2n.C b/gcc/testsuite/g++.dg/cpp0x/rv2n.C
new file mode 100644
index 000000000000..df35358a6c1f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv2n.C
@@ -0,0 +1,370 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 2 at a time
+
+one   sink_2_12(               A&);  // { dg-error "" }
+two   sink_2_12(const          A&);  // { dg-error "" }
+
+int test2_12()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_12(va);           // { dg-error "no match" }
+    sink_2_12(cva);          // { dg-error "no match" }
+    sink_2_12(v_source());   // { dg-error "no match" }
+    sink_2_12(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_2_13(               A&);  // { dg-error "" }
+three sink_2_13(volatile       A&);  // { dg-error "" }
+
+int test2_13()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_13(ca);           // { dg-error "no match" }
+    sink_2_13(cva);          // { dg-error "no match" }
+    sink_2_13(source());     // { dg-error "no match" }
+    sink_2_13(c_source());   // { dg-error "no match" }
+    sink_2_13(v_source());   // { dg-error "no match" }
+    sink_2_13(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_2_14(               A&);  // { dg-error "" }
+four  sink_2_14(const volatile A&);  // { dg-error "" }
+
+int test2_14()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_14(source());     // { dg-error "no match" }
+    sink_2_14(c_source());   // { dg-error "no match" }
+    sink_2_14(v_source());   // { dg-error "no match" }
+    sink_2_14(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_2_15(               A&);  // { dg-error "" }
+five  sink_2_15(               A&&);  // { dg-error "" }
+
+int test2_15()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+   sink_2_15(ca);           // { dg-error "no match" }
+   sink_2_15(va);           // { dg-error "no match" }
+   sink_2_15(cva);          // { dg-error "no match" }
+   sink_2_15(c_source());   // { dg-error "no match" }
+   sink_2_15(v_source());   // { dg-error "no match" }
+   sink_2_15(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_2_16(               A&);  // { dg-error "" }
+six   sink_2_16(const          A&&);  // { dg-error "" }
+
+int test2_16()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_16(va);           // { dg-error "no match" }
+    sink_2_16(cva);          // { dg-error "no match" }
+    sink_2_16(v_source());   // { dg-error "no match" }
+    sink_2_16(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_2_17(               A&);  // { dg-error "" }
+seven sink_2_17(volatile       A&&);  // { dg-error "" }
+
+int test2_17()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_17(ca);           // { dg-error "no match" }
+    sink_2_17(cva);          // { dg-error "no match" }
+    sink_2_17(c_source());   // { dg-error "no match" }
+    sink_2_17(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_2_23(const          A&);  // { dg-error "" }
+three sink_2_23(volatile       A&);  // { dg-error "" }
+
+int test2_23()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_23(a);            // { dg-error "ambiguous" }
+    sink_2_23(cva);          // { dg-error "no match" }
+    sink_2_23(v_source());   // { dg-error "no match" }
+    sink_2_23(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_2_24(const          A&);  // { dg-error "" }
+four  sink_2_24(const volatile A&);  // { dg-error "" }
+
+int test2_24()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_24(v_source());   // { dg-error "no match" }
+    sink_2_24(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_2_34(volatile       A&);  // { dg-error "" }
+four  sink_2_34(const volatile A&);  // { dg-error "" }
+
+int test2_34()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_34(source());     // { dg-error "no match" }
+    sink_2_34(c_source());   // { dg-error "no match" }
+    sink_2_34(v_source());   // { dg-error "no match" }
+    sink_2_34(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_2_25(const          A&);  // { dg-error "" }
+five  sink_2_25(               A&&);  // { dg-error "" }
+
+int test2_25()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+   sink_2_25(va);           // { dg-error "no match" }
+   sink_2_25(cva);          // { dg-error "no match" }
+   sink_2_25(v_source());   // { dg-error "no match" }
+   sink_2_25(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_2_26(const          A&);  // { dg-error "" }
+six   sink_2_26(const          A&&);  // { dg-error "" }
+
+int test2_26()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_26(va);           // { dg-error "no match" }
+    sink_2_26(cva);          // { dg-error "no match" }
+    sink_2_26(v_source());   // { dg-error "no match" }
+    sink_2_26(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_2_27(const          A&);  // { dg-error "" }
+seven sink_2_27(volatile       A&&);  // { dg-error "" }
+
+int test2_27()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_27(cva);          // { dg-error "no match" }
+    sink_2_27(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_2_35(volatile       A&);  // { dg-error "" }
+five  sink_2_35(               A&&);  // { dg-error "" }
+
+int test2_35()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_35(ca);           // { dg-error "no match" }
+    sink_2_35(cva);          // { dg-error "no match" }
+    sink_2_35(c_source());   // { dg-error "no match" }
+    sink_2_35(v_source());   // { dg-error "no match" }
+    sink_2_35(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_2_36(volatile       A&);  // { dg-error "" }
+six   sink_2_36(const          A&&);  // { dg-error "" }
+
+int test2_36()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_36(cva);          // { dg-error "no match" }
+    sink_2_36(v_source());   // { dg-error "no match" }
+    sink_2_36(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_2_37(volatile       A&);  // { dg-error "" }
+seven sink_2_37(volatile       A&&);  // { dg-error "" }
+
+int test2_37()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_37(ca);           // { dg-error "no match" }
+    sink_2_37(cva);          // { dg-error "no match" }
+    sink_2_37(c_source());   // { dg-error "no match" }
+    sink_2_37(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+four  sink_2_45(const volatile A&);   // { dg-error "" }
+five  sink_2_45(               A&&);  // { dg-error "" }
+
+int test2_45()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_45(c_source());   // { dg-error "no match" }
+    sink_2_45(v_source());   // { dg-error "no match" }
+    sink_2_45(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+four  sink_2_46(const volatile A&);   // { dg-error "" }
+six   sink_2_46(const          A&&);  // { dg-error "" }
+
+int test2_46()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_46(v_source());   // { dg-error "no match" }
+    sink_2_46(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+four  sink_2_47(const volatile A&);   // { dg-error "" }
+seven sink_2_47(volatile       A&&);  // { dg-error "" }
+
+int test2_47()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_47(c_source());   // { dg-error "no match" }
+    sink_2_47(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+five  sink_2_56(               A&&);  // { dg-error "" }
+six   sink_2_56(const          A&&);  // { dg-error "" }
+
+int test2_56()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_56(va);           // { dg-error "no match" }
+    sink_2_56(cva);          // { dg-error "no match" }
+    sink_2_56(v_source());   // { dg-error "no match" }
+    sink_2_56(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+five  sink_2_57(               A&&);  // { dg-error "" }
+seven sink_2_57(volatile       A&&);  // { dg-error "" }
+
+int test2_57()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_57(ca);           // { dg-error "no match" }
+    sink_2_57(cva);          // { dg-error "no match" }
+    sink_2_57(c_source());   // { dg-error "no match" }
+    sink_2_57(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+six   sink_2_67(const          A&&);  // { dg-error "" }
+seven sink_2_67(volatile       A&&);  // { dg-error "" }
+
+int test2_67()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_2_67(a);            // { dg-error "ambiguous" }
+    sink_2_67(cva);          // { dg-error "no match" }
+    sink_2_67(source());     // { dg-error "ambiguous" }
+    sink_2_67(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+int main()
+{
+    return test2_12() + test2_13() + test2_15() + test2_16() +
+           test2_17() + test2_23() + test2_25() + test2_26() +
+           test2_27() + test2_35() + test2_36() + test2_37() +
+           test2_56() + test2_57() + test2_67();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv2p.C b/gcc/testsuite/g++.dg/cpp0x/rv2p.C
new file mode 100644
index 000000000000..0d12aac75e14
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv2p.C
@@ -0,0 +1,536 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 2 at a time
+
+one   sink_2_12(               A&);
+two   sink_2_12(const          A&);
+
+int test2_12()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_12(a))           == 1> t1;
+    sa<sizeof(sink_2_12(ca))          == 2> t2;
+    sa<sizeof(sink_2_12(source()))    == 2> t5;
+    sa<sizeof(sink_2_12(c_source()))  == 2> t6;
+    return 0;
+}
+
+one   sink_2_13(               A&);
+three sink_2_13(volatile       A&);
+
+int test2_13()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_13(a))           == 1> t1;
+    sa<sizeof(sink_2_13(va))          == 3> t3;
+    return 0;
+}
+
+one   sink_2_14(               A&);
+four  sink_2_14(const volatile A&);
+
+int test2_14()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_14(a))           == 1> t1;
+    sa<sizeof(sink_2_14(ca))          == 4> t2;
+    sa<sizeof(sink_2_14(va))          == 4> t3;
+    sa<sizeof(sink_2_14(cva))         == 4> t4;
+    return 0;
+}
+
+one   sink_2_15(               A&);
+five  sink_2_15(               A&&);
+
+int test2_15()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_15(a))           == 1> t1;
+    sa<sizeof(sink_2_15(source()))    == 5> t5;
+    return 0;
+}
+
+one   sink_2_16(               A&);
+six   sink_2_16(const          A&&);
+
+int test2_16()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_16(a))           == 1> t1;
+    sa<sizeof(sink_2_16(ca))          == 6> t2;
+    sa<sizeof(sink_2_16(source()))    == 6> t5;
+    sa<sizeof(sink_2_16(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_2_17(               A&);
+seven sink_2_17(volatile       A&&);
+
+int test2_17()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_17(a))           == 1> t1;
+    sa<sizeof(sink_2_17(va))          == 7> t3;
+    sa<sizeof(sink_2_17(source()))    == 7> t5;
+    sa<sizeof(sink_2_17(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_2_18(               A&);
+eight sink_2_18(const volatile A&&);
+
+int test2_18()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_18(a))           == 1> t1;
+    sa<sizeof(sink_2_18(ca))          == 8> t2;
+    sa<sizeof(sink_2_18(va))          == 8> t3;
+    sa<sizeof(sink_2_18(cva))         == 8> t4;
+    sa<sizeof(sink_2_18(source()))    == 8> t5;
+    sa<sizeof(sink_2_18(c_source()))  == 8> t6;
+    sa<sizeof(sink_2_18(v_source()))  == 8> t7;
+    sa<sizeof(sink_2_18(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_2_23(const          A&);
+three sink_2_23(volatile       A&);
+
+int test2_23()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_23(ca))          == 2> t2;
+    sa<sizeof(sink_2_23(va))          == 3> t3;
+    sa<sizeof(sink_2_23(source()))    == 2> t5;
+    sa<sizeof(sink_2_23(c_source()))  == 2> t6;
+    return 0;
+}
+
+two   sink_2_24(const          A&);
+four  sink_2_24(const volatile A&);
+
+int test2_24()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_24(a))           == 2> t1;
+    sa<sizeof(sink_2_24(ca))          == 2> t2;
+    sa<sizeof(sink_2_24(va))          == 4> t3;
+    sa<sizeof(sink_2_24(cva))         == 4> t4;
+    sa<sizeof(sink_2_24(source()))    == 2> t5;
+    sa<sizeof(sink_2_24(c_source()))  == 2> t6;
+//    sa<sizeof(sink_2_24(v_source()))  == 4> t7;
+//    sa<sizeof(sink_2_24(cv_source())) == 4> t8;
+    return 0;
+}
+
+two   sink_2_25(const          A&);
+five  sink_2_25(               A&&);
+
+int test2_25()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_25(a))           == 2> t1;
+    sa<sizeof(sink_2_25(ca))          == 2> t2;
+    sa<sizeof(sink_2_25(source()))    == 5> t5;
+    sa<sizeof(sink_2_25(c_source()))  == 2> t6;
+    return 0;
+}
+
+two   sink_2_26(const          A&);
+six   sink_2_26(const          A&&);
+
+int test2_26()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_26(a))           == 2> t1;
+    sa<sizeof(sink_2_26(ca))          == 2> t2;
+    sa<sizeof(sink_2_26(source()))    == 6> t5;
+    sa<sizeof(sink_2_26(c_source()))  == 6> t6;
+    return 0;
+}
+
+two   sink_2_27(const          A&);
+seven sink_2_27(volatile       A&&);
+
+int test2_27()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_27(a))           == 2> t1;
+    sa<sizeof(sink_2_27(ca))          == 2> t2;
+    sa<sizeof(sink_2_27(va))          == 7> t3;
+    sa<sizeof(sink_2_27(source()))    == 7> t5;
+    sa<sizeof(sink_2_27(c_source()))  == 2> t6;
+    sa<sizeof(sink_2_27(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_2_28(const          A&);
+eight sink_2_28(const volatile A&&);
+
+int test2_28()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_28(a))           == 2> t1;
+    sa<sizeof(sink_2_28(ca))          == 2> t2;
+    sa<sizeof(sink_2_28(va))          == 8> t3;
+    sa<sizeof(sink_2_28(cva))         == 8> t4;
+    sa<sizeof(sink_2_28(source()))    == 8> t5;
+    sa<sizeof(sink_2_28(c_source()))  == 8> t6;
+    sa<sizeof(sink_2_28(v_source()))  == 8> t7;
+    sa<sizeof(sink_2_28(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_2_34(volatile       A&);
+four  sink_2_34(const volatile A&);
+
+int test2_34()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_34(a))           == 3> t1;
+    sa<sizeof(sink_2_34(ca))          == 4> t2;
+    sa<sizeof(sink_2_34(va))          == 3> t3;
+    sa<sizeof(sink_2_34(cva))         == 4> t4;
+//    sa<sizeof(sink_2_34(source()))    == 4> t5;
+//    sa<sizeof(sink_2_34(c_source()))  == 4> t6;
+//    sa<sizeof(sink_2_34(v_source()))  == 4> t7;
+//    sa<sizeof(sink_2_34(cv_source())) == 4> t8;
+    return 0;
+}
+
+three sink_2_35(volatile       A&);
+five  sink_2_35(               A&&);
+
+int test2_35()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_35(a))           == 3> t1;
+    sa<sizeof(sink_2_35(va))          == 3> t3;
+    sa<sizeof(sink_2_35(source()))    == 5> t5;
+    return 0;
+}
+
+three sink_2_36(volatile       A&);
+six   sink_2_36(const          A&&);
+
+int test2_36()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_36(a))           == 3> t1;
+    sa<sizeof(sink_2_36(ca))          == 6> t2;
+    sa<sizeof(sink_2_36(va))          == 3> t3;
+    sa<sizeof(sink_2_36(source()))    == 6> t5;
+    sa<sizeof(sink_2_36(c_source()))  == 6> t6;
+    return 0;
+}
+
+three sink_2_37(volatile       A&);
+seven sink_2_37(volatile       A&&);
+
+int test2_37()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_37(a))           == 3> t1;
+    sa<sizeof(sink_2_37(va))          == 3> t3;
+    sa<sizeof(sink_2_37(source()))    == 7> t5;
+    sa<sizeof(sink_2_37(v_source()))  == 7> t7;
+    return 0;
+}
+
+three sink_2_38(volatile       A&);
+eight sink_2_38(const volatile A&&);
+
+int test2_38()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_38(a))           == 3> t1;
+    sa<sizeof(sink_2_38(ca))          == 8> t2;
+    sa<sizeof(sink_2_38(va))          == 3> t3;
+    sa<sizeof(sink_2_38(cva))         == 8> t4;
+    sa<sizeof(sink_2_38(source()))    == 8> t5;
+    sa<sizeof(sink_2_38(c_source()))  == 8> t6;
+    sa<sizeof(sink_2_38(v_source()))  == 8> t7;
+    sa<sizeof(sink_2_38(cv_source())) == 8> t8;
+    return 0;
+}
+
+four  sink_2_45(const volatile A&);
+five  sink_2_45(               A&&);
+
+int test2_45()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_45(a))           == 4> t1;
+    sa<sizeof(sink_2_45(ca))          == 4> t2;
+    sa<sizeof(sink_2_45(va))          == 4> t3;
+    sa<sizeof(sink_2_45(cva))         == 4> t4;
+    sa<sizeof(sink_2_45(source()))    == 5> t5;
+//    sa<sizeof(sink_2_45(c_source()))  == 4> t6;
+//    sa<sizeof(sink_2_45(v_source()))  == 4> t7;
+//    sa<sizeof(sink_2_45(cv_source())) == 4> t8;
+    return 0;
+}
+
+four  sink_2_46(const volatile A&);
+six   sink_2_46(const          A&&);
+
+int test2_46()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_46(a))           == 4> t1;
+    sa<sizeof(sink_2_46(ca))          == 4> t2;
+    sa<sizeof(sink_2_46(va))          == 4> t3;
+    sa<sizeof(sink_2_46(cva))         == 4> t4;
+    sa<sizeof(sink_2_46(source()))    == 6> t5;
+    sa<sizeof(sink_2_46(c_source()))  == 6> t6;
+//    sa<sizeof(sink_2_46(v_source()))  == 4> t7;
+//    sa<sizeof(sink_2_46(cv_source())) == 4> t8;
+    return 0;
+}
+
+four  sink_2_47(const volatile A&);
+seven sink_2_47(volatile       A&&);
+
+int test2_47()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_47(a))           == 4> t1;
+    sa<sizeof(sink_2_47(ca))          == 4> t2;
+    sa<sizeof(sink_2_47(va))          == 4> t3;
+    sa<sizeof(sink_2_47(cva))         == 4> t4;
+    sa<sizeof(sink_2_47(source()))    == 7> t5;
+//    sa<sizeof(sink_2_47(c_source()))  == 4> t6;
+    sa<sizeof(sink_2_47(v_source()))  == 7> t7;
+//    sa<sizeof(sink_2_47(cv_source())) == 4> t8;
+    return 0;
+}
+
+four  sink_2_48(const volatile A&);
+eight sink_2_48(const volatile A&&);
+
+int test2_48()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_48(a))           == 4> t1;
+    sa<sizeof(sink_2_48(ca))          == 4> t2;
+    sa<sizeof(sink_2_48(va))          == 4> t3;
+    sa<sizeof(sink_2_48(cva))         == 4> t4;
+    sa<sizeof(sink_2_48(source()))    == 8> t5;
+    sa<sizeof(sink_2_48(c_source()))  == 8> t6;
+    sa<sizeof(sink_2_48(v_source()))  == 8> t7;
+    sa<sizeof(sink_2_48(cv_source())) == 8> t8;
+    return 0;
+}
+
+five  sink_2_56(               A&&);
+six   sink_2_56(const          A&&);
+
+int test2_56()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_56(a))           == 5> t1;
+    sa<sizeof(sink_2_56(ca))          == 6> t2;
+    sa<sizeof(sink_2_56(source()))    == 5> t5;
+    sa<sizeof(sink_2_56(c_source()))  == 6> t6;
+    return 0;
+}
+
+five  sink_2_57(               A&&);
+seven sink_2_57(volatile       A&&);
+
+int test2_57()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_57(a))           == 5> t1;
+    sa<sizeof(sink_2_57(va))          == 7> t3;
+    sa<sizeof(sink_2_57(source()))    == 5> t5;
+    sa<sizeof(sink_2_57(v_source()))  == 7> t7;
+    return 0;
+}
+
+five  sink_2_58(               A&&);
+eight sink_2_58(const volatile A&&);
+
+int test2_58()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_58(a))           == 5> t1;
+    sa<sizeof(sink_2_58(ca))          == 8> t2;
+    sa<sizeof(sink_2_58(va))          == 8> t3;
+    sa<sizeof(sink_2_58(cva))         == 8> t4;
+    sa<sizeof(sink_2_58(source()))    == 5> t5;
+    sa<sizeof(sink_2_58(c_source()))  == 8> t6;
+    sa<sizeof(sink_2_58(v_source()))  == 8> t7;
+    sa<sizeof(sink_2_58(cv_source())) == 8> t8;
+    return 0;
+}
+
+six   sink_2_67(const          A&&);
+seven sink_2_67(volatile       A&&);
+
+int test2_67()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_67(ca))          == 6> t2;
+    sa<sizeof(sink_2_67(va))          == 7> t3;
+    sa<sizeof(sink_2_67(c_source()))  == 6> t6;
+    sa<sizeof(sink_2_67(v_source()))  == 7> t7;
+    return 0;
+}
+
+six   sink_2_68(const          A&&);
+eight sink_2_68(const volatile A&&);
+
+int test2_68()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_68(a))           == 6> t1;
+    sa<sizeof(sink_2_68(ca))          == 6> t2;
+    sa<sizeof(sink_2_68(va))          == 8> t3;
+    sa<sizeof(sink_2_68(cva))         == 8> t4;
+    sa<sizeof(sink_2_68(source()))    == 6> t5;
+    sa<sizeof(sink_2_68(c_source()))  == 6> t6;
+    sa<sizeof(sink_2_68(v_source()))  == 8> t7;
+    sa<sizeof(sink_2_68(cv_source())) == 8> t8;
+    return 0;
+}
+
+seven sink_2_78(volatile       A&&);
+eight sink_2_78(const volatile A&&);
+
+int test2_78()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_2_78(a))           == 7> t1;
+    sa<sizeof(sink_2_78(ca))          == 8> t2;
+    sa<sizeof(sink_2_78(va))          == 7> t3;
+    sa<sizeof(sink_2_78(cva))         == 8> t4;
+    sa<sizeof(sink_2_78(source()))    == 7> t5;
+    sa<sizeof(sink_2_78(c_source()))  == 8> t6;
+    sa<sizeof(sink_2_78(v_source()))  == 7> t7;
+    sa<sizeof(sink_2_78(cv_source())) == 8> t8;
+    return 0;
+}
+
+int main()
+{
+    return test2_12() + test2_13() + test2_14() + test2_15() +
+           test2_16() + test2_17() + test2_18() + test2_23() +
+           test2_24() + test2_25() + test2_26() + test2_27() +
+           test2_28() + test2_34() + test2_35() + test2_36() +
+           test2_37() + test2_38() + test2_45() + test2_46() +
+           test2_47() + test2_48() + test2_56() + test2_57() +
+           test2_58() + test2_67() + test2_68() + test2_78();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv3n.C b/gcc/testsuite/g++.dg/cpp0x/rv3n.C
new file mode 100644
index 000000000000..e04ef4fee346
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv3n.C
@@ -0,0 +1,627 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 3 at a time
+
+one   sink_3_123(               A&);  // { dg-error "" }
+two   sink_3_123(const          A&);  // { dg-error "" }
+three sink_3_123(volatile       A&);  // { dg-error "" }
+
+int test3_123()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_123(cva);          // { dg-error "no match" }
+    sink_3_123(v_source());   // { dg-error "no match" }
+    sink_3_123(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_125(               A&);  // { dg-error "" }
+two   sink_3_125(const          A&);  // { dg-error "" }
+five  sink_3_125(               A&&);  // { dg-error "" }
+
+one   sink_3_124(               A&);  // { dg-error "" }
+two   sink_3_124(const          A&);  // { dg-error "" }
+four  sink_3_124(const volatile A&);  // { dg-error "" }
+
+int test3_124()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_124(v_source());   // { dg-error "no match" }
+    sink_3_124(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+int test3_125()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_125(va);           // { dg-error "no match" }
+    sink_3_125(cva);          // { dg-error "no match" }
+    sink_3_125(v_source());   // { dg-error "no match" }
+    sink_3_125(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_126(               A&);  // { dg-error "" }
+two   sink_3_126(const          A&);  // { dg-error "" }
+six   sink_3_126(const          A&&);  // { dg-error "" }
+
+int test3_126()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_126(va);           // { dg-error "no match" }
+    sink_3_126(cva);          // { dg-error "no match" }
+    sink_3_126(v_source());   // { dg-error "no match" }
+    sink_3_126(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_127(               A&);  // { dg-error "" }
+two   sink_3_127(const          A&);  // { dg-error "" }
+seven sink_3_127(volatile       A&&);  // { dg-error "" }
+
+int test3_127()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_127(cva);          // { dg-error "no match" }
+    sink_3_127(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_134(               A&);  // { dg-error "" }
+three sink_3_134(volatile       A&);  // { dg-error "" }
+four  sink_3_134(const volatile A&);  // { dg-error "" }
+
+int test3_134()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_134(source());     // { dg-error "no match" }
+    sink_3_134(c_source());   // { dg-error "no match" }
+    sink_3_134(v_source());   // { dg-error "no match" }
+    sink_3_134(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_135(               A&);  // { dg-error "" }
+three sink_3_135(volatile       A&);  // { dg-error "" }
+five  sink_3_135(               A&&);  // { dg-error "" }
+
+int test3_135()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_135(ca);           // { dg-error "no match" }
+    sink_3_135(cva);          // { dg-error "no match" }
+    sink_3_135(c_source());   // { dg-error "no match" }
+    sink_3_135(v_source());   // { dg-error "no match" }
+    sink_3_135(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_136(               A&);  // { dg-error "" }
+three sink_3_136(volatile       A&);  // { dg-error "" }
+six   sink_3_136(const          A&&);  // { dg-error "" }
+
+int test3_136()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_136(cva);          // { dg-error "no match" }
+    sink_3_136(v_source());   // { dg-error "no match" }
+    sink_3_136(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_137(               A&);  // { dg-error "" }
+three sink_3_137(volatile       A&);  // { dg-error "" }
+seven sink_3_137(volatile       A&&);  // { dg-error "" }
+
+int test3_137()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_137(ca);           // { dg-error "no match" }
+    sink_3_137(cva);          // { dg-error "no match" }
+    sink_3_137(c_source());   // { dg-error "no match" }
+    sink_3_137(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_145(               A&);  // { dg-error "" }
+four  sink_3_145(const volatile A&);  // { dg-error "" }
+five  sink_3_145(               A&&);  // { dg-error "" }
+
+int test3_145()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_145(c_source());   // { dg-error "no match" }
+    sink_3_145(v_source());   // { dg-error "no match" }
+    sink_3_145(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_146(               A&);  // { dg-error "" }
+four  sink_3_146(const volatile A&);  // { dg-error "" }
+six   sink_3_146(const          A&&);  // { dg-error "" }
+
+int test3_146()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_146(v_source());   // { dg-error "no match" }
+    sink_3_146(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_147(               A&);  // { dg-error "" }
+four  sink_3_147(const volatile A&);  // { dg-error "" }
+seven sink_3_147(volatile       A&&);  // { dg-error "" }
+
+int test3_147()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_147(c_source());   // { dg-error "no match" }
+    sink_3_147(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_156(               A&);  // { dg-error "" }
+five  sink_3_156(               A&&);  // { dg-error "" }
+six   sink_3_156(const          A&&);  // { dg-error "" }
+
+int test3_156()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_156(va);           // { dg-error "no match" }
+    sink_3_156(cva);          // { dg-error "no match" }
+    sink_3_156(v_source());   // { dg-error "no match" }
+    sink_3_156(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_157(               A&);  // { dg-error "" }
+five  sink_3_157(               A&&);  // { dg-error "" }
+seven sink_3_157(volatile       A&&);  // { dg-error "" }
+
+int test3_157()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_157(ca);           // { dg-error "no match" }
+    sink_3_157(cva);          // { dg-error "no match" }
+    sink_3_157(c_source());   // { dg-error "no match" }
+    sink_3_157(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_3_167(               A&);  // { dg-error "" }
+six   sink_3_167(const          A&&);  // { dg-error "" }
+seven sink_3_167(volatile       A&&);  // { dg-error "" }
+
+int test3_167()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_167(cva);          // { dg-error "no match" }
+    sink_3_167(source());     // { dg-error "ambiguous" }
+    sink_3_167(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_234(const          A&);  // { dg-error "" }
+three sink_3_234(volatile       A&);  // { dg-error "" }
+four  sink_3_234(const volatile A&);  // { dg-error "" }
+
+int test3_234()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_234(a);            // { dg-error "ambiguous" }
+    sink_3_234(v_source());   // { dg-error "no match" }
+    sink_3_234(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_235(const          A&);  // { dg-error "" }
+three sink_3_235(volatile       A&);  // { dg-error "" }
+five  sink_3_235(               A&&);  // { dg-error "" }
+
+int test3_235()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_235(a);            // { dg-error "ambiguous" }
+    sink_3_235(cva);          // { dg-error "no match" }
+    sink_3_235(v_source());   // { dg-error "no match" }
+    sink_3_235(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_236(const          A&);  // { dg-error "" }
+three sink_3_236(volatile       A&);  // { dg-error "" }
+six   sink_3_236(const          A&&);  // { dg-error "" }
+
+int test3_236()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_236(a);            // { dg-error "ambiguous" }
+    sink_3_236(cva);          // { dg-error "no match" }
+    sink_3_236(v_source());   // { dg-error "no match" }
+    sink_3_236(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_237(const          A&);  // { dg-error "" }
+three sink_3_237(volatile       A&);  // { dg-error "" }
+seven sink_3_237(volatile       A&&);  // { dg-error "" }
+
+int test3_237()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_237(a);            // { dg-error "ambiguous" }
+    sink_3_237(cva);          // { dg-error "no match" }
+    sink_3_237(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_238(const          A&);  // { dg-error "" }
+three sink_3_238(volatile       A&);  // { dg-error "" }
+eight sink_3_238(const volatile A&&);  // { dg-error "" }
+
+int test3_238()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_238(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_3_245(const          A&);  // { dg-error "" }
+four  sink_3_245(const volatile A&);  // { dg-error "" }
+five  sink_3_245(               A&&);  // { dg-error "" }
+
+int test3_245()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_245(v_source());   // { dg-error "no match" }
+    sink_3_245(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_246(const          A&);  // { dg-error "" }
+four  sink_3_246(const volatile A&);  // { dg-error "" }
+six   sink_3_246(const          A&&);  // { dg-error "" }
+
+int test3_246()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_246(v_source());   // { dg-error "no match" }
+    sink_3_246(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_247(const          A&);  // { dg-error "" }
+four  sink_3_247(const volatile A&);  // { dg-error "" }
+seven sink_3_247(volatile       A&&);  // { dg-error "" }
+
+int test3_247()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_247(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_256(const          A&);  // { dg-error "" }
+five  sink_3_256(               A&&);  // { dg-error "" }
+six   sink_3_256(const          A&&);  // { dg-error "" }
+
+int test3_256()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_256(va);           // { dg-error "no match" }
+    sink_3_256(cva);          // { dg-error "no match" }
+    sink_3_256(v_source());   // { dg-error "no match" }
+    sink_3_256(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_257(const          A&);  // { dg-error "" }
+five  sink_3_257(               A&&);  // { dg-error "" }
+seven sink_3_257(volatile       A&&);  // { dg-error "" }
+
+int test3_257()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_257(cva);          // { dg-error "no match" }
+    sink_3_257(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_3_267(const          A&);  // { dg-error "" }
+six   sink_3_267(const          A&&);  // { dg-error "" }
+seven sink_3_267(volatile       A&&);  // { dg-error "" }
+
+int test3_267()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_267(cva);          // { dg-error "no match" }
+    sink_3_267(source());     // { dg-error "ambiguous" }
+    sink_3_267(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_3_345(volatile       A&);  // { dg-error "" }
+four  sink_3_345(const volatile A&);  // { dg-error "" }
+five  sink_3_345(               A&&);  // { dg-error "" }
+
+int test3_345()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_345(c_source());   // { dg-error "no match" }
+    sink_3_345(v_source());   // { dg-error "no match" }
+    sink_3_345(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_3_346(volatile       A&);  // { dg-error "" }
+four  sink_3_346(const volatile A&);  // { dg-error "" }
+six   sink_3_346(const          A&&);  // { dg-error "" }
+
+int test3_346()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_346(v_source());   // { dg-error "no match" }
+    sink_3_346(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_3_347(volatile       A&);  // { dg-error "" }
+four  sink_3_347(const volatile A&);  // { dg-error "" }
+seven sink_3_347(volatile       A&&);  // { dg-error "" }
+
+int test3_347()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_347(c_source());   // { dg-error "no match" }
+    sink_3_347(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_3_356(volatile       A&);  // { dg-error "" }
+five  sink_3_356(               A&&);  // { dg-error "" }
+six   sink_3_356(const          A&&);  // { dg-error "" }
+
+int test3_356()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_356(cva);          // { dg-error "no match" }
+    sink_3_356(v_source());   // { dg-error "no match" }
+    sink_3_356(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_3_357(volatile       A&);  // { dg-error "" }
+five  sink_3_357(               A&&);  // { dg-error "" }
+seven sink_3_357(volatile       A&&);  // { dg-error "" }
+
+int test3_357()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_357(ca);           // { dg-error "no match" }
+    sink_3_357(cva);          // { dg-error "no match" }
+    sink_3_357(c_source());   // { dg-error "no match" }
+    sink_3_357(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_3_367(volatile       A&);  // { dg-error "" }
+six   sink_3_367(const          A&&);  // { dg-error "" }
+seven sink_3_367(volatile       A&&);  // { dg-error "" }
+
+int test3_367()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_367(cva);          // { dg-error "no match" }
+    sink_3_367(source());     // { dg-error "ambiguous" }
+    sink_3_367(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+four  sink_3_456(const volatile A&);  // { dg-error "" }
+five  sink_3_456(               A&&);  // { dg-error "" }
+six   sink_3_456(const          A&&);  // { dg-error "" }
+
+int test3_456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_456(v_source());   // { dg-error "no match" }
+    sink_3_456(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+four  sink_3_457(const volatile A&);  // { dg-error "" }
+five  sink_3_457(               A&&);  // { dg-error "" }
+seven sink_3_457(volatile       A&&);  // { dg-error "" }
+
+int test3_457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_457(c_source());   // { dg-error "no match" }
+    sink_3_457(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+four  sink_3_467(const volatile A&);  // { dg-error "" }
+six   sink_3_467(const          A&&);  // { dg-error "" }
+seven sink_3_467(volatile       A&&);  // { dg-error "" }
+
+int test3_467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_467(source());     // { dg-error "ambiguous" }
+    sink_3_467(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+five  sink_3_567(               A&&);  // { dg-error "" }
+six   sink_3_567(const          A&&);  // { dg-error "" }
+seven sink_3_567(volatile       A&&);  // { dg-error "" }
+
+int test3_567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_567(cva);          // { dg-error "no match" }
+    sink_3_567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+six   sink_3_678(const          A&&);  // { dg-error "" }
+seven sink_3_678(volatile       A&&);  // { dg-error "" }
+eight sink_3_678(const volatile A&&);  // { dg-error "" }
+
+int test3_678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_3_678(a);          // { dg-error "ambiguous" }
+    sink_3_678(source());   // { dg-error "ambiguous" }
+    return 0;
+}
+
+int main()
+{
+    return test3_123() + test3_125() + test3_126() + test3_127() +
+           test3_135() + test3_136() + test3_137() + test3_156() +
+           test3_157() + test3_167() + test3_234() + test3_235() +
+           test3_236() + test3_237() + test3_238() + test3_256() +
+           test3_257() + test3_267() + test3_356() + test3_357() +
+           test3_367() + test3_467() + test3_567() + test3_678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv3p.C b/gcc/testsuite/g++.dg/cpp0x/rv3p.C
new file mode 100644
index 000000000000..c688b11e2367
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv3p.C
@@ -0,0 +1,1120 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 3 at a time
+
+one   sink_3_123(               A&);
+two   sink_3_123(const          A&);
+three sink_3_123(volatile       A&);
+
+int test3_123()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_123(a))           == 1> t1;
+    sa<sizeof(sink_3_123(ca))          == 2> t2;
+    sa<sizeof(sink_3_123(va))          == 3> t3;
+    sa<sizeof(sink_3_123(source()))    == 2> t5;
+    sa<sizeof(sink_3_123(c_source()))  == 2> t6;
+    return 0;
+}
+
+one   sink_3_124(               A&);
+two   sink_3_124(const          A&);
+four  sink_3_124(const volatile A&);
+
+int test3_124()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_124(a))           == 1> t1;
+    sa<sizeof(sink_3_124(ca))          == 2> t2;
+    sa<sizeof(sink_3_124(va))          == 4> t3;
+    sa<sizeof(sink_3_124(cva))         == 4> t4;
+    sa<sizeof(sink_3_124(source()))    == 2> t5;
+    sa<sizeof(sink_3_124(c_source()))  == 2> t6;
+    return 0;
+}
+
+one   sink_3_125(               A&);
+two   sink_3_125(const          A&);
+five  sink_3_125(               A&&);
+
+int test3_125()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_125(a))           == 1> t1;
+    sa<sizeof(sink_3_125(ca))          == 2> t2;
+    sa<sizeof(sink_3_125(source()))    == 5> t5;
+    sa<sizeof(sink_3_125(c_source()))  == 2> t6;
+    return 0;
+}
+
+one   sink_3_126(               A&);
+two   sink_3_126(const          A&);
+six   sink_3_126(const          A&&);
+
+int test3_126()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_126(a))           == 1> t1;
+    sa<sizeof(sink_3_126(ca))          == 2> t2;
+    sa<sizeof(sink_3_126(source()))    == 6> t5;
+    sa<sizeof(sink_3_126(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_3_127(               A&);
+two   sink_3_127(const          A&);
+seven sink_3_127(volatile       A&&);
+
+int test3_127()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_127(a))           == 1> t1;
+    sa<sizeof(sink_3_127(ca))          == 2> t2;
+    sa<sizeof(sink_3_127(va))          == 7> t3;
+    sa<sizeof(sink_3_127(source()))    == 7> t5;
+    sa<sizeof(sink_3_127(c_source()))  == 2> t6;
+    sa<sizeof(sink_3_127(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_3_128(               A&);
+two   sink_3_128(const          A&);
+eight sink_3_128(const volatile A&&);
+
+int test3_128()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_128(a))           == 1> t1;
+    sa<sizeof(sink_3_128(ca))          == 2> t2;
+    sa<sizeof(sink_3_128(va))          == 8> t3;
+    sa<sizeof(sink_3_128(cva))         == 8> t4;
+    sa<sizeof(sink_3_128(source()))    == 8> t5;
+    sa<sizeof(sink_3_128(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_128(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_128(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_3_134(               A&);
+three sink_3_134(volatile       A&);
+four  sink_3_134(const volatile A&);
+
+int test3_134()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_134(a))           == 1> t1;
+    sa<sizeof(sink_3_134(ca))          == 4> t2;
+    sa<sizeof(sink_3_134(va))          == 3> t3;
+    sa<sizeof(sink_3_134(cva))         == 4> t4;
+    return 0;
+}
+
+one   sink_3_135(               A&);
+three sink_3_135(volatile       A&);
+five  sink_3_135(               A&&);
+
+int test3_135()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_135(a))           == 1> t1;
+    sa<sizeof(sink_3_135(va))          == 3> t3;
+    sa<sizeof(sink_3_135(source()))    == 5> t5;
+    return 0;
+}
+
+one   sink_3_136(               A&);
+three sink_3_136(volatile       A&);
+six   sink_3_136(const          A&&);
+
+int test3_136()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_136(a))           == 1> t1;
+    sa<sizeof(sink_3_136(ca))          == 6> t2;
+    sa<sizeof(sink_3_136(va))          == 3> t3;
+    sa<sizeof(sink_3_136(source()))    == 6> t5;
+    sa<sizeof(sink_3_136(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_3_137(               A&);
+three sink_3_137(volatile       A&);
+seven sink_3_137(volatile       A&&);
+
+int test3_137()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_137(a))           == 1> t1;
+    sa<sizeof(sink_3_137(va))          == 3> t3;
+    sa<sizeof(sink_3_137(source()))    == 7> t5;
+    sa<sizeof(sink_3_137(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_3_138(               A&);
+three sink_3_138(volatile       A&);
+eight sink_3_138(const volatile A&&);
+
+int test3_138()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_138(a))           == 1> t1;
+    sa<sizeof(sink_3_138(ca))          == 8> t2;
+    sa<sizeof(sink_3_138(va))          == 3> t3;
+    sa<sizeof(sink_3_138(cva))         == 8> t4;
+    sa<sizeof(sink_3_138(source()))    == 8> t5;
+    sa<sizeof(sink_3_138(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_138(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_138(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_3_145(               A&);
+four  sink_3_145(const volatile A&);
+five  sink_3_145(               A&&);
+
+int test3_145()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_145(a))           == 1> t1;
+    sa<sizeof(sink_3_145(ca))          == 4> t2;
+    sa<sizeof(sink_3_145(va))          == 4> t3;
+    sa<sizeof(sink_3_145(cva))         == 4> t4;
+    sa<sizeof(sink_3_145(source()))    == 5> t5;
+    return 0;
+}
+
+one   sink_3_146(               A&);
+four  sink_3_146(const volatile A&);
+six   sink_3_146(const          A&&);
+
+int test3_146()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_146(a))           == 1> t1;
+    sa<sizeof(sink_3_146(ca))          == 4> t2;
+    sa<sizeof(sink_3_146(va))          == 4> t3;
+    sa<sizeof(sink_3_146(cva))         == 4> t4;
+    sa<sizeof(sink_3_146(source()))    == 6> t5;
+    sa<sizeof(sink_3_146(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_3_147(               A&);
+four  sink_3_147(const volatile A&);
+seven sink_3_147(volatile       A&&);
+
+int test3_147()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_147(a))           == 1> t1;
+    sa<sizeof(sink_3_147(ca))          == 4> t2;
+    sa<sizeof(sink_3_147(va))          == 4> t3;
+    sa<sizeof(sink_3_147(cva))         == 4> t4;
+    sa<sizeof(sink_3_147(source()))    == 7> t5;
+    sa<sizeof(sink_3_147(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_3_148(               A&);
+four  sink_3_148(const volatile A&);
+eight sink_3_148(const volatile A&&);
+
+int test3_148()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_148(a))           == 1> t1;
+    sa<sizeof(sink_3_148(ca))          == 4> t2;
+    sa<sizeof(sink_3_148(va))          == 4> t3;
+    sa<sizeof(sink_3_148(cva))         == 4> t4;
+    sa<sizeof(sink_3_148(source()))    == 8> t5;
+    sa<sizeof(sink_3_148(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_148(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_148(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_3_156(               A&);
+five  sink_3_156(               A&&);
+six   sink_3_156(const          A&&);
+
+int test3_156()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_156(a))           == 1> t1;
+    sa<sizeof(sink_3_156(ca))          == 6> t2;
+    sa<sizeof(sink_3_156(source()))    == 5> t5;
+    sa<sizeof(sink_3_156(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_3_157(               A&);
+five  sink_3_157(               A&&);
+seven sink_3_157(volatile       A&&);
+
+int test3_157()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_157(a))           == 1> t1;
+    sa<sizeof(sink_3_157(va))          == 7> t3;
+    sa<sizeof(sink_3_157(source()))    == 5> t5;
+    sa<sizeof(sink_3_157(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_3_158(               A&);
+five  sink_3_158(               A&&);
+eight sink_3_158(const volatile A&&);
+
+int test3_158()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_158(a))           == 1> t1;
+    sa<sizeof(sink_3_158(ca))          == 8> t2;
+    sa<sizeof(sink_3_158(va))          == 8> t3;
+    sa<sizeof(sink_3_158(cva))         == 8> t4;
+    sa<sizeof(sink_3_158(source()))    == 5> t5;
+    sa<sizeof(sink_3_158(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_158(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_158(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_3_167(               A&);
+six   sink_3_167(const          A&&);
+seven sink_3_167(volatile       A&&);
+
+int test3_167()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_167(a))           == 1> t1;
+    sa<sizeof(sink_3_167(ca))          == 6> t2;
+    sa<sizeof(sink_3_167(va))          == 7> t3;
+    sa<sizeof(sink_3_167(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_167(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_3_168(               A&);
+six   sink_3_168(const          A&&);
+eight sink_3_168(const volatile A&&);
+
+int test3_168()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_168(a))           == 1> t1;
+    sa<sizeof(sink_3_168(ca))          == 6> t2;
+    sa<sizeof(sink_3_168(va))          == 8> t3;
+    sa<sizeof(sink_3_168(cva))         == 8> t4;
+    sa<sizeof(sink_3_168(source()))    == 6> t5;
+    sa<sizeof(sink_3_168(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_168(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_168(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_3_178(               A&);
+seven sink_3_178(volatile       A&&);
+eight sink_3_178(const volatile A&&);
+
+int test3_178()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_178(a))           == 1> t1;
+    sa<sizeof(sink_3_178(ca))          == 8> t2;
+    sa<sizeof(sink_3_178(va))          == 7> t3;
+    sa<sizeof(sink_3_178(cva))         == 8> t4;
+    sa<sizeof(sink_3_178(source()))    == 7> t5;
+    sa<sizeof(sink_3_178(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_178(v_source()))  == 7> t7;
+    sa<sizeof(sink_3_178(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_3_234(const          A&);
+three sink_3_234(volatile       A&);
+four  sink_3_234(const volatile A&);
+
+int test3_234()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_234(ca))          == 2> t2;
+    sa<sizeof(sink_3_234(va))          == 3> t3;
+    sa<sizeof(sink_3_234(cva))         == 4> t4;
+    sa<sizeof(sink_3_234(source()))    == 2> t5;
+    sa<sizeof(sink_3_234(c_source()))  == 2> t6;
+    return 0;
+}
+
+two   sink_3_235(const          A&);
+three sink_3_235(volatile       A&);
+five  sink_3_235(               A&&);
+
+int test3_235()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_235(ca))          == 2> t2;
+    sa<sizeof(sink_3_235(va))          == 3> t3;
+    sa<sizeof(sink_3_235(source()))    == 5> t5;
+    sa<sizeof(sink_3_235(c_source()))  == 2> t6;
+    return 0;
+}
+
+two   sink_3_236(const          A&);
+three sink_3_236(volatile       A&);
+six   sink_3_236(const          A&&);
+
+int test3_236()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_236(ca))          == 2> t2;
+    sa<sizeof(sink_3_236(va))          == 3> t3;
+    sa<sizeof(sink_3_236(source()))    == 6> t5;
+    sa<sizeof(sink_3_236(c_source()))  == 6> t6;
+    return 0;
+}
+
+two   sink_3_237(const          A&);
+three sink_3_237(volatile       A&);
+seven sink_3_237(volatile       A&&);
+
+int test3_237()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_237(ca))          == 2> t2;
+    sa<sizeof(sink_3_237(va))          == 3> t3;
+    sa<sizeof(sink_3_237(source()))    == 7> t5;
+    sa<sizeof(sink_3_237(c_source()))  == 2> t6;
+    sa<sizeof(sink_3_237(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_3_238(const          A&);
+three sink_3_238(volatile       A&);
+eight sink_3_238(const volatile A&&);
+
+int test3_238()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_238(ca))          == 2> t2;
+    sa<sizeof(sink_3_238(va))          == 3> t3;
+    sa<sizeof(sink_3_238(cva))         == 8> t4;
+    sa<sizeof(sink_3_238(source()))    == 8> t5;
+    sa<sizeof(sink_3_238(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_238(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_238(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_3_245(const          A&);
+four  sink_3_245(const volatile A&);
+five  sink_3_245(               A&&);
+
+int test3_245()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_245(a))           == 2> t1;
+    sa<sizeof(sink_3_245(ca))          == 2> t2;
+    sa<sizeof(sink_3_245(va))          == 4> t3;
+    sa<sizeof(sink_3_245(cva))         == 4> t4;
+    sa<sizeof(sink_3_245(source()))    == 5> t5;
+    sa<sizeof(sink_3_245(c_source()))  == 2> t6;
+    return 0;
+}
+
+two   sink_3_246(const          A&);
+four  sink_3_246(const volatile A&);
+six   sink_3_246(const          A&&);
+
+int test3_246()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_246(a))           == 2> t1;
+    sa<sizeof(sink_3_246(ca))          == 2> t2;
+    sa<sizeof(sink_3_246(va))          == 4> t3;
+    sa<sizeof(sink_3_246(cva))         == 4> t4;
+    sa<sizeof(sink_3_246(source()))    == 6> t5;
+    sa<sizeof(sink_3_246(c_source()))  == 6> t6;
+    return 0;
+}
+
+two   sink_3_247(const          A&);
+four  sink_3_247(const volatile A&);
+seven sink_3_247(volatile       A&&);
+
+int test3_247()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_247(a))           == 2> t1;
+    sa<sizeof(sink_3_247(ca))          == 2> t2;
+    sa<sizeof(sink_3_247(va))          == 4> t3;
+    sa<sizeof(sink_3_247(cva))         == 4> t4;
+    sa<sizeof(sink_3_247(source()))    == 7> t5;
+    sa<sizeof(sink_3_247(c_source()))  == 2> t6;
+    sa<sizeof(sink_3_247(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_3_248(const          A&);
+four  sink_3_248(const volatile A&);
+eight sink_3_248(const volatile A&&);
+
+int test3_248()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_248(a))           == 2> t1;
+    sa<sizeof(sink_3_248(ca))          == 2> t2;
+    sa<sizeof(sink_3_248(va))          == 4> t3;
+    sa<sizeof(sink_3_248(cva))         == 4> t4;
+    sa<sizeof(sink_3_248(source()))    == 8> t5;
+    sa<sizeof(sink_3_248(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_248(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_248(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_3_256(const          A&);
+five  sink_3_256(               A&&);
+six   sink_3_256(const          A&&);
+
+int test3_256()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_256(a))           == 2> t1;
+    sa<sizeof(sink_3_256(ca))          == 2> t2;
+    sa<sizeof(sink_3_256(source()))    == 5> t5;
+    sa<sizeof(sink_3_256(c_source()))  == 6> t6;
+    return 0;
+}
+
+two   sink_3_257(const          A&);
+five  sink_3_257(               A&&);
+seven sink_3_257(volatile       A&&);
+
+int test3_257()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_257(a))           == 2> t1;
+    sa<sizeof(sink_3_257(ca))          == 2> t2;
+    sa<sizeof(sink_3_257(va))          == 7> t3;
+    sa<sizeof(sink_3_257(source()))    == 5> t5;
+    sa<sizeof(sink_3_257(c_source()))  == 2> t6;
+    sa<sizeof(sink_3_257(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_3_258(const          A&);
+five  sink_3_258(               A&&);
+eight sink_3_258(const volatile A&&);
+
+int test3_258()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_258(a))           == 2> t1;
+    sa<sizeof(sink_3_258(ca))          == 2> t2;
+    sa<sizeof(sink_3_258(va))          == 8> t3;
+    sa<sizeof(sink_3_258(cva))         == 8> t4;
+    sa<sizeof(sink_3_258(source()))    == 5> t5;
+    sa<sizeof(sink_3_258(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_258(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_258(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_3_267(const          A&);
+six   sink_3_267(const          A&&);
+seven sink_3_267(volatile       A&&);
+
+int test3_267()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_267(a))           == 2> t1;
+    sa<sizeof(sink_3_267(ca))          == 2> t2;
+    sa<sizeof(sink_3_267(va))          == 7> t3;
+    sa<sizeof(sink_3_267(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_267(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_3_268(const          A&);
+six   sink_3_268(const          A&&);
+eight sink_3_268(const volatile A&&);
+
+int test3_268()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_268(a))           == 2> t1;
+    sa<sizeof(sink_3_268(ca))          == 2> t2;
+    sa<sizeof(sink_3_268(va))          == 8> t3;
+    sa<sizeof(sink_3_268(cva))         == 8> t4;
+    sa<sizeof(sink_3_268(source()))    == 6> t5;
+    sa<sizeof(sink_3_268(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_268(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_268(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_3_278(const          A&);
+seven sink_3_278(volatile       A&&);
+eight sink_3_278(const volatile A&&);
+
+int test3_278()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_278(a))           == 2> t1;
+    sa<sizeof(sink_3_278(ca))          == 2> t2;
+    sa<sizeof(sink_3_278(va))          == 7> t3;
+    sa<sizeof(sink_3_278(cva))         == 8> t4;
+    sa<sizeof(sink_3_278(source()))    == 7> t5;
+    sa<sizeof(sink_3_278(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_278(v_source()))  == 7> t7;
+    sa<sizeof(sink_3_278(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_3_345(volatile       A&);
+four  sink_3_345(const volatile A&);
+five  sink_3_345(               A&&);
+
+int test3_345()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_345(a))           == 3> t1;
+    sa<sizeof(sink_3_345(ca))          == 4> t2;
+    sa<sizeof(sink_3_345(va))          == 3> t3;
+    sa<sizeof(sink_3_345(cva))         == 4> t4;
+    sa<sizeof(sink_3_345(source()))    == 5> t5;
+    return 0;
+}
+
+three sink_3_346(volatile       A&);
+four  sink_3_346(const volatile A&);
+six   sink_3_346(const          A&&);
+
+int test3_346()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_346(a))           == 3> t1;
+    sa<sizeof(sink_3_346(ca))          == 4> t2;
+    sa<sizeof(sink_3_346(va))          == 3> t3;
+    sa<sizeof(sink_3_346(cva))         == 4> t4;
+    sa<sizeof(sink_3_346(source()))    == 6> t5;
+    sa<sizeof(sink_3_346(c_source()))  == 6> t6;
+    return 0;
+}
+
+three sink_3_347(volatile       A&);
+four  sink_3_347(const volatile A&);
+seven sink_3_347(volatile       A&&);
+
+int test3_347()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_347(a))           == 3> t1;
+    sa<sizeof(sink_3_347(ca))          == 4> t2;
+    sa<sizeof(sink_3_347(va))          == 3> t3;
+    sa<sizeof(sink_3_347(cva))         == 4> t4;
+    sa<sizeof(sink_3_347(source()))    == 7> t5;
+    sa<sizeof(sink_3_347(v_source()))  == 7> t7;
+    return 0;
+}
+
+three sink_3_348(volatile       A&);
+four  sink_3_348(const volatile A&);
+eight sink_3_348(const volatile A&&);
+
+int test3_348()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_348(a))           == 3> t1;
+    sa<sizeof(sink_3_348(ca))          == 4> t2;
+    sa<sizeof(sink_3_348(va))          == 3> t3;
+    sa<sizeof(sink_3_348(cva))         == 4> t4;
+    sa<sizeof(sink_3_348(source()))    == 8> t5;
+    sa<sizeof(sink_3_348(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_348(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_348(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_3_356(volatile       A&);
+five  sink_3_356(               A&&);
+six   sink_3_356(const          A&&);
+
+int test3_356()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_356(a))           == 3> t1;
+    sa<sizeof(sink_3_356(ca))          == 6> t2;
+    sa<sizeof(sink_3_356(va))          == 3> t3;
+    sa<sizeof(sink_3_356(source()))    == 5> t5;
+    sa<sizeof(sink_3_356(c_source()))  == 6> t6;
+    return 0;
+}
+
+three sink_3_357(volatile       A&);
+five  sink_3_357(               A&&);
+seven sink_3_357(volatile       A&&);
+
+int test3_357()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_357(a))           == 3> t1;
+    sa<sizeof(sink_3_357(va))          == 3> t3;
+    sa<sizeof(sink_3_357(source()))    == 5> t5;
+    sa<sizeof(sink_3_357(v_source()))  == 7> t7;
+    return 0;
+}
+
+three sink_3_358(volatile       A&);
+five  sink_3_358(               A&&);
+eight sink_3_358(const volatile A&&);
+
+int test3_358()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_358(a))           == 3> t1;
+    sa<sizeof(sink_3_358(ca))          == 8> t2;
+    sa<sizeof(sink_3_358(va))          == 3> t3;
+    sa<sizeof(sink_3_358(cva))         == 8> t4;
+    sa<sizeof(sink_3_358(source()))    == 5> t5;
+    sa<sizeof(sink_3_358(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_358(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_358(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_3_367(volatile       A&);
+six   sink_3_367(const          A&&);
+seven sink_3_367(volatile       A&&);
+
+int test3_367()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_367(a))           == 3> t1;
+    sa<sizeof(sink_3_367(ca))          == 6> t2;
+    sa<sizeof(sink_3_367(va))          == 3> t3;
+    sa<sizeof(sink_3_367(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_367(v_source()))  == 7> t7;
+    return 0;
+}
+
+three sink_3_368(volatile       A&);
+six   sink_3_368(const          A&&);
+eight sink_3_368(const volatile A&&);
+
+int test3_368()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_368(a))           == 3> t1;
+    sa<sizeof(sink_3_368(ca))          == 6> t2;
+    sa<sizeof(sink_3_368(va))          == 3> t3;
+    sa<sizeof(sink_3_368(cva))         == 8> t4;
+    sa<sizeof(sink_3_368(source()))    == 6> t5;
+    sa<sizeof(sink_3_368(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_368(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_368(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_3_378(volatile       A&);
+seven sink_3_378(volatile       A&&);
+eight sink_3_378(const volatile A&&);
+
+int test3_378()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_378(a))           == 3> t1;
+    sa<sizeof(sink_3_378(ca))          == 8> t2;
+    sa<sizeof(sink_3_378(va))          == 3> t3;
+    sa<sizeof(sink_3_378(cva))         == 8> t4;
+    sa<sizeof(sink_3_378(source()))    == 7> t5;
+    sa<sizeof(sink_3_378(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_378(v_source()))  == 7> t7;
+    sa<sizeof(sink_3_378(cv_source())) == 8> t8;
+    return 0;
+}
+
+four  sink_3_456(const volatile A&);
+five  sink_3_456(               A&&);
+six   sink_3_456(const          A&&);
+
+int test3_456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_456(a))           == 4> t1;
+    sa<sizeof(sink_3_456(ca))          == 4> t2;
+    sa<sizeof(sink_3_456(va))          == 4> t3;
+    sa<sizeof(sink_3_456(cva))         == 4> t4;
+    sa<sizeof(sink_3_456(source()))    == 5> t5;
+    sa<sizeof(sink_3_456(c_source()))  == 6> t6;
+    return 0;
+}
+
+four  sink_3_457(const volatile A&);
+five  sink_3_457(               A&&);
+seven sink_3_457(volatile       A&&);
+
+int test3_457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_457(a))           == 4> t1;
+    sa<sizeof(sink_3_457(ca))          == 4> t2;
+    sa<sizeof(sink_3_457(va))          == 4> t3;
+    sa<sizeof(sink_3_457(cva))         == 4> t4;
+    sa<sizeof(sink_3_457(source()))    == 5> t5;
+    sa<sizeof(sink_3_457(v_source()))  == 7> t7;
+    return 0;
+}
+
+four  sink_3_458(const volatile A&);
+five  sink_3_458(               A&&);
+eight sink_3_458(const volatile A&&);
+
+int test3_458()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_458(a))           == 4> t1;
+    sa<sizeof(sink_3_458(ca))          == 4> t2;
+    sa<sizeof(sink_3_458(va))          == 4> t3;
+    sa<sizeof(sink_3_458(cva))         == 4> t4;
+    sa<sizeof(sink_3_458(source()))    == 5> t5;
+    sa<sizeof(sink_3_458(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_458(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_458(cv_source())) == 8> t8;
+    return 0;
+}
+
+four  sink_3_467(const volatile A&);
+six   sink_3_467(const          A&&);
+seven sink_3_467(volatile       A&&);
+
+int test3_467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_467(a))           == 4> t1;
+    sa<sizeof(sink_3_467(ca))          == 4> t2;
+    sa<sizeof(sink_3_467(va))          == 4> t3;
+    sa<sizeof(sink_3_467(cva))         == 4> t4;
+    sa<sizeof(sink_3_467(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_467(v_source()))  == 7> t7;
+    return 0;
+}
+
+four  sink_3_468(const volatile A&);
+six   sink_3_468(const          A&&);
+eight sink_3_468(const volatile A&&);
+
+int test3_468()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_468(a))           == 4> t1;
+    sa<sizeof(sink_3_468(ca))          == 4> t2;
+    sa<sizeof(sink_3_468(va))          == 4> t3;
+    sa<sizeof(sink_3_468(cva))         == 4> t4;
+    sa<sizeof(sink_3_468(source()))    == 6> t5;
+    sa<sizeof(sink_3_468(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_468(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_468(cv_source())) == 8> t8;
+    return 0;
+}
+
+four  sink_3_478(const volatile A&);
+seven sink_3_478(volatile       A&&);
+eight sink_3_478(const volatile A&&);
+
+int test3_478()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_478(a))           == 4> t1;
+    sa<sizeof(sink_3_478(ca))          == 4> t2;
+    sa<sizeof(sink_3_478(va))          == 4> t3;
+    sa<sizeof(sink_3_478(cva))         == 4> t4;
+    sa<sizeof(sink_3_478(source()))    == 7> t5;
+    sa<sizeof(sink_3_478(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_478(v_source()))  == 7> t7;
+    sa<sizeof(sink_3_478(cv_source())) == 8> t8;
+    return 0;
+}
+
+five  sink_3_567(               A&&);
+six   sink_3_567(const          A&&);
+seven sink_3_567(volatile       A&&);
+
+int test3_567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_567(a))           == 5> t1;
+    sa<sizeof(sink_3_567(ca))          == 6> t2;
+    sa<sizeof(sink_3_567(va))          == 7> t3;
+    sa<sizeof(sink_3_567(source()))    == 5> t5;
+    sa<sizeof(sink_3_567(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_567(v_source()))  == 7> t7;
+    return 0;
+}
+
+five  sink_3_568(               A&&);
+six   sink_3_568(const          A&&);
+eight sink_3_568(const volatile A&&);
+
+int test3_568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_568(a))           == 5> t1;
+    sa<sizeof(sink_3_568(ca))          == 6> t2;
+    sa<sizeof(sink_3_568(va))          == 8> t3;
+    sa<sizeof(sink_3_568(cva))         == 8> t4;
+    sa<sizeof(sink_3_568(source()))    == 5> t5;
+    sa<sizeof(sink_3_568(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_568(v_source()))  == 8> t7;
+    sa<sizeof(sink_3_568(cv_source())) == 8> t8;
+    return 0;
+}
+
+five  sink_3_578(               A&&);
+seven sink_3_578(volatile       A&&);
+eight sink_3_578(const volatile A&&);
+
+int test3_578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_578(a))           == 5> t1;
+    sa<sizeof(sink_3_578(ca))          == 8> t2;
+    sa<sizeof(sink_3_578(va))          == 7> t3;
+    sa<sizeof(sink_3_578(cva))         == 8> t4;
+    sa<sizeof(sink_3_578(source()))    == 5> t5;
+    sa<sizeof(sink_3_578(c_source()))  == 8> t6;
+    sa<sizeof(sink_3_578(v_source()))  == 7> t7;
+    sa<sizeof(sink_3_578(cv_source())) == 8> t8;
+    return 0;
+}
+
+six   sink_3_678(const          A&&);
+seven sink_3_678(volatile       A&&);
+eight sink_3_678(const volatile A&&);
+
+int test3_678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_3_678(ca))          == 6> t2;
+    sa<sizeof(sink_3_678(va))          == 7> t3;
+    sa<sizeof(sink_3_678(cva))         == 8> t4;
+    sa<sizeof(sink_3_678(c_source()))  == 6> t6;
+    sa<sizeof(sink_3_678(v_source()))  == 7> t7;
+    sa<sizeof(sink_3_678(cv_source())) == 8> t8;
+    return 0;
+}
+
+int main()
+{
+    return test3_123() + test3_124() + test3_125() + test3_126() +
+           test3_127() + test3_128() + test3_134() + test3_135() +
+           test3_136() + test3_137() + test3_138() + test3_145() +
+           test3_146() + test3_147() + test3_148() + test3_156() +
+           test3_157() + test3_158() + test3_167() + test3_168() +
+           test3_178() + test3_234() + test3_235() + test3_236() +
+           test3_237() + test3_238() + test3_245() + test3_246() +
+           test3_247() + test3_248() + test3_256() + test3_257() +
+           test3_258() + test3_267() + test3_268() + test3_278() +
+           test3_345() + test3_346() + test3_347() + test3_348() +
+           test3_356() + test3_357() + test3_358() + test3_367() +
+           test3_368() + test3_378() + test3_456() + test3_457() +
+           test3_458() + test3_467() + test3_468() + test3_478() +
+           test3_567() + test3_568() + test3_578() + test3_678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv4n.C b/gcc/testsuite/g++.dg/cpp0x/rv4n.C
new file mode 100644
index 000000000000..302ab8eedcc7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv4n.C
@@ -0,0 +1,735 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 4 at a time
+
+one   sink_4_1234(               A&);  // { dg-error "" }
+two   sink_4_1234(const          A&);  // { dg-error "" }
+three sink_4_1234(volatile       A&);  // { dg-error "" }
+four  sink_4_1234(const volatile A&);  // { dg-error "" }
+
+int test4_1234()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1234(v_source());   // { dg-error "no match" }
+    sink_4_1234(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1235(               A&);  // { dg-error "" }
+two   sink_4_1235(const          A&);  // { dg-error "" }
+three sink_4_1235(volatile       A&);  // { dg-error "" }
+five  sink_4_1235(               A&&);  // { dg-error "" }
+
+int test4_1235()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1235(cva);          // { dg-error "no match" }
+    sink_4_1235(v_source());   // { dg-error "no match" }
+    sink_4_1235(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1236(               A&);  // { dg-error "" }
+two   sink_4_1236(const          A&);  // { dg-error "" }
+three sink_4_1236(volatile       A&);  // { dg-error "" }
+six   sink_4_1236(const          A&&);  // { dg-error "" }
+
+int test4_1236()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1236(cva);          // { dg-error "no match" }
+    sink_4_1236(v_source());   // { dg-error "no match" }
+    sink_4_1236(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1237(               A&);  // { dg-error "" }
+two   sink_4_1237(const          A&);  // { dg-error "" }
+three sink_4_1237(volatile       A&);  // { dg-error "" }
+seven sink_4_1237(volatile       A&&);  // { dg-error "" }
+
+int test4_1237()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1237(cva);          // { dg-error "no match" }
+    sink_4_1237(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1245(               A&);  // { dg-error "" }
+two   sink_4_1245(const          A&);  // { dg-error "" }
+four  sink_4_1245(const volatile A&);  // { dg-error "" }
+five  sink_4_1245(               A&&);  // { dg-error "" }
+
+int test4_1245()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1245(v_source());   // { dg-error "no match" }
+    sink_4_1245(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1246(               A&);  // { dg-error "" }
+two   sink_4_1246(const          A&);  // { dg-error "" }
+four  sink_4_1246(const volatile A&);  // { dg-error "" }
+six   sink_4_1246(const          A&&);  // { dg-error "" }
+
+int test4_1246()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1246(v_source());   // { dg-error "no match" }
+    sink_4_1246(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1247(               A&);  // { dg-error "" }
+two   sink_4_1247(const          A&);  // { dg-error "" }
+four  sink_4_1247(const volatile A&);  // { dg-error "" }
+seven sink_4_1247(volatile       A&&);  // { dg-error "" }
+
+int test4_1247()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1247(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1256(               A&);  // { dg-error "" }
+two   sink_4_1256(const          A&);  // { dg-error "" }
+five  sink_4_1256(               A&&);  // { dg-error "" }
+six   sink_4_1256(const          A&&);  // { dg-error "" }
+
+int test4_1256()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1256(va);           // { dg-error "no match" }
+    sink_4_1256(cva);          // { dg-error "no match" }
+    sink_4_1256(v_source());   // { dg-error "no match" }
+    sink_4_1256(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1257(               A&);  // { dg-error "" }
+two   sink_4_1257(const          A&);  // { dg-error "" }
+five  sink_4_1257(               A&&);  // { dg-error "" }
+seven sink_4_1257(volatile       A&&);  // { dg-error "" }
+
+int test4_1257()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1257(cva);          // { dg-error "no match" }
+    sink_4_1257(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1267(               A&);  // { dg-error "" }
+two   sink_4_1267(const          A&);  // { dg-error "" }
+six   sink_4_1267(const          A&&);  // { dg-error "" }
+seven sink_4_1267(volatile       A&&);  // { dg-error "" }
+
+int test4_1267()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1267(cva);          // { dg-error "no match" }
+    sink_4_1267(source());     // { dg-error "ambiguous" }
+    sink_4_1267(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1345(               A&);  // { dg-error "" }
+three sink_4_1345(volatile       A&);  // { dg-error "" }
+four  sink_4_1345(const volatile A&);  // { dg-error "" }
+five  sink_4_1345(               A&&);  // { dg-error "" }
+
+int test4_1345()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1345(c_source());   // { dg-error "no match" }
+    sink_4_1345(v_source());   // { dg-error "no match" }
+    sink_4_1345(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1346(               A&);  // { dg-error "" }
+three sink_4_1346(volatile       A&);  // { dg-error "" }
+four  sink_4_1346(const volatile A&);  // { dg-error "" }
+six   sink_4_1346(const          A&&);  // { dg-error "" }
+
+int test4_1346()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1346(v_source());   // { dg-error "no match" }
+    sink_4_1346(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1347(               A&);  // { dg-error "" }
+three sink_4_1347(volatile       A&);  // { dg-error "" }
+four  sink_4_1347(const volatile A&);  // { dg-error "" }
+seven sink_4_1347(volatile       A&&);  // { dg-error "" }
+
+int test4_1347()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1347(c_source());   // { dg-error "no match" }
+    sink_4_1347(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1356(               A&);  // { dg-error "" }
+three sink_4_1356(volatile       A&);  // { dg-error "" }
+five  sink_4_1356(               A&&);  // { dg-error "" }
+six   sink_4_1356(const          A&&);  // { dg-error "" }
+
+int test4_1356()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1356(cva);          // { dg-error "no match" }
+    sink_4_1356(v_source());   // { dg-error "no match" }
+    sink_4_1356(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1357(               A&);  // { dg-error "" }
+three sink_4_1357(volatile       A&);  // { dg-error "" }
+five  sink_4_1357(               A&&);  // { dg-error "" }
+seven sink_4_1357(volatile       A&&);  // { dg-error "" }
+
+int test4_1357()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1357(ca);           // { dg-error "no match" }
+    sink_4_1357(cva);          // { dg-error "no match" }
+    sink_4_1357(c_source());   // { dg-error "no match" }
+    sink_4_1357(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1367(               A&);  // { dg-error "" }
+three sink_4_1367(volatile       A&);  // { dg-error "" }
+six   sink_4_1367(const          A&&);  // { dg-error "" }
+seven sink_4_1367(volatile       A&&);  // { dg-error "" }
+
+int test4_1367()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1367(cva);          // { dg-error "no match" }
+    sink_4_1367(source());     // { dg-error "ambiguous" }
+    sink_4_1367(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1456(               A&);  // { dg-error "" }
+four  sink_4_1456(const volatile A&);  // { dg-error "" }
+five  sink_4_1456(               A&&);  // { dg-error "" }
+six   sink_4_1456(const          A&&);  // { dg-error "" }
+
+int test4_1456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1456(v_source());   // { dg-error "no match" }
+    sink_4_1456(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1457(               A&);  // { dg-error "" }
+four  sink_4_1457(const volatile A&);  // { dg-error "" }
+five  sink_4_1457(               A&&);  // { dg-error "" }
+seven sink_4_1457(volatile       A&&);  // { dg-error "" }
+
+int test4_1457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1457(c_source());   // { dg-error "no match" }
+    sink_4_1457(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1467(               A&);  // { dg-error "" }
+four  sink_4_1467(const volatile A&);  // { dg-error "" }
+six   sink_4_1467(const          A&&);  // { dg-error "" }
+seven sink_4_1467(volatile       A&&);  // { dg-error "" }
+
+int test4_1467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1467(source());     // { dg-error "ambiguous" }
+    sink_4_1467(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1567(               A&);  // { dg-error "" }
+five  sink_4_1567(               A&&);  // { dg-error "" }
+six   sink_4_1567(const          A&&);  // { dg-error "" }
+seven sink_4_1567(volatile       A&&);  // { dg-error "" }
+
+int test4_1567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1567(cva);          // { dg-error "no match" }
+    sink_4_1567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_4_1678(               A&);
+six   sink_4_1678(const          A&&);  // { dg-error "" }
+seven sink_4_1678(volatile       A&&);  // { dg-error "" }
+eight sink_4_1678(const volatile A&&);  // { dg-error "" }
+
+int test4_1678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_1678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_4_2345(const          A&);  // { dg-error "" }
+three sink_4_2345(volatile       A&);  // { dg-error "" }
+four  sink_4_2345(const volatile A&);  // { dg-error "" }
+five  sink_4_2345(               A&&);  // { dg-error "" }
+
+int test4_2345()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2345(a);            // { dg-error "ambiguous" }
+    sink_4_2345(v_source());   // { dg-error "no match" }
+    sink_4_2345(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2346(const          A&);  // { dg-error "" }
+three sink_4_2346(volatile       A&);  // { dg-error "" }
+four  sink_4_2346(const volatile A&);  // { dg-error "" }
+six   sink_4_2346(const          A&&);  // { dg-error "" }
+
+int test4_2346()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2346(a);            // { dg-error "ambiguous" }
+    sink_4_2346(v_source());   // { dg-error "no match" }
+    sink_4_2346(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2347(const          A&);  // { dg-error "" }
+three sink_4_2347(volatile       A&);  // { dg-error "" }
+four  sink_4_2347(const volatile A&);  // { dg-error "" }
+seven sink_4_2347(volatile       A&&);  // { dg-error "" }
+
+int test4_2347()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2347(a);            // { dg-error "ambiguous" }
+    sink_4_2347(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2348(const          A&);  // { dg-error "" }
+three sink_4_2348(volatile       A&);  // { dg-error "" }
+four  sink_4_2348(const volatile A&);  // { dg-error "" }
+eight sink_4_2348(const volatile A&&);  // { dg-error "" }
+
+int test4_2348()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2348(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_4_2356(const          A&);  // { dg-error "" }
+three sink_4_2356(volatile       A&);  // { dg-error "" }
+five  sink_4_2356(               A&&);  // { dg-error "" }
+six   sink_4_2356(const          A&&);  // { dg-error "" }
+
+int test4_2356()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2356(a);            // { dg-error "ambiguous" }
+    sink_4_2356(cva);          // { dg-error "no match" }
+    sink_4_2356(v_source());   // { dg-error "no match" }
+    sink_4_2356(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2357(const          A&);  // { dg-error "" }
+three sink_4_2357(volatile       A&);  // { dg-error "" }
+five  sink_4_2357(               A&&);  // { dg-error "" }
+seven sink_4_2357(volatile       A&&);  // { dg-error "" }
+
+int test4_2357()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2357(a);            // { dg-error "ambiguous" }
+    sink_4_2357(cva);          // { dg-error "no match" }
+    sink_4_2357(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2358(const          A&);  // { dg-error "" }
+three sink_4_2358(volatile       A&);  // { dg-error "" }
+five  sink_4_2358(               A&&);  // { dg-error "" }
+eight sink_4_2358(const volatile A&&);  // { dg-error "" }
+
+int test4_2358()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2358(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_4_2367(const          A&);  // { dg-error "" }
+three sink_4_2367(volatile       A&);  // { dg-error "" }
+six   sink_4_2367(const          A&&);  // { dg-error "" }
+seven sink_4_2367(volatile       A&&);  // { dg-error "" }
+
+int test4_2367()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2367(a);            // { dg-error "ambiguous" }
+    sink_4_2367(cva);          // { dg-error "no match" }
+    sink_4_2367(source());     // { dg-error "ambiguous" }
+    sink_4_2367(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2368(const          A&);  // { dg-error "" }
+three sink_4_2368(volatile       A&);  // { dg-error "" }
+six   sink_4_2368(const          A&&);  // { dg-error "" }
+eight sink_4_2368(const volatile A&&);  // { dg-error "" }
+
+int test4_2368()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2368(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_4_2378(const          A&);  // { dg-error "" }
+three sink_4_2378(volatile       A&);  // { dg-error "" }
+seven sink_4_2378(volatile       A&&);  // { dg-error "" }
+eight sink_4_2378(const volatile A&&);  // { dg-error "" }
+
+int test4_2378()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2378(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_4_2456(const          A&);  // { dg-error "" }
+four  sink_4_2456(const volatile A&);  // { dg-error "" }
+five  sink_4_2456(               A&&);  // { dg-error "" }
+six   sink_4_2456(const          A&&);  // { dg-error "" }
+
+int test4_2456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2456(v_source());   // { dg-error "no match" }
+    sink_4_2456(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2457(const          A&);  // { dg-error "" }
+four  sink_4_2457(const volatile A&);  // { dg-error "" }
+five  sink_4_2457(               A&&);  // { dg-error "" }
+seven sink_4_2457(volatile       A&&);  // { dg-error "" }
+
+int test4_2457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2457(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2467(const          A&);  // { dg-error "" }
+four  sink_4_2467(const volatile A&);  // { dg-error "" }
+six   sink_4_2467(const          A&&);  // { dg-error "" }
+seven sink_4_2467(volatile       A&&);  // { dg-error "" }
+
+int test4_2467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2467(source());     // { dg-error "ambiguous" }
+    sink_4_2467(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2567(const          A&);  // { dg-error "" }
+five  sink_4_2567(               A&&);  // { dg-error "" }
+six   sink_4_2567(const          A&&);  // { dg-error "" }
+seven sink_4_2567(volatile       A&&);  // { dg-error "" }
+
+int test4_2567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2567(cva);          // { dg-error "no match" }
+    sink_4_2567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_4_2678(const          A&);  // { dg-error "" }
+six   sink_4_2678(const          A&&);  // { dg-error "" }
+seven sink_4_2678(volatile       A&&);  // { dg-error "" }
+eight sink_4_2678(const volatile A&&);  // { dg-error "" }
+
+int test4_2678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_2678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+three sink_4_3456(volatile       A&);  // { dg-error "" }
+four  sink_4_3456(const volatile A&);  // { dg-error "" }
+five  sink_4_3456(               A&&);  // { dg-error "" }
+six   sink_4_3456(const          A&&);  // { dg-error "" }
+
+int test4_3456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_3456(v_source());   // { dg-error "no match" }
+    sink_4_3456(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_4_3457(volatile       A&);  // { dg-error "" }
+four  sink_4_3457(const volatile A&);  // { dg-error "" }
+five  sink_4_3457(               A&&);  // { dg-error "" }
+seven sink_4_3457(volatile       A&&);  // { dg-error "" }
+
+int test4_3457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_3457(c_source());   // { dg-error "no match" }
+    sink_4_3457(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_4_3467(volatile       A&);  // { dg-error "" }
+four  sink_4_3467(const volatile A&);  // { dg-error "" }
+six   sink_4_3467(const          A&&);  // { dg-error "" }
+seven sink_4_3467(volatile       A&&);  // { dg-error "" }
+
+int test4_3467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_3467(source());     // { dg-error "ambiguous" }
+    sink_4_3467(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_4_3567(volatile       A&);  // { dg-error "" }
+five  sink_4_3567(               A&&);  // { dg-error "" }
+six   sink_4_3567(const          A&&);  // { dg-error "" }
+seven sink_4_3567(volatile       A&&);  // { dg-error "" }
+
+int test4_3567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_3567(cva);          // { dg-error "no match" }
+    sink_4_3567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_4_3678(volatile       A&);
+six   sink_4_3678(const          A&&);  // { dg-error "" }
+seven sink_4_3678(volatile       A&&);  // { dg-error "" }
+eight sink_4_3678(const volatile A&&);  // { dg-error "" }
+
+int test4_3678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_3678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+four  sink_4_4567(const volatile A&);  // { dg-error "" }
+five  sink_4_4567(               A&&);  // { dg-error "" }
+six   sink_4_4567(const          A&&);  // { dg-error "" }
+seven sink_4_4567(volatile       A&&);  // { dg-error "" }
+
+int test4_4567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_4567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+four  sink_4_4678(const volatile A&);
+six   sink_4_4678(const          A&&);  // { dg-error "" }
+seven sink_4_4678(volatile       A&&);  // { dg-error "" }
+eight sink_4_4678(const volatile A&&);  // { dg-error "" }
+
+int test4_4678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_4_4678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+int main()
+{
+    return test4_1235() + test4_1236() + test4_1237() + test4_1256() + test4_1257() +
+           test4_1267() + test4_1356() + test4_1357() + test4_1467() + test4_1567() +
+           test4_1678() + test4_2345() + test4_2346() + test4_2347() + test4_2348() +
+           test4_2356() + test4_2357() + test4_2358() + test4_2367() + test4_2368() +
+           test4_2378() + test4_2467() + test4_2567() + test4_2678() + test4_3467() +
+           test4_3567() + test4_3678() + test4_4678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv4p.C b/gcc/testsuite/g++.dg/cpp0x/rv4p.C
new file mode 100644
index 000000000000..a486e75e2e30
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv4p.C
@@ -0,0 +1,1497 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 4 at a time
+
+one   sink_4_1234(               A&);
+two   sink_4_1234(const          A&);
+three sink_4_1234(volatile       A&);
+four  sink_4_1234(const volatile A&);
+
+int test4_1234()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1234(a))           == 1> t1;
+    sa<sizeof(sink_4_1234(ca))          == 2> t2;
+    sa<sizeof(sink_4_1234(va))          == 3> t3;
+    sa<sizeof(sink_4_1234(cva))         == 4> t4;
+    sa<sizeof(sink_4_1234(source()))    == 2> t5;
+    sa<sizeof(sink_4_1234(c_source()))  == 2> t6;
+    return 0;
+}
+
+one   sink_4_1235(               A&);
+two   sink_4_1235(const          A&);
+three sink_4_1235(volatile       A&);
+five  sink_4_1235(               A&&);
+
+int test4_1235()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1235(a))           == 1> t1;
+    sa<sizeof(sink_4_1235(ca))          == 2> t2;
+    sa<sizeof(sink_4_1235(va))          == 3> t3;
+    sa<sizeof(sink_4_1235(source()))    == 5> t5;
+    sa<sizeof(sink_4_1235(c_source()))  == 2> t6;
+    return 0;
+}
+
+one   sink_4_1236(               A&);
+two   sink_4_1236(const          A&);
+three sink_4_1236(volatile       A&);
+six   sink_4_1236(const          A&&);
+
+int test4_1236()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1236(a))           == 1> t1;
+    sa<sizeof(sink_4_1236(ca))          == 2> t2;
+    sa<sizeof(sink_4_1236(va))          == 3> t3;
+    sa<sizeof(sink_4_1236(source()))    == 6> t5;
+    sa<sizeof(sink_4_1236(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_4_1237(               A&);
+two   sink_4_1237(const          A&);
+three sink_4_1237(volatile       A&);
+seven sink_4_1237(volatile       A&&);
+
+int test4_1237()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1237(a))           == 1> t1;
+    sa<sizeof(sink_4_1237(ca))          == 2> t2;
+    sa<sizeof(sink_4_1237(va))          == 3> t3;
+    sa<sizeof(sink_4_1237(source()))    == 7> t5;
+    sa<sizeof(sink_4_1237(c_source()))  == 2> t6;
+    sa<sizeof(sink_4_1237(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1238(               A&);
+two   sink_4_1238(const          A&);
+three sink_4_1238(volatile       A&);
+eight sink_4_1238(const volatile A&&);
+
+int test4_1238()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1238(a))           == 1> t1;
+    sa<sizeof(sink_4_1238(ca))          == 2> t2;
+    sa<sizeof(sink_4_1238(va))          == 3> t3;
+    sa<sizeof(sink_4_1238(cva))         == 8> t4;
+    sa<sizeof(sink_4_1238(source()))    == 8> t5;
+    sa<sizeof(sink_4_1238(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1238(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1238(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1245(               A&);
+two   sink_4_1245(const          A&);
+four  sink_4_1245(const volatile A&);
+five  sink_4_1245(               A&&);
+
+int test4_1245()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1245(a))           == 1> t1;
+    sa<sizeof(sink_4_1245(ca))          == 2> t2;
+    sa<sizeof(sink_4_1245(va))          == 4> t3;
+    sa<sizeof(sink_4_1245(cva))         == 4> t4;
+    sa<sizeof(sink_4_1245(source()))    == 5> t5;
+    sa<sizeof(sink_4_1245(c_source()))  == 2> t6;
+    return 0;
+}
+
+one   sink_4_1246(               A&);
+two   sink_4_1246(const          A&);
+four  sink_4_1246(const volatile A&);
+six   sink_4_1246(const          A&&);
+
+int test4_1246()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1246(a))           == 1> t1;
+    sa<sizeof(sink_4_1246(ca))          == 2> t2;
+    sa<sizeof(sink_4_1246(va))          == 4> t3;
+    sa<sizeof(sink_4_1246(cva))         == 4> t4;
+    sa<sizeof(sink_4_1246(source()))    == 6> t5;
+    sa<sizeof(sink_4_1246(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_4_1247(               A&);
+two   sink_4_1247(const          A&);
+four  sink_4_1247(const volatile A&);
+seven sink_4_1247(volatile       A&&);
+
+int test4_1247()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1247(a))           == 1> t1;
+    sa<sizeof(sink_4_1247(ca))          == 2> t2;
+    sa<sizeof(sink_4_1247(va))          == 4> t3;
+    sa<sizeof(sink_4_1247(cva))         == 4> t4;
+    sa<sizeof(sink_4_1247(source()))    == 7> t5;
+    sa<sizeof(sink_4_1247(c_source()))  == 2> t6;
+    sa<sizeof(sink_4_1247(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1248(               A&);
+two   sink_4_1248(const          A&);
+four  sink_4_1248(const volatile A&);
+eight sink_4_1248(const volatile A&&);
+
+int test4_1248()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1248(a))           == 1> t1;
+    sa<sizeof(sink_4_1248(ca))          == 2> t2;
+    sa<sizeof(sink_4_1248(va))          == 4> t3;
+    sa<sizeof(sink_4_1248(cva))         == 4> t4;
+    sa<sizeof(sink_4_1248(source()))    == 8> t5;
+    sa<sizeof(sink_4_1248(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1248(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1248(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1256(               A&);
+two   sink_4_1256(const          A&);
+five  sink_4_1256(               A&&);
+six   sink_4_1256(const          A&&);
+
+int test4_1256()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1256(a))           == 1> t1;
+    sa<sizeof(sink_4_1256(ca))          == 2> t2;
+    sa<sizeof(sink_4_1256(source()))    == 5> t5;
+    sa<sizeof(sink_4_1256(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_4_1257(               A&);
+two   sink_4_1257(const          A&);
+five  sink_4_1257(               A&&);
+seven sink_4_1257(volatile       A&&);
+
+int test4_1257()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1257(a))           == 1> t1;
+    sa<sizeof(sink_4_1257(ca))          == 2> t2;
+    sa<sizeof(sink_4_1257(va))          == 7> t3;
+    sa<sizeof(sink_4_1257(source()))    == 5> t5;
+    sa<sizeof(sink_4_1257(c_source()))  == 2> t6;
+    sa<sizeof(sink_4_1257(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1258(               A&);
+two   sink_4_1258(const          A&);
+five  sink_4_1258(               A&&);
+eight sink_4_1258(const volatile A&&);
+
+int test4_1258()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1258(a))           == 1> t1;
+    sa<sizeof(sink_4_1258(ca))          == 2> t2;
+    sa<sizeof(sink_4_1258(va))          == 8> t3;
+    sa<sizeof(sink_4_1258(cva))         == 8> t4;
+    sa<sizeof(sink_4_1258(source()))    == 5> t5;
+    sa<sizeof(sink_4_1258(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1258(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1258(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1267(               A&);
+two   sink_4_1267(const          A&);
+six   sink_4_1267(const          A&&);
+seven sink_4_1267(volatile       A&&);
+
+int test4_1267()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1267(a))           == 1> t1;
+    sa<sizeof(sink_4_1267(ca))          == 2> t2;
+    sa<sizeof(sink_4_1267(va))          == 7> t3;
+    sa<sizeof(sink_4_1267(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_1267(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1268(               A&);
+two   sink_4_1268(const          A&);
+six   sink_4_1268(const          A&&);
+eight sink_4_1268(const volatile A&&);
+
+int test4_1268()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1268(a))           == 1> t1;
+    sa<sizeof(sink_4_1268(ca))          == 2> t2;
+    sa<sizeof(sink_4_1268(va))          == 8> t3;
+    sa<sizeof(sink_4_1268(cva))         == 8> t4;
+    sa<sizeof(sink_4_1268(source()))    == 6> t5;
+    sa<sizeof(sink_4_1268(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_1268(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1268(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1278(               A&);
+two   sink_4_1278(const          A&);
+seven sink_4_1278(volatile       A&&);
+eight sink_4_1278(const volatile A&&);
+
+int test4_1278()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1278(a))           == 1> t1;
+    sa<sizeof(sink_4_1278(ca))          == 2> t2;
+    sa<sizeof(sink_4_1278(va))          == 7> t3;
+    sa<sizeof(sink_4_1278(cva))         == 8> t4;
+    sa<sizeof(sink_4_1278(source()))    == 7> t5;
+    sa<sizeof(sink_4_1278(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1278(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_1278(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1345(               A&);
+three sink_4_1345(volatile       A&);
+four  sink_4_1345(const volatile A&);
+five  sink_4_1345(               A&&);
+
+int test4_1345()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1345(a))           == 1> t1;
+    sa<sizeof(sink_4_1345(ca))          == 4> t2;
+    sa<sizeof(sink_4_1345(va))          == 3> t3;
+    sa<sizeof(sink_4_1345(cva))         == 4> t4;
+    sa<sizeof(sink_4_1345(source()))    == 5> t5;
+    return 0;
+}
+
+one   sink_4_1346(               A&);
+three sink_4_1346(volatile       A&);
+four  sink_4_1346(const volatile A&);
+six   sink_4_1346(const          A&&);
+
+int test4_1346()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1346(a))           == 1> t1;
+    sa<sizeof(sink_4_1346(ca))          == 4> t2;
+    sa<sizeof(sink_4_1346(va))          == 3> t3;
+    sa<sizeof(sink_4_1346(cva))         == 4> t4;
+    sa<sizeof(sink_4_1346(source()))    == 6> t5;
+    sa<sizeof(sink_4_1346(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_4_1347(               A&);
+three sink_4_1347(volatile       A&);
+four  sink_4_1347(const volatile A&);
+seven sink_4_1347(volatile       A&&);
+
+int test4_1347()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1347(a))           == 1> t1;
+    sa<sizeof(sink_4_1347(ca))          == 4> t2;
+    sa<sizeof(sink_4_1347(va))          == 3> t3;
+    sa<sizeof(sink_4_1347(cva))         == 4> t4;
+    sa<sizeof(sink_4_1347(source()))    == 7> t5;
+    sa<sizeof(sink_4_1347(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1348(               A&);
+three sink_4_1348(volatile       A&);
+four  sink_4_1348(const volatile A&);
+eight sink_4_1348(const volatile A&&);
+
+int test4_1348()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1348(a))           == 1> t1;
+    sa<sizeof(sink_4_1348(ca))          == 4> t2;
+    sa<sizeof(sink_4_1348(va))          == 3> t3;
+    sa<sizeof(sink_4_1348(cva))         == 4> t4;
+    sa<sizeof(sink_4_1348(source()))    == 8> t5;
+    sa<sizeof(sink_4_1348(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1348(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1348(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1356(               A&);
+three sink_4_1356(volatile       A&);
+five  sink_4_1356(               A&&);
+six   sink_4_1356(const          A&&);
+
+int test4_1356()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1356(a))           == 1> t1;
+    sa<sizeof(sink_4_1356(ca))          == 6> t2;
+    sa<sizeof(sink_4_1356(va))          == 3> t3;
+    sa<sizeof(sink_4_1356(source()))    == 5> t5;
+    sa<sizeof(sink_4_1356(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_4_1357(               A&);
+three sink_4_1357(volatile       A&);
+five  sink_4_1357(               A&&);
+seven sink_4_1357(volatile       A&&);
+
+int test4_1357()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1357(a))           == 1> t1;
+    sa<sizeof(sink_4_1357(va))          == 3> t3;
+    sa<sizeof(sink_4_1357(source()))    == 5> t5;
+    sa<sizeof(sink_4_1357(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1358(               A&);
+three sink_4_1358(volatile       A&);
+five  sink_4_1358(               A&&);
+eight sink_4_1358(const volatile A&&);
+
+int test4_1358()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1358(a))           == 1> t1;
+    sa<sizeof(sink_4_1358(ca))          == 8> t2;
+    sa<sizeof(sink_4_1358(va))          == 3> t3;
+    sa<sizeof(sink_4_1358(cva))         == 8> t4;
+    sa<sizeof(sink_4_1358(source()))    == 5> t5;
+    sa<sizeof(sink_4_1358(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1358(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1358(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1367(               A&);
+three sink_4_1367(volatile       A&);
+six   sink_4_1367(const          A&&);
+seven sink_4_1367(volatile       A&&);
+
+int test4_1367()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1367(a))           == 1> t1;
+    sa<sizeof(sink_4_1367(ca))          == 6> t2;
+    sa<sizeof(sink_4_1367(va))          == 3> t3;
+    sa<sizeof(sink_4_1367(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_1367(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1368(               A&);
+three sink_4_1368(volatile       A&);
+six   sink_4_1368(const          A&&);
+eight sink_4_1368(const volatile A&&);
+
+int test4_1368()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1368(a))           == 1> t1;
+    sa<sizeof(sink_4_1368(ca))          == 6> t2;
+    sa<sizeof(sink_4_1368(va))          == 3> t3;
+    sa<sizeof(sink_4_1368(cva))         == 8> t4;
+    sa<sizeof(sink_4_1368(source()))    == 6> t5;
+    sa<sizeof(sink_4_1368(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_1368(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1368(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1378(               A&);
+three sink_4_1378(volatile       A&);
+seven sink_4_1378(volatile       A&&);
+eight sink_4_1378(const volatile A&&);
+
+int test4_1378()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1378(a))           == 1> t1;
+    sa<sizeof(sink_4_1378(ca))          == 8> t2;
+    sa<sizeof(sink_4_1378(va))          == 3> t3;
+    sa<sizeof(sink_4_1378(cva))         == 8> t4;
+    sa<sizeof(sink_4_1378(source()))    == 7> t5;
+    sa<sizeof(sink_4_1378(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1378(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_1378(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1456(               A&);
+four  sink_4_1456(const volatile A&);
+five  sink_4_1456(               A&&);
+six   sink_4_1456(const          A&&);
+
+int test4_1456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1456(a))           == 1> t1;
+    sa<sizeof(sink_4_1456(ca))          == 4> t2;
+    sa<sizeof(sink_4_1456(va))          == 4> t3;
+    sa<sizeof(sink_4_1456(cva))         == 4> t4;
+    sa<sizeof(sink_4_1456(source()))    == 5> t5;
+    sa<sizeof(sink_4_1456(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_4_1457(               A&);
+four  sink_4_1457(const volatile A&);
+five  sink_4_1457(               A&&);
+seven sink_4_1457(volatile       A&&);
+
+int test4_1457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1457(a))           == 1> t1;
+    sa<sizeof(sink_4_1457(ca))          == 4> t2;
+    sa<sizeof(sink_4_1457(va))          == 4> t3;
+    sa<sizeof(sink_4_1457(cva))         == 4> t4;
+    sa<sizeof(sink_4_1457(source()))    == 5> t5;
+    sa<sizeof(sink_4_1457(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1458(               A&);
+four  sink_4_1458(const volatile A&);
+five  sink_4_1458(               A&&);
+eight sink_4_1458(const volatile A&&);
+
+int test4_1458()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1458(a))           == 1> t1;
+    sa<sizeof(sink_4_1458(ca))          == 4> t2;
+    sa<sizeof(sink_4_1458(va))          == 4> t3;
+    sa<sizeof(sink_4_1458(cva))         == 4> t4;
+    sa<sizeof(sink_4_1458(source()))    == 5> t5;
+    sa<sizeof(sink_4_1458(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1458(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1458(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1467(               A&);
+four  sink_4_1467(const volatile A&);
+six   sink_4_1467(const          A&&);
+seven sink_4_1467(volatile       A&&);
+
+int test4_1467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1467(a))           == 1> t1;
+    sa<sizeof(sink_4_1467(ca))          == 4> t2;
+    sa<sizeof(sink_4_1467(va))          == 4> t3;
+    sa<sizeof(sink_4_1467(cva))         == 4> t4;
+    sa<sizeof(sink_4_1467(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_1467(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1468(               A&);
+four  sink_4_1468(const volatile A&);
+six   sink_4_1468(const          A&&);
+eight sink_4_1468(const volatile A&&);
+
+int test4_1468()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1468(a))           == 1> t1;
+    sa<sizeof(sink_4_1468(ca))          == 4> t2;
+    sa<sizeof(sink_4_1468(va))          == 4> t3;
+    sa<sizeof(sink_4_1468(cva))         == 4> t4;
+    sa<sizeof(sink_4_1468(source()))    == 6> t5;
+    sa<sizeof(sink_4_1468(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_1468(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1468(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1478(               A&);
+four  sink_4_1478(const volatile A&);
+seven sink_4_1478(volatile       A&&);
+eight sink_4_1478(const volatile A&&);
+
+int test4_1478()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1478(a))           == 1> t1;
+    sa<sizeof(sink_4_1478(ca))          == 4> t2;
+    sa<sizeof(sink_4_1478(va))          == 4> t3;
+    sa<sizeof(sink_4_1478(cva))         == 4> t4;
+    sa<sizeof(sink_4_1478(source()))    == 7> t5;
+    sa<sizeof(sink_4_1478(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1478(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_1478(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1567(               A&);
+five  sink_4_1567(               A&&);
+six   sink_4_1567(const          A&&);
+seven sink_4_1567(volatile       A&&);
+
+int test4_1567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1567(a))           == 1> t1;
+    sa<sizeof(sink_4_1567(ca))          == 6> t2;
+    sa<sizeof(sink_4_1567(va))          == 7> t3;
+    sa<sizeof(sink_4_1567(source()))    == 5> t5;
+    sa<sizeof(sink_4_1567(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_1567(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_4_1568(               A&);
+five  sink_4_1568(               A&&);
+six   sink_4_1568(const          A&&);
+eight sink_4_1568(const volatile A&&);
+
+int test4_1568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1568(a))           == 1> t1;
+    sa<sizeof(sink_4_1568(ca))          == 6> t2;
+    sa<sizeof(sink_4_1568(va))          == 8> t3;
+    sa<sizeof(sink_4_1568(cva))         == 8> t4;
+    sa<sizeof(sink_4_1568(source()))    == 5> t5;
+    sa<sizeof(sink_4_1568(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_1568(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_1568(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1578(               A&);
+five  sink_4_1578(               A&&);
+seven sink_4_1578(volatile       A&&);
+eight sink_4_1578(const volatile A&&);
+
+int test4_1578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1578(a))           == 1> t1;
+    sa<sizeof(sink_4_1578(ca))          == 8> t2;
+    sa<sizeof(sink_4_1578(va))          == 7> t3;
+    sa<sizeof(sink_4_1578(cva))         == 8> t4;
+    sa<sizeof(sink_4_1578(source()))    == 5> t5;
+    sa<sizeof(sink_4_1578(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_1578(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_1578(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_4_1678(               A&);
+six   sink_4_1678(const          A&&);
+seven sink_4_1678(volatile       A&&);
+eight sink_4_1678(const volatile A&&);
+
+int test4_1678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_1678(a))           == 1> t1;
+    sa<sizeof(sink_4_1678(ca))          == 6> t2;
+    sa<sizeof(sink_4_1678(va))          == 7> t3;
+    sa<sizeof(sink_4_1678(cva))         == 8> t4;
+    sa<sizeof(sink_4_1678(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_1678(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_1678(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2345(const          A&);
+three sink_4_2345(volatile       A&);
+four  sink_4_2345(const volatile A&);
+five  sink_4_2345(               A&&);
+
+int test4_2345()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2345(ca))          == 2> t2;
+    sa<sizeof(sink_4_2345(va))          == 3> t3;
+    sa<sizeof(sink_4_2345(cva))         == 4> t4;
+    sa<sizeof(sink_4_2345(source()))    == 5> t5;
+    sa<sizeof(sink_4_2345(c_source()))  == 2> t6;
+    return 0;
+}
+
+two   sink_4_2346(const          A&);
+three sink_4_2346(volatile       A&);
+four  sink_4_2346(const volatile A&);
+six   sink_4_2346(const          A&&);
+
+int test4_2346()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2346(ca))          == 2> t2;
+    sa<sizeof(sink_4_2346(va))          == 3> t3;
+    sa<sizeof(sink_4_2346(cva))         == 4> t4;
+    sa<sizeof(sink_4_2346(source()))    == 6> t5;
+    sa<sizeof(sink_4_2346(c_source()))  == 6> t6;
+    return 0;
+}
+
+two   sink_4_2347(const          A&);
+three sink_4_2347(volatile       A&);
+four  sink_4_2347(const volatile A&);
+seven sink_4_2347(volatile       A&&);
+
+int test4_2347()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2347(ca))          == 2> t2;
+    sa<sizeof(sink_4_2347(va))          == 3> t3;
+    sa<sizeof(sink_4_2347(cva))         == 4> t4;
+    sa<sizeof(sink_4_2347(source()))    == 7> t5;
+    sa<sizeof(sink_4_2347(c_source()))  == 2> t6;
+    sa<sizeof(sink_4_2347(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_4_2348(const          A&);
+three sink_4_2348(volatile       A&);
+four  sink_4_2348(const volatile A&);
+eight sink_4_2348(const volatile A&&);
+
+int test4_2348()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2348(ca))          == 2> t2;
+    sa<sizeof(sink_4_2348(va))          == 3> t3;
+    sa<sizeof(sink_4_2348(cva))         == 4> t4;
+    sa<sizeof(sink_4_2348(source()))    == 8> t5;
+    sa<sizeof(sink_4_2348(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_2348(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_2348(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2356(const          A&);
+three sink_4_2356(volatile       A&);
+five  sink_4_2356(               A&&);
+six   sink_4_2356(const          A&&);
+
+int test4_2356()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2356(ca))          == 2> t2;
+    sa<sizeof(sink_4_2356(va))          == 3> t3;
+    sa<sizeof(sink_4_2356(source()))    == 5> t5;
+    sa<sizeof(sink_4_2356(c_source()))  == 6> t6;
+    return 0;
+}
+
+two   sink_4_2357(const          A&);
+three sink_4_2357(volatile       A&);
+five  sink_4_2357(               A&&);
+seven sink_4_2357(volatile       A&&);
+
+int test4_2357()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2357(ca))          == 2> t2;
+    sa<sizeof(sink_4_2357(va))          == 3> t3;
+    sa<sizeof(sink_4_2357(source()))    == 5> t5;
+    sa<sizeof(sink_4_2357(c_source()))  == 2> t6;
+    sa<sizeof(sink_4_2357(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_4_2358(const          A&);
+three sink_4_2358(volatile       A&);
+five  sink_4_2358(               A&&);
+eight sink_4_2358(const volatile A&&);
+
+int test4_2358()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2358(ca))          == 2> t2;
+    sa<sizeof(sink_4_2358(va))          == 3> t3;
+    sa<sizeof(sink_4_2358(cva))         == 8> t4;
+    sa<sizeof(sink_4_2358(source()))    == 5> t5;
+    sa<sizeof(sink_4_2358(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_2358(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_2358(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2367(const          A&);
+three sink_4_2367(volatile       A&);
+six   sink_4_2367(const          A&&);
+seven sink_4_2367(volatile       A&&);
+
+int test4_2367()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2367(ca))          == 2> t2;
+    sa<sizeof(sink_4_2367(va))          == 3> t3;
+    sa<sizeof(sink_4_2367(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_2367(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_4_2368(const          A&);
+three sink_4_2368(volatile       A&);
+six   sink_4_2368(const          A&&);
+eight sink_4_2368(const volatile A&&);
+
+int test4_2368()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2368(ca))          == 2> t2;
+    sa<sizeof(sink_4_2368(va))          == 3> t3;
+    sa<sizeof(sink_4_2368(cva))         == 8> t4;
+    sa<sizeof(sink_4_2368(source()))    == 6> t5;
+    sa<sizeof(sink_4_2368(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_2368(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_2368(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2378(const          A&);
+three sink_4_2378(volatile       A&);
+seven sink_4_2378(volatile       A&&);
+eight sink_4_2378(const volatile A&&);
+
+int test4_2378()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2378(ca))          == 2> t2;
+    sa<sizeof(sink_4_2378(va))          == 3> t3;
+    sa<sizeof(sink_4_2378(cva))         == 8> t4;
+    sa<sizeof(sink_4_2378(source()))    == 7> t5;
+    sa<sizeof(sink_4_2378(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_2378(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_2378(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2456(const          A&);
+four  sink_4_2456(const volatile A&);
+five  sink_4_2456(               A&&);
+six   sink_4_2456(const          A&&);
+
+int test4_2456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2456(a))           == 2> t1;
+    sa<sizeof(sink_4_2456(ca))          == 2> t2;
+    sa<sizeof(sink_4_2456(va))          == 4> t3;
+    sa<sizeof(sink_4_2456(cva))         == 4> t4;
+    sa<sizeof(sink_4_2456(source()))    == 5> t5;
+    sa<sizeof(sink_4_2456(c_source()))  == 6> t6;
+    return 0;
+}
+
+two   sink_4_2457(const          A&);
+four  sink_4_2457(const volatile A&);
+five  sink_4_2457(               A&&);
+seven sink_4_2457(volatile       A&&);
+
+int test4_2457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2457(a))           == 2> t1;
+    sa<sizeof(sink_4_2457(ca))          == 2> t2;
+    sa<sizeof(sink_4_2457(va))          == 4> t3;
+    sa<sizeof(sink_4_2457(cva))         == 4> t4;
+    sa<sizeof(sink_4_2457(source()))    == 5> t5;
+    sa<sizeof(sink_4_2457(c_source()))  == 2> t6;
+    sa<sizeof(sink_4_2457(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_4_2458(const          A&);
+four  sink_4_2458(const volatile A&);
+five  sink_4_2458(               A&&);
+eight sink_4_2458(const volatile A&&);
+
+int test4_2458()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2458(a))           == 2> t1;
+    sa<sizeof(sink_4_2458(ca))          == 2> t2;
+    sa<sizeof(sink_4_2458(va))          == 4> t3;
+    sa<sizeof(sink_4_2458(cva))         == 4> t4;
+    sa<sizeof(sink_4_2458(source()))    == 5> t5;
+    sa<sizeof(sink_4_2458(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_2458(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_2458(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2467(const          A&);
+four  sink_4_2467(const volatile A&);
+six   sink_4_2467(const          A&&);
+seven sink_4_2467(volatile       A&&);
+
+int test4_2467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2467(a))           == 2> t1;
+    sa<sizeof(sink_4_2467(ca))          == 2> t2;
+    sa<sizeof(sink_4_2467(va))          == 4> t3;
+    sa<sizeof(sink_4_2467(cva))         == 4> t4;
+    sa<sizeof(sink_4_2467(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_2467(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_4_2468(const          A&);
+four  sink_4_2468(const volatile A&);
+six   sink_4_2468(const          A&&);
+eight sink_4_2468(const volatile A&&);
+
+int test4_2468()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2468(a))           == 2> t1;
+    sa<sizeof(sink_4_2468(ca))          == 2> t2;
+    sa<sizeof(sink_4_2468(va))          == 4> t3;
+    sa<sizeof(sink_4_2468(cva))         == 4> t4;
+    sa<sizeof(sink_4_2468(source()))    == 6> t5;
+    sa<sizeof(sink_4_2468(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_2468(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_2468(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2478(const          A&);
+four  sink_4_2478(const volatile A&);
+seven sink_4_2478(volatile       A&&);
+eight sink_4_2478(const volatile A&&);
+
+int test4_2478()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2478(a))           == 2> t1;
+    sa<sizeof(sink_4_2478(ca))          == 2> t2;
+    sa<sizeof(sink_4_2478(va))          == 4> t3;
+    sa<sizeof(sink_4_2478(cva))         == 4> t4;
+    sa<sizeof(sink_4_2478(source()))    == 7> t5;
+    sa<sizeof(sink_4_2478(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_2478(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_2478(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2567(const          A&);
+five  sink_4_2567(               A&&);
+six   sink_4_2567(const          A&&);
+seven sink_4_2567(volatile       A&&);
+
+int test4_2567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2567(a))           == 2> t1;
+    sa<sizeof(sink_4_2567(ca))          == 2> t2;
+    sa<sizeof(sink_4_2567(va))          == 7> t3;
+    sa<sizeof(sink_4_2567(source()))    == 5> t5;
+    sa<sizeof(sink_4_2567(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_2567(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_4_2568(const          A&);
+five  sink_4_2568(               A&&);
+six   sink_4_2568(const          A&&);
+eight sink_4_2568(const volatile A&&);
+
+int test4_2568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2568(a))           == 2> t1;
+    sa<sizeof(sink_4_2568(ca))          == 2> t2;
+    sa<sizeof(sink_4_2568(va))          == 8> t3;
+    sa<sizeof(sink_4_2568(cva))         == 8> t4;
+    sa<sizeof(sink_4_2568(source()))    == 5> t5;
+    sa<sizeof(sink_4_2568(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_2568(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_2568(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2578(const          A&);
+five  sink_4_2578(               A&&);
+seven sink_4_2578(volatile       A&&);
+eight sink_4_2578(const volatile A&&);
+
+int test4_2578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2578(a))           == 2> t1;
+    sa<sizeof(sink_4_2578(ca))          == 2> t2;
+    sa<sizeof(sink_4_2578(va))          == 7> t3;
+    sa<sizeof(sink_4_2578(cva))         == 8> t4;
+    sa<sizeof(sink_4_2578(source()))    == 5> t5;
+    sa<sizeof(sink_4_2578(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_2578(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_2578(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_4_2678(const          A&);
+six   sink_4_2678(const          A&&);
+seven sink_4_2678(volatile       A&&);
+eight sink_4_2678(const volatile A&&);
+
+int test4_2678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_2678(a))           == 2> t1;
+    sa<sizeof(sink_4_2678(ca))          == 2> t2;
+    sa<sizeof(sink_4_2678(va))          == 7> t3;
+    sa<sizeof(sink_4_2678(cva))         == 8> t4;
+    sa<sizeof(sink_4_2678(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_2678(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_2678(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_4_3456(volatile       A&);
+four  sink_4_3456(const volatile A&);
+five  sink_4_3456(               A&&);
+six   sink_4_3456(const          A&&);
+
+int test4_3456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3456(a))           == 3> t1;
+    sa<sizeof(sink_4_3456(ca))          == 4> t2;
+    sa<sizeof(sink_4_3456(va))          == 3> t3;
+    sa<sizeof(sink_4_3456(cva))         == 4> t4;
+    sa<sizeof(sink_4_3456(source()))    == 5> t5;
+    sa<sizeof(sink_4_3456(c_source()))  == 6> t6;
+    return 0;
+}
+
+three sink_4_3457(volatile       A&);
+four  sink_4_3457(const volatile A&);
+five  sink_4_3457(               A&&);
+seven sink_4_3457(volatile       A&&);
+
+int test4_3457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3457(a))           == 3> t1;
+    sa<sizeof(sink_4_3457(ca))          == 4> t2;
+    sa<sizeof(sink_4_3457(va))          == 3> t3;
+    sa<sizeof(sink_4_3457(cva))         == 4> t4;
+    sa<sizeof(sink_4_3457(source()))    == 5> t5;
+    sa<sizeof(sink_4_3457(v_source()))  == 7> t7;
+    return 0;
+}
+
+three sink_4_3458(volatile       A&);
+four  sink_4_3458(const volatile A&);
+five  sink_4_3458(               A&&);
+eight sink_4_3458(const volatile A&&);
+
+int test4_3458()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3458(a))           == 3> t1;
+    sa<sizeof(sink_4_3458(ca))          == 4> t2;
+    sa<sizeof(sink_4_3458(va))          == 3> t3;
+    sa<sizeof(sink_4_3458(cva))         == 4> t4;
+    sa<sizeof(sink_4_3458(source()))    == 5> t5;
+    sa<sizeof(sink_4_3458(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_3458(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_3458(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_4_3467(volatile       A&);
+four  sink_4_3467(const volatile A&);
+six   sink_4_3467(const          A&&);
+seven sink_4_3467(volatile       A&&);
+
+int test4_3467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3467(a))           == 3> t1;
+    sa<sizeof(sink_4_3467(ca))          == 4> t2;
+    sa<sizeof(sink_4_3467(va))          == 3> t3;
+    sa<sizeof(sink_4_3467(cva))         == 4> t4;
+    sa<sizeof(sink_4_3467(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_3467(v_source()))  == 7> t7;
+    return 0;
+}
+
+three sink_4_3468(volatile       A&);
+four  sink_4_3468(const volatile A&);
+six   sink_4_3468(const          A&&);
+eight sink_4_3468(const volatile A&&);
+
+int test4_3468()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3468(a))           == 3> t1;
+    sa<sizeof(sink_4_3468(ca))          == 4> t2;
+    sa<sizeof(sink_4_3468(va))          == 3> t3;
+    sa<sizeof(sink_4_3468(cva))         == 4> t4;
+    sa<sizeof(sink_4_3468(source()))    == 6> t5;
+    sa<sizeof(sink_4_3468(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_3468(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_3468(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_4_3478(volatile       A&);
+four  sink_4_3478(const volatile A&);
+seven sink_4_3478(volatile       A&&);
+eight sink_4_3478(const volatile A&&);
+
+int test4_3478()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3478(a))           == 3> t1;
+    sa<sizeof(sink_4_3478(ca))          == 4> t2;
+    sa<sizeof(sink_4_3478(va))          == 3> t3;
+    sa<sizeof(sink_4_3478(cva))         == 4> t4;
+    sa<sizeof(sink_4_3478(source()))    == 7> t5;
+    sa<sizeof(sink_4_3478(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_3478(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_3478(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_4_3567(volatile       A&);
+five  sink_4_3567(               A&&);
+six   sink_4_3567(const          A&&);
+seven sink_4_3567(volatile       A&&);
+
+int test4_3567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3567(a))           == 3> t1;
+    sa<sizeof(sink_4_3567(ca))          == 6> t2;
+    sa<sizeof(sink_4_3567(va))          == 3> t3;
+    sa<sizeof(sink_4_3567(source()))    == 5> t5;
+    sa<sizeof(sink_4_3567(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_3567(v_source()))  == 7> t7;
+    return 0;
+}
+
+three sink_4_3568(volatile       A&);
+five  sink_4_3568(               A&&);
+six   sink_4_3568(const          A&&);
+eight sink_4_3568(const volatile A&&);
+
+int test4_3568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3568(a))           == 3> t1;
+    sa<sizeof(sink_4_3568(ca))          == 6> t2;
+    sa<sizeof(sink_4_3568(va))          == 3> t3;
+    sa<sizeof(sink_4_3568(cva))         == 8> t4;
+    sa<sizeof(sink_4_3568(source()))    == 5> t5;
+    sa<sizeof(sink_4_3568(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_3568(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_3568(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_4_3578(volatile       A&);
+five  sink_4_3578(               A&&);
+seven sink_4_3578(volatile       A&&);
+eight sink_4_3578(const volatile A&&);
+
+int test4_3578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3578(a))           == 3> t1;
+    sa<sizeof(sink_4_3578(ca))          == 8> t2;
+    sa<sizeof(sink_4_3578(va))          == 3> t3;
+    sa<sizeof(sink_4_3578(cva))         == 8> t4;
+    sa<sizeof(sink_4_3578(source()))    == 5> t5;
+    sa<sizeof(sink_4_3578(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_3578(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_3578(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_4_3678(volatile       A&);
+six   sink_4_3678(const          A&&);
+seven sink_4_3678(volatile       A&&);
+eight sink_4_3678(const volatile A&&);
+
+int test4_3678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_3678(a))           == 3> t1;
+    sa<sizeof(sink_4_3678(ca))          == 6> t2;
+    sa<sizeof(sink_4_3678(va))          == 3> t3;
+    sa<sizeof(sink_4_3678(cva))         == 8> t4;
+    sa<sizeof(sink_4_3678(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_3678(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_3678(cv_source())) == 8> t8;
+    return 0;
+}
+
+four  sink_4_4567(const volatile A&);
+five  sink_4_4567(               A&&);
+six   sink_4_4567(const          A&&);
+seven sink_4_4567(volatile       A&&);
+
+int test4_4567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_4567(a))           == 4> t1;
+    sa<sizeof(sink_4_4567(ca))          == 4> t2;
+    sa<sizeof(sink_4_4567(va))          == 4> t3;
+    sa<sizeof(sink_4_4567(cva))         == 4> t4;
+    sa<sizeof(sink_4_4567(source()))    == 5> t5;
+    sa<sizeof(sink_4_4567(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_4567(v_source()))  == 7> t7;
+    return 0;
+}
+
+four  sink_4_4568(const volatile A&);
+five  sink_4_4568(               A&&);
+six   sink_4_4568(const          A&&);
+eight sink_4_4568(const volatile A&&);
+
+int test4_4568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_4568(a))           == 4> t1;
+    sa<sizeof(sink_4_4568(ca))          == 4> t2;
+    sa<sizeof(sink_4_4568(va))          == 4> t3;
+    sa<sizeof(sink_4_4568(cva))         == 4> t4;
+    sa<sizeof(sink_4_4568(source()))    == 5> t5;
+    sa<sizeof(sink_4_4568(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_4568(v_source()))  == 8> t7;
+    sa<sizeof(sink_4_4568(cv_source())) == 8> t8;
+    return 0;
+}
+
+four  sink_4_4578(const volatile A&);
+five  sink_4_4578(               A&&);
+seven sink_4_4578(volatile       A&&);
+eight sink_4_4578(const volatile A&&);
+
+int test4_4578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_4578(a))           == 4> t1;
+    sa<sizeof(sink_4_4578(ca))          == 4> t2;
+    sa<sizeof(sink_4_4578(va))          == 4> t3;
+    sa<sizeof(sink_4_4578(cva))         == 4> t4;
+    sa<sizeof(sink_4_4578(source()))    == 5> t5;
+    sa<sizeof(sink_4_4578(c_source()))  == 8> t6;
+    sa<sizeof(sink_4_4578(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_4578(cv_source())) == 8> t8;
+    return 0;
+}
+
+four  sink_4_4678(const volatile A&);
+six   sink_4_4678(const          A&&);
+seven sink_4_4678(volatile       A&&);
+eight sink_4_4678(const volatile A&&);
+
+int test4_4678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_4678(a))           == 4> t1;
+    sa<sizeof(sink_4_4678(ca))          == 4> t2;
+    sa<sizeof(sink_4_4678(va))          == 4> t3;
+    sa<sizeof(sink_4_4678(cva))         == 4> t4;
+    sa<sizeof(sink_4_4678(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_4678(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_4678(cv_source())) == 8> t8;
+    return 0;
+}
+
+five  sink_4_5678(               A&&);
+six   sink_4_5678(const          A&&);
+seven sink_4_5678(volatile       A&&);
+eight sink_4_5678(const volatile A&&);
+
+int test4_5678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_4_5678(a))           == 5> t1;
+    sa<sizeof(sink_4_5678(ca))          == 6> t2;
+    sa<sizeof(sink_4_5678(va))          == 7> t3;
+    sa<sizeof(sink_4_5678(cva))         == 8> t4;
+    sa<sizeof(sink_4_5678(source()))    == 5> t5;
+    sa<sizeof(sink_4_5678(c_source()))  == 6> t6;
+    sa<sizeof(sink_4_5678(v_source()))  == 7> t7;
+    sa<sizeof(sink_4_5678(cv_source())) == 8> t8;
+    return 0;
+}
+
+int main()
+{
+    return test4_1234() + test4_1235() + test4_1236() + test4_1237() + test4_1238() +
+           test4_1245() + test4_1246() + test4_1247() + test4_1248() + test4_1256() +
+           test4_1257() + test4_1258() + test4_1267() + test4_1268() + test4_1278() +
+           test4_1345() + test4_1346() + test4_1347() + test4_1348() + test4_1356() +
+           test4_1357() + test4_1358() + test4_1367() + test4_1368() + test4_1378() +
+           test4_1456() + test4_1457() + test4_1458() + test4_1467() + test4_1468() +
+           test4_1478() + test4_1567() + test4_1568() + test4_1578() + test4_1678() +
+           test4_2345() + test4_2346() + test4_2347() + test4_2348() + test4_2356() +
+           test4_2357() + test4_2358() + test4_2367() + test4_2368() + test4_2378() +
+           test4_2456() + test4_2457() + test4_2458() + test4_2467() + test4_2468() +
+           test4_2478() + test4_2567() + test4_2568() + test4_2578() + test4_2678() +
+           test4_3456() + test4_3457() + test4_3458() + test4_3467() + test4_3468() +
+           test4_3478() + test4_3567() + test4_3568() + test4_3578() + test4_3678() +
+           test4_4567() + test4_4568() + test4_4578() + test4_4678() + test4_5678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv5n.C b/gcc/testsuite/g++.dg/cpp0x/rv5n.C
new file mode 100644
index 000000000000..715716e45ee0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv5n.C
@@ -0,0 +1,575 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 5 at a time
+
+one   sink_5_12345(               A&);  // { dg-error "" }
+two   sink_5_12345(const          A&);  // { dg-error "" }
+three sink_5_12345(volatile       A&);  // { dg-error "" }
+four  sink_5_12345(const volatile A&);  // { dg-error "" }
+five  sink_5_12345(               A&&);  // { dg-error "" }
+
+int test5_12345()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12345(v_source());   // { dg-error "no match" }
+    sink_5_12345(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12346(               A&);  // { dg-error "" }
+two   sink_5_12346(const          A&);  // { dg-error "" }
+three sink_5_12346(volatile       A&);  // { dg-error "" }
+four  sink_5_12346(const volatile A&);  // { dg-error "" }
+six   sink_5_12346(const          A&&);  // { dg-error "" }
+
+int test5_12346()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12346(v_source());   // { dg-error "no match" }
+    sink_5_12346(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12347(               A&);  // { dg-error "" }
+two   sink_5_12347(const          A&);  // { dg-error "" }
+three sink_5_12347(volatile       A&);  // { dg-error "" }
+four  sink_5_12347(const volatile A&);  // { dg-error "" }
+seven sink_5_12347(volatile       A&&);  // { dg-error "" }
+
+int test5_12347()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12347(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12356(               A&);  // { dg-error "" }
+two   sink_5_12356(const          A&);  // { dg-error "" }
+three sink_5_12356(volatile       A&);  // { dg-error "" }
+five  sink_5_12356(               A&&);  // { dg-error "" }
+six   sink_5_12356(const          A&&);  // { dg-error "" }
+
+int test5_12356()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12356(cva);          // { dg-error "no match" }
+    sink_5_12356(v_source());   // { dg-error "no match" }
+    sink_5_12356(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12357(               A&);  // { dg-error "" }
+two   sink_5_12357(const          A&);  // { dg-error "" }
+three sink_5_12357(volatile       A&);  // { dg-error "" }
+five  sink_5_12357(               A&&);  // { dg-error "" }
+seven sink_5_12357(volatile       A&&);  // { dg-error "" }
+
+int test5_12357()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12357(cva);          // { dg-error "no match" }
+    sink_5_12357(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12367(               A&);  // { dg-error "" }
+two   sink_5_12367(const          A&);  // { dg-error "" }
+three sink_5_12367(volatile       A&);  // { dg-error "" }
+six   sink_5_12367(const          A&&);  // { dg-error "" }
+seven sink_5_12367(volatile       A&&);  // { dg-error "" }
+
+int test5_12367()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12367(cva);          // { dg-error "no match" }
+    sink_5_12367(source());     // { dg-error "ambiguous" }
+    sink_5_12367(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12456(               A&);  // { dg-error "" }
+two   sink_5_12456(const          A&);  // { dg-error "" }
+four  sink_5_12456(const volatile A&);  // { dg-error "" }
+five  sink_5_12456(               A&&);  // { dg-error "" }
+six   sink_5_12456(const          A&&);  // { dg-error "" }
+
+int test5_12456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12456(v_source());   // { dg-error "no match" }
+    sink_5_12456(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12457(               A&);  // { dg-error "" }
+two   sink_5_12457(const          A&);  // { dg-error "" }
+four  sink_5_12457(const volatile A&);  // { dg-error "" }
+five  sink_5_12457(               A&&);  // { dg-error "" }
+seven sink_5_12457(volatile       A&&);  // { dg-error "" }
+
+int test5_12457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12457(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12467(               A&);  // { dg-error "" }
+two   sink_5_12467(const          A&);  // { dg-error "" }
+four  sink_5_12467(const volatile A&);  // { dg-error "" }
+six   sink_5_12467(const          A&&);  // { dg-error "" }
+seven sink_5_12467(volatile       A&&);  // { dg-error "" }
+
+int test5_12467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12467(source());     // { dg-error "ambiguous" }
+    sink_5_12467(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12567(               A&);  // { dg-error "" }
+two   sink_5_12567(const          A&);  // { dg-error "" }
+five  sink_5_12567(               A&&);  // { dg-error "" }
+six   sink_5_12567(const          A&&);  // { dg-error "" }
+seven sink_5_12567(volatile       A&&);  // { dg-error "" }
+
+int test5_12567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12567(cva);          // { dg-error "no match" }
+    sink_5_12567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_12678(               A&);
+two   sink_5_12678(const          A&);  // { dg-error "" }
+six   sink_5_12678(const          A&&);  // { dg-error "" }
+seven sink_5_12678(volatile       A&&);  // { dg-error "" }
+eight sink_5_12678(const volatile A&&);  // { dg-error "" }
+
+int test5_12678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_12678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+one   sink_5_13456(               A&);  // { dg-error "" }
+three sink_5_13456(volatile       A&);  // { dg-error "" }
+four  sink_5_13456(const volatile A&);  // { dg-error "" }
+five  sink_5_13456(               A&&);  // { dg-error "" }
+six   sink_5_13456(const          A&&);  // { dg-error "" }
+
+int test5_13456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_13456(v_source());   // { dg-error "no match" }
+    sink_5_13456(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_13457(               A&);  // { dg-error "" }
+three sink_5_13457(volatile       A&);  // { dg-error "" }
+four  sink_5_13457(const volatile A&);  // { dg-error "" }
+five  sink_5_13457(               A&&);  // { dg-error "" }
+seven sink_5_13457(volatile       A&&);  // { dg-error "" }
+
+int test5_13457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_13457(c_source());   // { dg-error "no match" }
+    sink_5_13457(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_13467(               A&);  // { dg-error "" }
+three sink_5_13467(volatile       A&);  // { dg-error "" }
+four  sink_5_13467(const volatile A&);  // { dg-error "" }
+six   sink_5_13467(const          A&&);  // { dg-error "" }
+seven sink_5_13467(volatile       A&&);  // { dg-error "" }
+
+int test5_13467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_13467(source());     // { dg-error "ambiguous" }
+    sink_5_13467(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_13567(               A&);  // { dg-error "" }
+three sink_5_13567(volatile       A&);  // { dg-error "" }
+five  sink_5_13567(               A&&);  // { dg-error "" }
+six   sink_5_13567(const          A&&);  // { dg-error "" }
+seven sink_5_13567(volatile       A&&);  // { dg-error "" }
+
+int test5_13567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_13567(cva);          // { dg-error "no match" }
+    sink_5_13567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_13678(               A&);
+three sink_5_13678(volatile       A&);
+six   sink_5_13678(const          A&&);  // { dg-error "" }
+seven sink_5_13678(volatile       A&&);  // { dg-error "" }
+eight sink_5_13678(const volatile A&&);  // { dg-error "" }
+
+int test5_13678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_13678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+one   sink_5_14567(               A&);  // { dg-error "" }
+four  sink_5_14567(const volatile A&);  // { dg-error "" }
+five  sink_5_14567(               A&&);  // { dg-error "" }
+six   sink_5_14567(const          A&&);  // { dg-error "" }
+seven sink_5_14567(volatile       A&&);  // { dg-error "" }
+
+int test5_14567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_14567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_5_14678(               A&);
+four  sink_5_14678(const volatile A&);
+six   sink_5_14678(const          A&&);  // { dg-error "" }
+seven sink_5_14678(volatile       A&&);  // { dg-error "" }
+eight sink_5_14678(const volatile A&&);  // { dg-error "" }
+
+int test5_14678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_14678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_5_23456(const          A&);  // { dg-error "" }
+three sink_5_23456(volatile       A&);  // { dg-error "" }
+four  sink_5_23456(const volatile A&);  // { dg-error "" }
+five  sink_5_23456(               A&&);  // { dg-error "" }
+six   sink_5_23456(const          A&&);  // { dg-error "" }
+
+int test5_23456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23456(a);            // { dg-error "ambiguous" }
+    sink_5_23456(v_source());   // { dg-error "no match" }
+    sink_5_23456(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_5_23457(const          A&);  // { dg-error "" }
+three sink_5_23457(volatile       A&);  // { dg-error "" }
+four  sink_5_23457(const volatile A&);  // { dg-error "" }
+five  sink_5_23457(               A&&);  // { dg-error "" }
+seven sink_5_23457(volatile       A&&);  // { dg-error "" }
+
+int test5_23457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23457(a);            // { dg-error "ambiguous" }
+    sink_5_23457(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_5_23458(const          A&);  // { dg-error "" }
+three sink_5_23458(volatile       A&);  // { dg-error "" }
+four  sink_5_23458(const volatile A&);  // { dg-error "" }
+five  sink_5_23458(               A&&);  // { dg-error "" }
+eight sink_5_23458(const volatile A&&);  // { dg-error "" }
+
+int test5_23458()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23458(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_5_23467(const          A&);  // { dg-error "" }
+three sink_5_23467(volatile       A&);  // { dg-error "" }
+four  sink_5_23467(const volatile A&);  // { dg-error "" }
+six   sink_5_23467(const          A&&);  // { dg-error "" }
+seven sink_5_23467(volatile       A&&);  // { dg-error "" }
+
+int test5_23467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23467(a);            // { dg-error "ambiguous" }
+    sink_5_23467(source());     // { dg-error "ambiguous" }
+    sink_5_23467(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_5_23468(const          A&);  // { dg-error "" }
+three sink_5_23468(volatile       A&);  // { dg-error "" }
+four  sink_5_23468(const volatile A&);  // { dg-error "" }
+six   sink_5_23468(const          A&&);  // { dg-error "" }
+eight sink_5_23468(const volatile A&&);  // { dg-error "" }
+
+int test5_23468()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23468(a);  // { dg-error "ambiguous" }
+   return 0;
+}
+
+two   sink_5_23478(const          A&);  // { dg-error "" }
+three sink_5_23478(volatile       A&);  // { dg-error "" }
+four  sink_5_23478(const volatile A&);  // { dg-error "" }
+seven sink_5_23478(volatile       A&&);  // { dg-error "" }
+eight sink_5_23478(const volatile A&&);  // { dg-error "" }
+
+int test5_23478()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23478(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_5_23567(const          A&);  // { dg-error "" }
+three sink_5_23567(volatile       A&);  // { dg-error "" }
+five  sink_5_23567(               A&&);  // { dg-error "" }
+six   sink_5_23567(const          A&&);  // { dg-error "" }
+seven sink_5_23567(volatile       A&&);  // { dg-error "" }
+
+int test5_23567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23567(a);            // { dg-error "ambiguous" }
+    sink_5_23567(cva);          // { dg-error "no match" }
+    sink_5_23567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_5_23568(const          A&);  // { dg-error "" }
+three sink_5_23568(volatile       A&);  // { dg-error "" }
+five  sink_5_23568(               A&&);  // { dg-error "" }
+six   sink_5_23568(const          A&&);  // { dg-error "" }
+eight sink_5_23568(const volatile A&&);  // { dg-error "" }
+
+int test5_23568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23568(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_5_23578(const          A&);  // { dg-error "" }
+three sink_5_23578(volatile       A&);  // { dg-error "" }
+five  sink_5_23578(               A&&);  // { dg-error "" }
+seven sink_5_23578(volatile       A&&);  // { dg-error "" }
+eight sink_5_23578(const volatile A&&);  // { dg-error "" }
+
+int test5_23578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23578(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_5_23678(const          A&);  // { dg-error "" }
+three sink_5_23678(volatile       A&);  // { dg-error "" }
+six   sink_5_23678(const          A&&);  // { dg-error "" }
+seven sink_5_23678(volatile       A&&);  // { dg-error "" }
+eight sink_5_23678(const volatile A&&);  // { dg-error "" }
+
+int test5_23678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_23678(a);         // { dg-error "ambiguous" }
+    sink_5_23678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_5_24567(const          A&);  // { dg-error "" }
+four  sink_5_24567(const volatile A&);  // { dg-error "" }
+five  sink_5_24567(               A&&);  // { dg-error "" }
+six   sink_5_24567(const          A&&);  // { dg-error "" }
+seven sink_5_24567(volatile       A&&);  // { dg-error "" }
+
+int test5_24567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_24567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_5_24678(const          A&);  // { dg-error "" }
+four  sink_5_24678(const volatile A&);
+six   sink_5_24678(const          A&&);  // { dg-error "" }
+seven sink_5_24678(volatile       A&&);  // { dg-error "" }
+eight sink_5_24678(const volatile A&&);  // { dg-error "" }
+
+int test5_24678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_24678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+three sink_5_34567(volatile       A&);  // { dg-error "" }
+four  sink_5_34567(const volatile A&);  // { dg-error "" }
+five  sink_5_34567(               A&&);  // { dg-error "" }
+six   sink_5_34567(const          A&&);  // { dg-error "" }
+seven sink_5_34567(volatile       A&&);  // { dg-error "" }
+
+int test5_34567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_34567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+three sink_5_34678(volatile       A&);
+four  sink_5_34678(const volatile A&);
+six   sink_5_34678(const          A&&);  // { dg-error "" }
+seven sink_5_34678(volatile       A&&);  // { dg-error "" }
+eight sink_5_34678(const volatile A&&);  // { dg-error "" }
+
+int test5_34678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_5_34678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+int main()
+{
+    return test5_12356() + test5_12357() + test5_12367() + test5_12467() +
+           test5_12567() + test5_12678() + test5_13467() + test5_13567() +
+           test5_13678() + test5_13678() + test5_23456() + test5_23457() +
+           test5_23458() + test5_23467() + test5_23468() + test5_23478() +
+           test5_23567() + test5_23568() + test5_23578() + test5_23678() +
+           test5_24678() + test5_34678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv5p.C b/gcc/testsuite/g++.dg/cpp0x/rv5p.C
new file mode 100644
index 000000000000..a4d916714c3b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv5p.C
@@ -0,0 +1,1283 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 5 at a time
+
+one   sink_5_12345(               A&);
+two   sink_5_12345(const          A&);
+three sink_5_12345(volatile       A&);
+four  sink_5_12345(const volatile A&);
+five  sink_5_12345(               A&&);
+
+int test5_12345()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12345(a))           == 1> t1;
+    sa<sizeof(sink_5_12345(ca))          == 2> t2;
+    sa<sizeof(sink_5_12345(va))          == 3> t3;
+    sa<sizeof(sink_5_12345(cva))         == 4> t4;
+    sa<sizeof(sink_5_12345(source()))    == 5> t5;
+    sa<sizeof(sink_5_12345(c_source()))  == 2> t6;
+    return 0;
+}
+
+one   sink_5_12346(               A&);
+two   sink_5_12346(const          A&);
+three sink_5_12346(volatile       A&);
+four  sink_5_12346(const volatile A&);
+six   sink_5_12346(const          A&&);
+
+int test5_12346()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12346(a))           == 1> t1;
+    sa<sizeof(sink_5_12346(ca))          == 2> t2;
+    sa<sizeof(sink_5_12346(va))          == 3> t3;
+    sa<sizeof(sink_5_12346(cva))         == 4> t4;
+    sa<sizeof(sink_5_12346(source()))    == 6> t5;
+    sa<sizeof(sink_5_12346(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_5_12347(               A&);
+two   sink_5_12347(const          A&);
+three sink_5_12347(volatile       A&);
+four  sink_5_12347(const volatile A&);
+seven sink_5_12347(volatile       A&&);
+
+int test5_12347()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12347(a))           == 1> t1;
+    sa<sizeof(sink_5_12347(ca))          == 2> t2;
+    sa<sizeof(sink_5_12347(va))          == 3> t3;
+    sa<sizeof(sink_5_12347(cva))         == 4> t4;
+    sa<sizeof(sink_5_12347(source()))    == 7> t5;
+    sa<sizeof(sink_5_12347(c_source()))  == 2> t6;
+    sa<sizeof(sink_5_12347(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_12348(               A&);
+two   sink_5_12348(const          A&);
+three sink_5_12348(volatile       A&);
+four  sink_5_12348(const volatile A&);
+eight sink_5_12348(const volatile A&&);
+
+int test5_12348()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12348(a))           == 1> t1;
+    sa<sizeof(sink_5_12348(ca))          == 2> t2;
+    sa<sizeof(sink_5_12348(va))          == 3> t3;
+    sa<sizeof(sink_5_12348(cva))         == 4> t4;
+    sa<sizeof(sink_5_12348(source()))    == 8> t5;
+    sa<sizeof(sink_5_12348(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_12348(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_12348(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_12356(               A&);
+two   sink_5_12356(const          A&);
+three sink_5_12356(volatile       A&);
+five  sink_5_12356(               A&&);
+six   sink_5_12356(const          A&&);
+
+int test5_12356()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12356(a))           == 1> t1;
+    sa<sizeof(sink_5_12356(ca))          == 2> t2;
+    sa<sizeof(sink_5_12356(va))          == 3> t3;
+    sa<sizeof(sink_5_12356(source()))    == 5> t5;
+    sa<sizeof(sink_5_12356(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_5_12357(               A&);
+two   sink_5_12357(const          A&);
+three sink_5_12357(volatile       A&);
+five  sink_5_12357(               A&&);
+seven sink_5_12357(volatile       A&&);
+
+int test5_12357()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12357(a))           == 1> t1;
+    sa<sizeof(sink_5_12357(ca))          == 2> t2;
+    sa<sizeof(sink_5_12357(va))          == 3> t3;
+    sa<sizeof(sink_5_12357(source()))    == 5> t5;
+    sa<sizeof(sink_5_12357(c_source()))  == 2> t6;
+    sa<sizeof(sink_5_12357(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_12358(               A&);
+two   sink_5_12358(const          A&);
+three sink_5_12358(volatile       A&);
+five  sink_5_12358(               A&&);
+eight sink_5_12358(const volatile A&&);
+
+int test5_12358()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12358(a))           == 1> t1;
+    sa<sizeof(sink_5_12358(ca))          == 2> t2;
+    sa<sizeof(sink_5_12358(va))          == 3> t3;
+    sa<sizeof(sink_5_12358(cva))         == 8> t4;
+    sa<sizeof(sink_5_12358(source()))    == 5> t5;
+    sa<sizeof(sink_5_12358(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_12358(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_12358(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_12367(               A&);
+two   sink_5_12367(const          A&);
+three sink_5_12367(volatile       A&);
+six   sink_5_12367(const          A&&);
+seven sink_5_12367(volatile       A&&);
+
+int test5_12367()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12367(a))           == 1> t1;
+    sa<sizeof(sink_5_12367(ca))          == 2> t2;
+    sa<sizeof(sink_5_12367(va))          == 3> t3;
+    sa<sizeof(sink_5_12367(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_12367(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_12368(               A&);
+two   sink_5_12368(const          A&);
+three sink_5_12368(volatile       A&);
+six   sink_5_12368(const          A&&);
+eight sink_5_12368(const volatile A&&);
+
+int test5_12368()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12368(a))           == 1> t1;
+    sa<sizeof(sink_5_12368(ca))          == 2> t2;
+    sa<sizeof(sink_5_12368(va))          == 3> t3;
+    sa<sizeof(sink_5_12368(cva))         == 8> t4;
+    sa<sizeof(sink_5_12368(source()))    == 6> t5;
+    sa<sizeof(sink_5_12368(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_12368(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_12368(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_12378(               A&);
+two   sink_5_12378(const          A&);
+three sink_5_12378(volatile       A&);
+seven sink_5_12378(volatile       A&&);
+eight sink_5_12378(const volatile A&&);
+
+int test5_12378()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12378(a))           == 1> t1;
+    sa<sizeof(sink_5_12378(ca))          == 2> t2;
+    sa<sizeof(sink_5_12378(va))          == 3> t3;
+    sa<sizeof(sink_5_12378(cva))         == 8> t4;
+    sa<sizeof(sink_5_12378(source()))    == 7> t5;
+    sa<sizeof(sink_5_12378(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_12378(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_12378(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_12456(               A&);
+two   sink_5_12456(const          A&);
+four  sink_5_12456(const volatile A&);
+five  sink_5_12456(               A&&);
+six   sink_5_12456(const          A&&);
+
+int test5_12456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12456(a))           == 1> t1;
+    sa<sizeof(sink_5_12456(ca))          == 2> t2;
+    sa<sizeof(sink_5_12456(va))          == 4> t3;
+    sa<sizeof(sink_5_12456(cva))         == 4> t4;
+    sa<sizeof(sink_5_12456(source()))    == 5> t5;
+    sa<sizeof(sink_5_12456(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_5_12457(               A&);
+two   sink_5_12457(const          A&);
+four  sink_5_12457(const volatile A&);
+five  sink_5_12457(               A&&);
+seven sink_5_12457(volatile       A&&);
+
+int test5_12457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12457(a))           == 1> t1;
+    sa<sizeof(sink_5_12457(ca))          == 2> t2;
+    sa<sizeof(sink_5_12457(va))          == 4> t3;
+    sa<sizeof(sink_5_12457(cva))         == 4> t4;
+    sa<sizeof(sink_5_12457(source()))    == 5> t5;
+    sa<sizeof(sink_5_12457(c_source()))  == 2> t6;
+    sa<sizeof(sink_5_12457(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_12458(               A&);
+two   sink_5_12458(const          A&);
+four  sink_5_12458(const volatile A&);
+five  sink_5_12458(               A&&);
+eight sink_5_12458(const volatile A&&);
+
+int test5_12458()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12458(a))           == 1> t1;
+    sa<sizeof(sink_5_12458(ca))          == 2> t2;
+    sa<sizeof(sink_5_12458(va))          == 4> t3;
+    sa<sizeof(sink_5_12458(cva))         == 4> t4;
+    sa<sizeof(sink_5_12458(source()))    == 5> t5;
+    sa<sizeof(sink_5_12458(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_12458(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_12458(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_12467(               A&);
+two   sink_5_12467(const          A&);
+four  sink_5_12467(const volatile A&);
+six   sink_5_12467(const          A&&);
+seven sink_5_12467(volatile       A&&);
+
+int test5_12467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12467(a))           == 1> t1;
+    sa<sizeof(sink_5_12467(ca))          == 2> t2;
+    sa<sizeof(sink_5_12467(va))          == 4> t3;
+    sa<sizeof(sink_5_12467(cva))         == 4> t4;
+    sa<sizeof(sink_5_12467(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_12467(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_12468(               A&);
+two   sink_5_12468(const          A&);
+four  sink_5_12468(const volatile A&);
+six   sink_5_12468(const          A&&);
+eight sink_5_12468(const volatile A&&);
+
+int test5_12468()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12468(a))           == 1> t1;
+    sa<sizeof(sink_5_12468(ca))          == 2> t2;
+    sa<sizeof(sink_5_12468(va))          == 4> t3;
+    sa<sizeof(sink_5_12468(cva))         == 4> t4;
+    sa<sizeof(sink_5_12468(source()))    == 6> t5;
+    sa<sizeof(sink_5_12468(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_12468(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_12468(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_12478(               A&);
+two   sink_5_12478(const          A&);
+four  sink_5_12478(const volatile A&);
+seven sink_5_12478(volatile       A&&);
+eight sink_5_12478(const volatile A&&);
+
+int test5_12478()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12478(a))           == 1> t1;
+    sa<sizeof(sink_5_12478(ca))          == 2> t2;
+    sa<sizeof(sink_5_12478(va))          == 4> t3;
+    sa<sizeof(sink_5_12478(cva))         == 4> t4;
+    sa<sizeof(sink_5_12478(source()))    == 7> t5;
+    sa<sizeof(sink_5_12478(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_12478(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_12478(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_12567(               A&);
+two   sink_5_12567(const          A&);
+five  sink_5_12567(               A&&);
+six   sink_5_12567(const          A&&);
+seven sink_5_12567(volatile       A&&);
+
+int test5_12567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12567(a))           == 1> t1;
+    sa<sizeof(sink_5_12567(ca))          == 2> t2;
+    sa<sizeof(sink_5_12567(va))          == 7> t3;
+    sa<sizeof(sink_5_12567(source()))    == 5> t5;
+    sa<sizeof(sink_5_12567(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_12567(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_12568(               A&);
+two   sink_5_12568(const          A&);
+five  sink_5_12568(               A&&);
+six   sink_5_12568(const          A&&);
+eight sink_5_12568(const volatile A&&);
+
+int test5_12568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12568(a))           == 1> t1;
+    sa<sizeof(sink_5_12568(ca))          == 2> t2;
+    sa<sizeof(sink_5_12568(va))          == 8> t3;
+    sa<sizeof(sink_5_12568(cva))         == 8> t4;
+    sa<sizeof(sink_5_12568(source()))    == 5> t5;
+    sa<sizeof(sink_5_12568(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_12568(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_12568(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_12578(               A&);
+two   sink_5_12578(const          A&);
+five  sink_5_12578(               A&&);
+seven sink_5_12578(volatile       A&&);
+eight sink_5_12578(const volatile A&&);
+
+int test5_12578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12578(a))           == 1> t1;
+    sa<sizeof(sink_5_12578(ca))          == 2> t2;
+    sa<sizeof(sink_5_12578(va))          == 7> t3;
+    sa<sizeof(sink_5_12578(cva))         == 8> t4;
+    sa<sizeof(sink_5_12578(source()))    == 5> t5;
+    sa<sizeof(sink_5_12578(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_12578(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_12578(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_12678(               A&);
+two   sink_5_12678(const          A&);
+six   sink_5_12678(const          A&&);
+seven sink_5_12678(volatile       A&&);
+eight sink_5_12678(const volatile A&&);
+
+int test5_12678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_12678(a))           == 1> t1;
+    sa<sizeof(sink_5_12678(ca))          == 2> t2;
+    sa<sizeof(sink_5_12678(va))          == 7> t3;
+    sa<sizeof(sink_5_12678(cva))         == 8> t4;
+    sa<sizeof(sink_5_12678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_12678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_12678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_13456(               A&);
+three sink_5_13456(volatile       A&);
+four  sink_5_13456(const volatile A&);
+five  sink_5_13456(               A&&);
+six   sink_5_13456(const          A&&);
+
+int test5_13456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13456(a))           == 1> t1;
+    sa<sizeof(sink_5_13456(ca))          == 4> t2;
+    sa<sizeof(sink_5_13456(va))          == 3> t3;
+    sa<sizeof(sink_5_13456(cva))         == 4> t4;
+    sa<sizeof(sink_5_13456(source()))    == 5> t5;
+    sa<sizeof(sink_5_13456(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_5_13457(               A&);
+three sink_5_13457(volatile       A&);
+four  sink_5_13457(const volatile A&);
+five  sink_5_13457(               A&&);
+seven sink_5_13457(volatile       A&&);
+
+int test5_13457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13457(a))           == 1> t1;
+    sa<sizeof(sink_5_13457(ca))          == 4> t2;
+    sa<sizeof(sink_5_13457(va))          == 3> t3;
+    sa<sizeof(sink_5_13457(cva))         == 4> t4;
+    sa<sizeof(sink_5_13457(source()))    == 5> t5;
+    sa<sizeof(sink_5_13457(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_13458(               A&);
+three sink_5_13458(volatile       A&);
+four  sink_5_13458(const volatile A&);
+five  sink_5_13458(               A&&);
+eight sink_5_13458(const volatile A&&);
+
+int test5_13458()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13458(a))           == 1> t1;
+    sa<sizeof(sink_5_13458(ca))          == 4> t2;
+    sa<sizeof(sink_5_13458(va))          == 3> t3;
+    sa<sizeof(sink_5_13458(cva))         == 4> t4;
+    sa<sizeof(sink_5_13458(source()))    == 5> t5;
+    sa<sizeof(sink_5_13458(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_13458(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_13458(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_13467(               A&);
+three sink_5_13467(volatile       A&);
+four  sink_5_13467(const volatile A&);
+six   sink_5_13467(const          A&&);
+seven sink_5_13467(volatile       A&&);
+
+int test5_13467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13467(a))           == 1> t1;
+    sa<sizeof(sink_5_13467(ca))          == 4> t2;
+    sa<sizeof(sink_5_13467(va))          == 3> t3;
+    sa<sizeof(sink_5_13467(cva))         == 4> t4;
+    sa<sizeof(sink_5_13467(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_13467(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_13468(               A&);
+three sink_5_13468(volatile       A&);
+four  sink_5_13468(const volatile A&);
+six   sink_5_13468(const          A&&);
+eight sink_5_13468(const volatile A&&);
+
+int test5_13468()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13468(a))           == 1> t1;
+    sa<sizeof(sink_5_13468(ca))          == 4> t2;
+    sa<sizeof(sink_5_13468(va))          == 3> t3;
+    sa<sizeof(sink_5_13468(cva))         == 4> t4;
+    sa<sizeof(sink_5_13468(source()))    == 6> t5;
+    sa<sizeof(sink_5_13468(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_13468(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_13468(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_13478(               A&);
+three sink_5_13478(volatile       A&);
+four  sink_5_13478(const volatile A&);
+seven sink_5_13478(volatile       A&&);
+eight sink_5_13478(const volatile A&&);
+
+int test5_13478()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13478(a))           == 1> t1;
+    sa<sizeof(sink_5_13478(ca))          == 4> t2;
+    sa<sizeof(sink_5_13478(va))          == 3> t3;
+    sa<sizeof(sink_5_13478(cva))         == 4> t4;
+    sa<sizeof(sink_5_13478(source()))    == 7> t5;
+    sa<sizeof(sink_5_13478(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_13478(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_13478(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_13567(               A&);
+three sink_5_13567(volatile       A&);
+five  sink_5_13567(               A&&);
+six   sink_5_13567(const          A&&);
+seven sink_5_13567(volatile       A&&);
+
+int test5_13567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13567(a))           == 1> t1;
+    sa<sizeof(sink_5_13567(ca))          == 6> t2;
+    sa<sizeof(sink_5_13567(va))          == 3> t3;
+    sa<sizeof(sink_5_13567(source()))    == 5> t5;
+    sa<sizeof(sink_5_13567(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_13567(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_13568(               A&);
+three sink_5_13568(volatile       A&);
+five  sink_5_13568(               A&&);
+six   sink_5_13568(const          A&&);
+eight sink_5_13568(const volatile A&&);
+
+int test5_13568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13568(a))           == 1> t1;
+    sa<sizeof(sink_5_13568(ca))          == 6> t2;
+    sa<sizeof(sink_5_13568(va))          == 3> t3;
+    sa<sizeof(sink_5_13568(cva))         == 8> t4;
+    sa<sizeof(sink_5_13568(source()))    == 5> t5;
+    sa<sizeof(sink_5_13568(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_13568(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_13568(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_13578(               A&);
+three sink_5_13578(volatile       A&);
+five  sink_5_13578(               A&&);
+seven sink_5_13578(volatile       A&&);
+eight sink_5_13578(const volatile A&&);
+
+int test5_13578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13578(a))           == 1> t1;
+    sa<sizeof(sink_5_13578(ca))          == 8> t2;
+    sa<sizeof(sink_5_13578(va))          == 3> t3;
+    sa<sizeof(sink_5_13578(cva))         == 8> t4;
+    sa<sizeof(sink_5_13578(source()))    == 5> t5;
+    sa<sizeof(sink_5_13578(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_13578(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_13578(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_13678(               A&);
+three sink_5_13678(volatile       A&);
+six   sink_5_13678(const          A&&);
+seven sink_5_13678(volatile       A&&);
+eight sink_5_13678(const volatile A&&);
+
+int test5_13678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_13678(a))           == 1> t1;
+    sa<sizeof(sink_5_13678(ca))          == 6> t2;
+    sa<sizeof(sink_5_13678(va))          == 3> t3;
+    sa<sizeof(sink_5_13678(cva))         == 8> t4;
+    sa<sizeof(sink_5_13678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_13678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_13678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_14567(               A&);
+four  sink_5_14567(const volatile A&);
+five  sink_5_14567(               A&&);
+six   sink_5_14567(const          A&&);
+seven sink_5_14567(volatile       A&&);
+
+int test5_14567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_14567(a))           == 1> t1;
+    sa<sizeof(sink_5_14567(ca))          == 4> t2;
+    sa<sizeof(sink_5_14567(va))          == 4> t3;
+    sa<sizeof(sink_5_14567(cva))         == 4> t4;
+    sa<sizeof(sink_5_14567(source()))    == 5> t5;
+    sa<sizeof(sink_5_14567(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_14567(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_5_14568(               A&);
+four  sink_5_14568(const volatile A&);
+five  sink_5_14568(               A&&);
+six   sink_5_14568(const          A&&);
+eight sink_5_14568(const volatile A&&);
+
+int test5_14568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_14568(a))           == 1> t1;
+    sa<sizeof(sink_5_14568(ca))          == 4> t2;
+    sa<sizeof(sink_5_14568(va))          == 4> t3;
+    sa<sizeof(sink_5_14568(cva))         == 4> t4;
+    sa<sizeof(sink_5_14568(source()))    == 5> t5;
+    sa<sizeof(sink_5_14568(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_14568(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_14568(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_14578(               A&);
+four  sink_5_14578(const volatile A&);
+five  sink_5_14578(               A&&);
+seven sink_5_14578(volatile       A&&);
+eight sink_5_14578(const volatile A&&);
+
+int test5_14578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_14578(a))           == 1> t1;
+    sa<sizeof(sink_5_14578(ca))          == 4> t2;
+    sa<sizeof(sink_5_14578(va))          == 4> t3;
+    sa<sizeof(sink_5_14578(cva))         == 4> t4;
+    sa<sizeof(sink_5_14578(source()))    == 5> t5;
+    sa<sizeof(sink_5_14578(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_14578(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_14578(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_14678(               A&);
+four  sink_5_14678(const volatile A&);
+six   sink_5_14678(const          A&&);
+seven sink_5_14678(volatile       A&&);
+eight sink_5_14678(const volatile A&&);
+
+int test5_14678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_14678(a))           == 1> t1;
+    sa<sizeof(sink_5_14678(ca))          == 4> t2;
+    sa<sizeof(sink_5_14678(va))          == 4> t3;
+    sa<sizeof(sink_5_14678(cva))         == 4> t4;
+    sa<sizeof(sink_5_14678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_14678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_14678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_5_15678(               A&);
+five  sink_5_15678(               A&&);
+six   sink_5_15678(const          A&&);
+seven sink_5_15678(volatile       A&&);
+eight sink_5_15678(const volatile A&&);
+
+int test5_15678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_15678(a))           == 1> t1;
+    sa<sizeof(sink_5_15678(ca))          == 6> t2;
+    sa<sizeof(sink_5_15678(va))          == 7> t3;
+    sa<sizeof(sink_5_15678(cva))         == 8> t4;
+    sa<sizeof(sink_5_15678(source()))    == 5> t5;
+    sa<sizeof(sink_5_15678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_15678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_15678(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_23456(const          A&);
+three sink_5_23456(volatile       A&);
+four  sink_5_23456(const volatile A&);
+five  sink_5_23456(               A&&);
+six   sink_5_23456(const          A&&);
+
+int test5_23456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23456(ca))          == 2> t2;
+    sa<sizeof(sink_5_23456(va))          == 3> t3;
+    sa<sizeof(sink_5_23456(cva))         == 4> t4;
+    sa<sizeof(sink_5_23456(source()))    == 5> t5;
+    sa<sizeof(sink_5_23456(c_source()))  == 6> t6;
+    return 0;
+}
+
+two   sink_5_23457(const          A&);
+three sink_5_23457(volatile       A&);
+four  sink_5_23457(const volatile A&);
+five  sink_5_23457(               A&&);
+seven sink_5_23457(volatile       A&&);
+
+int test5_23457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23457(ca))          == 2> t2;
+    sa<sizeof(sink_5_23457(va))          == 3> t3;
+    sa<sizeof(sink_5_23457(cva))         == 4> t4;
+    sa<sizeof(sink_5_23457(source()))    == 5> t5;
+    sa<sizeof(sink_5_23457(c_source()))  == 2> t6;
+    sa<sizeof(sink_5_23457(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_5_23458(const          A&);
+three sink_5_23458(volatile       A&);
+four  sink_5_23458(const volatile A&);
+five  sink_5_23458(               A&&);
+eight sink_5_23458(const volatile A&&);
+
+int test5_23458()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23458(ca))          == 2> t2;
+    sa<sizeof(sink_5_23458(va))          == 3> t3;
+    sa<sizeof(sink_5_23458(cva))         == 4> t4;
+    sa<sizeof(sink_5_23458(source()))    == 5> t5;
+    sa<sizeof(sink_5_23458(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_23458(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_23458(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_23467(const          A&);
+three sink_5_23467(volatile       A&);
+four  sink_5_23467(const volatile A&);
+six   sink_5_23467(const          A&&);
+seven sink_5_23467(volatile       A&&);
+
+int test5_23467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23467(ca))          == 2> t2;
+    sa<sizeof(sink_5_23467(va))          == 3> t3;
+    sa<sizeof(sink_5_23467(cva))         == 4> t4;
+    sa<sizeof(sink_5_23467(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_23467(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_5_23468(const          A&);
+three sink_5_23468(volatile       A&);
+four  sink_5_23468(const volatile A&);
+six   sink_5_23468(const          A&&);
+eight sink_5_23468(const volatile A&&);
+
+int test5_23468()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23468(ca))          == 2> t2;
+    sa<sizeof(sink_5_23468(va))          == 3> t3;
+    sa<sizeof(sink_5_23468(cva))         == 4> t4;
+    sa<sizeof(sink_5_23468(source()))    == 6> t5;
+    sa<sizeof(sink_5_23468(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_23468(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_23468(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_23478(const          A&);
+three sink_5_23478(volatile       A&);
+four  sink_5_23478(const volatile A&);
+seven sink_5_23478(volatile       A&&);
+eight sink_5_23478(const volatile A&&);
+
+int test5_23478()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23478(ca))          == 2> t2;
+    sa<sizeof(sink_5_23478(va))          == 3> t3;
+    sa<sizeof(sink_5_23478(cva))         == 4> t4;
+    sa<sizeof(sink_5_23478(source()))    == 7> t5;
+    sa<sizeof(sink_5_23478(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_23478(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_23478(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_23567(const          A&);
+three sink_5_23567(volatile       A&);
+five  sink_5_23567(               A&&);
+six   sink_5_23567(const          A&&);
+seven sink_5_23567(volatile       A&&);
+
+int test5_23567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23567(ca))          == 2> t2;
+    sa<sizeof(sink_5_23567(va))          == 3> t3;
+    sa<sizeof(sink_5_23567(source()))    == 5> t5;
+    sa<sizeof(sink_5_23567(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_23567(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_5_23568(const          A&);
+three sink_5_23568(volatile       A&);
+five  sink_5_23568(               A&&);
+six   sink_5_23568(const          A&&);
+eight sink_5_23568(const volatile A&&);
+
+int test5_23568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23568(ca))          == 2> t2;
+    sa<sizeof(sink_5_23568(va))          == 3> t3;
+    sa<sizeof(sink_5_23568(cva))         == 8> t4;
+    sa<sizeof(sink_5_23568(source()))    == 5> t5;
+    sa<sizeof(sink_5_23568(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_23568(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_23568(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_23578(const          A&);
+three sink_5_23578(volatile       A&);
+five  sink_5_23578(               A&&);
+seven sink_5_23578(volatile       A&&);
+eight sink_5_23578(const volatile A&&);
+
+int test5_23578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23578(ca))          == 2> t2;
+    sa<sizeof(sink_5_23578(va))          == 3> t3;
+    sa<sizeof(sink_5_23578(cva))         == 8> t4;
+    sa<sizeof(sink_5_23578(source()))    == 5> t5;
+    sa<sizeof(sink_5_23578(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_23578(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_23578(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_23678(const          A&);
+three sink_5_23678(volatile       A&);
+six   sink_5_23678(const          A&&);
+seven sink_5_23678(volatile       A&&);
+eight sink_5_23678(const volatile A&&);
+
+int test5_23678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_23678(ca))          == 2> t2;
+    sa<sizeof(sink_5_23678(va))          == 3> t3;
+    sa<sizeof(sink_5_23678(cva))         == 8> t4;
+    sa<sizeof(sink_5_23678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_23678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_23678(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_24567(const          A&);
+four  sink_5_24567(const volatile A&);
+five  sink_5_24567(               A&&);
+six   sink_5_24567(const          A&&);
+seven sink_5_24567(volatile       A&&);
+
+int test5_24567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_24567(a))           == 2> t1;
+    sa<sizeof(sink_5_24567(ca))          == 2> t2;
+    sa<sizeof(sink_5_24567(va))          == 4> t3;
+    sa<sizeof(sink_5_24567(cva))         == 4> t4;
+    sa<sizeof(sink_5_24567(source()))    == 5> t5;
+    sa<sizeof(sink_5_24567(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_24567(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_5_24568(const          A&);
+four  sink_5_24568(const volatile A&);
+five  sink_5_24568(               A&&);
+six   sink_5_24568(const          A&&);
+eight sink_5_24568(const volatile A&&);
+
+int test5_24568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_24568(a))           == 2> t1;
+    sa<sizeof(sink_5_24568(ca))          == 2> t2;
+    sa<sizeof(sink_5_24568(va))          == 4> t3;
+    sa<sizeof(sink_5_24568(cva))         == 4> t4;
+    sa<sizeof(sink_5_24568(source()))    == 5> t5;
+    sa<sizeof(sink_5_24568(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_24568(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_24568(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_24578(const          A&);
+four  sink_5_24578(const volatile A&);
+five  sink_5_24578(               A&&);
+seven sink_5_24578(volatile       A&&);
+eight sink_5_24578(const volatile A&&);
+
+int test5_24578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_24578(a))           == 2> t1;
+    sa<sizeof(sink_5_24578(ca))          == 2> t2;
+    sa<sizeof(sink_5_24578(va))          == 4> t3;
+    sa<sizeof(sink_5_24578(cva))         == 4> t4;
+    sa<sizeof(sink_5_24578(source()))    == 5> t5;
+    sa<sizeof(sink_5_24578(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_24578(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_24578(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_24678(const          A&);
+four  sink_5_24678(const volatile A&);
+six   sink_5_24678(const          A&&);
+seven sink_5_24678(volatile       A&&);
+eight sink_5_24678(const volatile A&&);
+
+int test5_24678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_24678(a))           == 2> t1;
+    sa<sizeof(sink_5_24678(ca))          == 2> t2;
+    sa<sizeof(sink_5_24678(va))          == 4> t3;
+    sa<sizeof(sink_5_24678(cva))         == 4> t4;
+    sa<sizeof(sink_5_24678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_24678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_24678(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_5_25678(const          A&);
+five  sink_5_25678(               A&&);
+six   sink_5_25678(const          A&&);
+seven sink_5_25678(volatile       A&&);
+eight sink_5_25678(const volatile A&&);
+
+int test5_25678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_25678(a))           == 2> t1;
+    sa<sizeof(sink_5_25678(ca))          == 2> t2;
+    sa<sizeof(sink_5_25678(va))          == 7> t3;
+    sa<sizeof(sink_5_25678(cva))         == 8> t4;
+    sa<sizeof(sink_5_25678(source()))    == 5> t5;
+    sa<sizeof(sink_5_25678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_25678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_25678(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_5_34567(volatile       A&);
+four  sink_5_34567(const volatile A&);
+five  sink_5_34567(               A&&);
+six   sink_5_34567(const          A&&);
+seven sink_5_34567(volatile       A&&);
+
+int test5_34567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_34567(a))           == 3> t1;
+    sa<sizeof(sink_5_34567(ca))          == 4> t2;
+    sa<sizeof(sink_5_34567(va))          == 3> t3;
+    sa<sizeof(sink_5_34567(cva))         == 4> t4;
+    sa<sizeof(sink_5_34567(source()))    == 5> t5;
+    sa<sizeof(sink_5_34567(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_34567(v_source()))  == 7> t7;
+    return 0;
+}
+
+three sink_5_34568(volatile       A&);
+four  sink_5_34568(const volatile A&);
+five  sink_5_34568(               A&&);
+six   sink_5_34568(const          A&&);
+eight sink_5_34568(const volatile A&&);
+
+int test5_34568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_34568(a))           == 3> t1;
+    sa<sizeof(sink_5_34568(ca))          == 4> t2;
+    sa<sizeof(sink_5_34568(va))          == 3> t3;
+    sa<sizeof(sink_5_34568(cva))         == 4> t4;
+    sa<sizeof(sink_5_34568(source()))    == 5> t5;
+    sa<sizeof(sink_5_34568(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_34568(v_source()))  == 8> t7;
+    sa<sizeof(sink_5_34568(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_5_34578(volatile       A&);
+four  sink_5_34578(const volatile A&);
+five  sink_5_34578(               A&&);
+seven sink_5_34578(volatile       A&&);
+eight sink_5_34578(const volatile A&&);
+
+int test5_34578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_34578(a))           == 3> t1;
+    sa<sizeof(sink_5_34578(ca))          == 4> t2;
+    sa<sizeof(sink_5_34578(va))          == 3> t3;
+    sa<sizeof(sink_5_34578(cva))         == 4> t4;
+    sa<sizeof(sink_5_34578(source()))    == 5> t5;
+    sa<sizeof(sink_5_34578(c_source()))  == 8> t6;
+    sa<sizeof(sink_5_34578(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_34578(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_5_34678(volatile       A&);
+four  sink_5_34678(const volatile A&);
+six   sink_5_34678(const          A&&);
+seven sink_5_34678(volatile       A&&);
+eight sink_5_34678(const volatile A&&);
+
+int test5_34678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_34678(a))           == 3> t1;
+    sa<sizeof(sink_5_34678(ca))          == 4> t2;
+    sa<sizeof(sink_5_34678(va))          == 3> t3;
+    sa<sizeof(sink_5_34678(cva))         == 4> t4;
+    sa<sizeof(sink_5_34678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_34678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_34678(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_5_35678(volatile       A&);
+five  sink_5_35678(               A&&);
+six   sink_5_35678(const          A&&);
+seven sink_5_35678(volatile       A&&);
+eight sink_5_35678(const volatile A&&);
+
+int test5_35678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_35678(a))           == 3> t1;
+    sa<sizeof(sink_5_35678(ca))          == 6> t2;
+    sa<sizeof(sink_5_35678(va))          == 3> t3;
+    sa<sizeof(sink_5_35678(cva))         == 8> t4;
+    sa<sizeof(sink_5_35678(source()))    == 5> t5;
+    sa<sizeof(sink_5_35678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_35678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_35678(cv_source())) == 8> t8;
+    return 0;
+}
+
+four  sink_5_45678(const volatile A&);
+five  sink_5_45678(               A&&);
+six   sink_5_45678(const          A&&);
+seven sink_5_45678(volatile       A&&);
+eight sink_5_45678(const volatile A&&);
+
+int test5_45678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_5_45678(a))           == 4> t1;
+    sa<sizeof(sink_5_45678(ca))          == 4> t2;
+    sa<sizeof(sink_5_45678(va))          == 4> t3;
+    sa<sizeof(sink_5_45678(cva))         == 4> t4;
+    sa<sizeof(sink_5_45678(source()))    == 5> t5;
+    sa<sizeof(sink_5_45678(c_source()))  == 6> t6;
+    sa<sizeof(sink_5_45678(v_source()))  == 7> t7;
+    sa<sizeof(sink_5_45678(cv_source())) == 8> t8;
+    return 0;
+}
+
+int main()
+{
+    return test5_12345() + test5_12346() + test5_12347() + test5_12348() +
+           test5_12356() + test5_12357() + test5_12358() + test5_12367() +
+           test5_12368() + test5_12378() + test5_12456() + test5_12457() +
+           test5_12458() + test5_12467() + test5_12468() + test5_12478() +
+           test5_12567() + test5_12568() + test5_12578() + test5_12678() +
+           test5_13456() + test5_13457() + test5_13458() + test5_13467() +
+           test5_13468() + test5_13478() + test5_13567() + test5_13568() +
+           test5_13578() + test5_13678() + test5_14567() + test5_14568() +
+           test5_14578() + test5_14678() + test5_15678() + test5_23456() +
+           test5_23457() + test5_23458() + test5_23467() + test5_23468() +
+           test5_23478() + test5_23567() + test5_23568() + test5_23578() +
+           test5_23678() + test5_24567() + test5_24568() + test5_24578() +
+           test5_24678() + test5_25678() + test5_34567() + test5_34568() +
+           test5_34578() + test5_34678() + test5_35678() + test5_45678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv6n.C b/gcc/testsuite/g++.dg/cpp0x/rv6n.C
new file mode 100644
index 000000000000..9a925ef0c617
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv6n.C
@@ -0,0 +1,281 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 6 at a time
+
+one   sink_6_123456(               A&);  // { dg-error "" }
+two   sink_6_123456(const          A&);  // { dg-error "" }
+three sink_6_123456(volatile       A&);  // { dg-error "" }
+four  sink_6_123456(const volatile A&);  // { dg-error "" }
+five  sink_6_123456(               A&&);  // { dg-error "" }
+six   sink_6_123456(const          A&&);  // { dg-error "" }
+
+int test6_123456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_123456(v_source());   // { dg-error "no match" }
+    sink_6_123456(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_6_123457(               A&);  // { dg-error "" }
+two   sink_6_123457(const          A&);  // { dg-error "" }
+three sink_6_123457(volatile       A&);  // { dg-error "" }
+four  sink_6_123457(const volatile A&);  // { dg-error "" }
+five  sink_6_123457(               A&&);  // { dg-error "" }
+seven sink_6_123457(volatile       A&&);  // { dg-error "" }
+
+int test6_123457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_123457(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_6_235678(const          A&);  // { dg-error "" }
+three sink_6_235678(volatile       A&);  // { dg-error "" }
+five  sink_6_235678(               A&&);  // { dg-error "" }
+six   sink_6_235678(const          A&&);  // { dg-error "" }
+seven sink_6_235678(volatile       A&&);  // { dg-error "" }
+eight sink_6_235678(const volatile A&&);  // { dg-error "" }
+
+int test6_235678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_235678(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_6_234678(const          A&);  // { dg-error "" }
+three sink_6_234678(volatile       A&);  // { dg-error "" }
+four  sink_6_234678(const volatile A&);  // { dg-error "" }
+six   sink_6_234678(const          A&&);  // { dg-error "" }
+seven sink_6_234678(volatile       A&&);  // { dg-error "" }
+eight sink_6_234678(const volatile A&&);  // { dg-error "" }
+
+int test6_234678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_234678(a);         // { dg-error "ambiguous" }
+    sink_6_234678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_6_234578(const          A&);  // { dg-error "" }
+three sink_6_234578(volatile       A&);  // { dg-error "" }
+four  sink_6_234578(const volatile A&);  // { dg-error "" }
+five  sink_6_234578(               A&&);  // { dg-error "" }
+seven sink_6_234578(volatile       A&&);  // { dg-error "" }
+eight sink_6_234578(const volatile A&&);  // { dg-error "" }
+
+int test6_234578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_234578(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_6_234568(const          A&);  // { dg-error "" }
+three sink_6_234568(volatile       A&);  // { dg-error "" }
+four  sink_6_234568(const volatile A&);  // { dg-error "" }
+five  sink_6_234568(               A&&);  // { dg-error "" }
+six   sink_6_234568(const          A&&);  // { dg-error "" }
+eight sink_6_234568(const volatile A&&);  // { dg-error "" }
+
+int test6_234568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_234568(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+two   sink_6_234567(const          A&);  // { dg-error "" }
+three sink_6_234567(volatile       A&);  // { dg-error "" }
+four  sink_6_234567(const volatile A&);  // { dg-error "" }
+five  sink_6_234567(               A&&);  // { dg-error "" }
+six   sink_6_234567(const          A&&);  // { dg-error "" }
+seven sink_6_234567(volatile       A&&);  // { dg-error "" }
+
+int test6_234567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_234567(a);            // { dg-error "ambiguous" }
+    sink_6_234567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_6_134678(               A&);
+three sink_6_134678(volatile       A&);
+four  sink_6_134678(const volatile A&);
+six   sink_6_134678(const          A&&);  // { dg-error "" }
+seven sink_6_134678(volatile       A&&);  // { dg-error "" }
+eight sink_6_134678(const volatile A&&);  // { dg-error "" }
+
+int test6_134678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_134678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+one   sink_6_124678(               A&);
+two   sink_6_124678(const          A&);  // { dg-error "" }
+four  sink_6_124678(const volatile A&);
+six   sink_6_124678(const          A&&);  // { dg-error "" }
+seven sink_6_124678(volatile       A&&);  // { dg-error "" }
+eight sink_6_124678(const volatile A&&);  // { dg-error "" }
+
+int test6_124678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_124678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+one   sink_6_123678(               A&);
+two   sink_6_123678(const          A&);  // { dg-error "" }
+three sink_6_123678(volatile       A&);
+six   sink_6_123678(const          A&&);  // { dg-error "" }
+seven sink_6_123678(volatile       A&&);  // { dg-error "" }
+eight sink_6_123678(const volatile A&&);  // { dg-error "" }
+
+int test6_123678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_123678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+one   sink_6_123567(               A&);  // { dg-error "" }
+two   sink_6_123567(const          A&);  // { dg-error "" }
+three sink_6_123567(volatile       A&);  // { dg-error "" }
+five  sink_6_123567(               A&&);  // { dg-error "" }
+six   sink_6_123567(const          A&&);  // { dg-error "" }
+seven sink_6_123567(volatile       A&&);  // { dg-error "" }
+
+int test6_123567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_123567(cva);          // { dg-error "no match" }
+    sink_6_123567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_6_123467(               A&);  // { dg-error "" }
+two   sink_6_123467(const          A&);  // { dg-error "" }
+three sink_6_123467(volatile       A&);  // { dg-error "" }
+four  sink_6_123467(const volatile A&);  // { dg-error "" }
+six   sink_6_123467(const          A&&);  // { dg-error "" }
+seven sink_6_123467(volatile       A&&);  // { dg-error "" }
+
+int test6_123467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_123467(source());     // { dg-error "ambiguous" }
+    sink_6_123467(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_6_124567(               A&);  // { dg-error "" }
+two   sink_6_124567(const          A&);  // { dg-error "" }
+four  sink_6_124567(const volatile A&);  // { dg-error "" }
+five  sink_6_124567(               A&&);  // { dg-error "" }
+six   sink_6_124567(const          A&&);  // { dg-error "" }
+seven sink_6_124567(volatile       A&&);  // { dg-error "" }
+
+int test6_124567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_124567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+one   sink_6_134567(               A&);  // { dg-error "" }
+three sink_6_134567(volatile       A&);  // { dg-error "" }
+four  sink_6_134567(const volatile A&);  // { dg-error "" }
+five  sink_6_134567(               A&&);  // { dg-error "" }
+six   sink_6_134567(const          A&&);  // { dg-error "" }
+seven sink_6_134567(volatile       A&&);  // { dg-error "" }
+
+int test6_134567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_6_134567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+int main()
+{
+    return test6_235678() + test6_234678() + test6_234578() + test6_234568() +
+           test6_234567() + test6_134678() + test6_124678() + test6_123678() +
+           test6_123567();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv6p.C b/gcc/testsuite/g++.dg/cpp0x/rv6p.C
new file mode 100644
index 000000000000..a59958e37ef5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv6p.C
@@ -0,0 +1,695 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 6 at a time
+
+one   sink_6_123456(               A&);
+two   sink_6_123456(const          A&);
+three sink_6_123456(volatile       A&);
+four  sink_6_123456(const volatile A&);
+five  sink_6_123456(               A&&);
+six   sink_6_123456(const          A&&);
+
+int test6_123456()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123456(a))           == 1> t1;
+    sa<sizeof(sink_6_123456(ca))          == 2> t2;
+    sa<sizeof(sink_6_123456(va))          == 3> t3;
+    sa<sizeof(sink_6_123456(cva))         == 4> t4;
+    sa<sizeof(sink_6_123456(source()))    == 5> t5;
+    sa<sizeof(sink_6_123456(c_source()))  == 6> t6;
+    return 0;
+}
+
+one   sink_6_123457(               A&);
+two   sink_6_123457(const          A&);
+three sink_6_123457(volatile       A&);
+four  sink_6_123457(const volatile A&);
+five  sink_6_123457(               A&&);
+seven sink_6_123457(volatile       A&&);
+
+int test6_123457()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123457(a))           == 1> t1;
+    sa<sizeof(sink_6_123457(ca))          == 2> t2;
+    sa<sizeof(sink_6_123457(va))          == 3> t3;
+    sa<sizeof(sink_6_123457(cva))         == 4> t4;
+    sa<sizeof(sink_6_123457(source()))    == 5> t5;
+    sa<sizeof(sink_6_123457(c_source()))  == 2> t6;
+    sa<sizeof(sink_6_123457(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_6_123458(               A&);
+two   sink_6_123458(const          A&);
+three sink_6_123458(volatile       A&);
+four  sink_6_123458(const volatile A&);
+five  sink_6_123458(               A&&);
+eight sink_6_123458(const volatile A&&);
+
+int test6_123458()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123458(a))           == 1> t1;
+    sa<sizeof(sink_6_123458(ca))          == 2> t2;
+    sa<sizeof(sink_6_123458(va))          == 3> t3;
+    sa<sizeof(sink_6_123458(cva))         == 4> t4;
+    sa<sizeof(sink_6_123458(source()))    == 5> t5;
+    sa<sizeof(sink_6_123458(c_source()))  == 8> t6;
+    sa<sizeof(sink_6_123458(v_source()))  == 8> t7;
+    sa<sizeof(sink_6_123458(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_123467(               A&);
+two   sink_6_123467(const          A&);
+three sink_6_123467(volatile       A&);
+four  sink_6_123467(const volatile A&);
+six   sink_6_123467(const          A&&);
+seven sink_6_123467(volatile       A&&);
+
+int test6_123467()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123467(a))           == 1> t1;
+    sa<sizeof(sink_6_123467(ca))          == 2> t2;
+    sa<sizeof(sink_6_123467(va))          == 3> t3;
+    sa<sizeof(sink_6_123467(cva))         == 4> t4;
+    sa<sizeof(sink_6_123467(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_123467(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_6_123468(               A&);
+two   sink_6_123468(const          A&);
+three sink_6_123468(volatile       A&);
+four  sink_6_123468(const volatile A&);
+six   sink_6_123468(const          A&&);
+eight sink_6_123468(const volatile A&&);
+
+int test6_123468()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123468(a))           == 1> t1;
+    sa<sizeof(sink_6_123468(ca))          == 2> t2;
+    sa<sizeof(sink_6_123468(va))          == 3> t3;
+    sa<sizeof(sink_6_123468(cva))         == 4> t4;
+    sa<sizeof(sink_6_123468(source()))    == 6> t5;
+    sa<sizeof(sink_6_123468(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_123468(v_source()))  == 8> t7;
+    sa<sizeof(sink_6_123468(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_123478(               A&);
+two   sink_6_123478(const          A&);
+three sink_6_123478(volatile       A&);
+four  sink_6_123478(const volatile A&);
+seven sink_6_123478(volatile       A&&);
+eight sink_6_123478(const volatile A&&);
+
+int test6_123478()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123478(a))           == 1> t1;
+    sa<sizeof(sink_6_123478(ca))          == 2> t2;
+    sa<sizeof(sink_6_123478(va))          == 3> t3;
+    sa<sizeof(sink_6_123478(cva))         == 4> t4;
+    sa<sizeof(sink_6_123478(source()))    == 7> t5;
+    sa<sizeof(sink_6_123478(c_source()))  == 8> t6;
+    sa<sizeof(sink_6_123478(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_123478(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_123567(               A&);
+two   sink_6_123567(const          A&);
+three sink_6_123567(volatile       A&);
+five  sink_6_123567(               A&&);
+six   sink_6_123567(const          A&&);
+seven sink_6_123567(volatile       A&&);
+
+int test6_123567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123567(a))           == 1> t1;
+    sa<sizeof(sink_6_123567(ca))          == 2> t2;
+    sa<sizeof(sink_6_123567(va))          == 3> t3;
+    sa<sizeof(sink_6_123567(source()))    == 5> t5;
+    sa<sizeof(sink_6_123567(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_123567(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_6_123568(               A&);
+two   sink_6_123568(const          A&);
+three sink_6_123568(volatile       A&);
+five  sink_6_123568(               A&&);
+six   sink_6_123568(const          A&&);
+eight sink_6_123568(const volatile A&&);
+
+int test6_123568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123568(a))           == 1> t1;
+    sa<sizeof(sink_6_123568(ca))          == 2> t2;
+    sa<sizeof(sink_6_123568(va))          == 3> t3;
+    sa<sizeof(sink_6_123568(cva))         == 8> t4;
+    sa<sizeof(sink_6_123568(source()))    == 5> t5;
+    sa<sizeof(sink_6_123568(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_123568(v_source()))  == 8> t7;
+    sa<sizeof(sink_6_123568(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_123578(               A&);
+two   sink_6_123578(const          A&);
+three sink_6_123578(volatile       A&);
+five  sink_6_123578(               A&&);
+seven sink_6_123578(volatile       A&&);
+eight sink_6_123578(const volatile A&&);
+
+int test6_123578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123578(a))           == 1> t1;
+    sa<sizeof(sink_6_123578(ca))          == 2> t2;
+    sa<sizeof(sink_6_123578(va))          == 3> t3;
+    sa<sizeof(sink_6_123578(cva))         == 8> t4;
+    sa<sizeof(sink_6_123578(source()))    == 5> t5;
+    sa<sizeof(sink_6_123578(c_source()))  == 8> t6;
+    sa<sizeof(sink_6_123578(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_123578(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_123678(               A&);
+two   sink_6_123678(const          A&);
+three sink_6_123678(volatile       A&);
+six   sink_6_123678(const          A&&);
+seven sink_6_123678(volatile       A&&);
+eight sink_6_123678(const volatile A&&);
+
+int test6_123678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_123678(a))           == 1> t1;
+    sa<sizeof(sink_6_123678(ca))          == 2> t2;
+    sa<sizeof(sink_6_123678(va))          == 3> t3;
+    sa<sizeof(sink_6_123678(cva))         == 8> t4;
+    sa<sizeof(sink_6_123678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_123678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_123678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_124567(               A&);
+two   sink_6_124567(const          A&);
+four  sink_6_124567(const volatile A&);
+five  sink_6_124567(               A&&);
+six   sink_6_124567(const          A&&);
+seven sink_6_124567(volatile       A&&);
+
+int test6_124567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_124567(a))           == 1> t1;
+    sa<sizeof(sink_6_124567(ca))          == 2> t2;
+    sa<sizeof(sink_6_124567(va))          == 4> t3;
+    sa<sizeof(sink_6_124567(cva))         == 4> t4;
+    sa<sizeof(sink_6_124567(source()))    == 5> t5;
+    sa<sizeof(sink_6_124567(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_124567(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_6_124568(               A&);
+two   sink_6_124568(const          A&);
+four  sink_6_124568(const volatile A&);
+five  sink_6_124568(               A&&);
+six   sink_6_124568(const          A&&);
+eight sink_6_124568(const volatile A&&);
+
+int test6_124568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_124568(a))           == 1> t1;
+    sa<sizeof(sink_6_124568(ca))          == 2> t2;
+    sa<sizeof(sink_6_124568(va))          == 4> t3;
+    sa<sizeof(sink_6_124568(cva))         == 4> t4;
+    sa<sizeof(sink_6_124568(source()))    == 5> t5;
+    sa<sizeof(sink_6_124568(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_124568(v_source()))  == 8> t7;
+    sa<sizeof(sink_6_124568(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_124578(               A&);
+two   sink_6_124578(const          A&);
+four  sink_6_124578(const volatile A&);
+five  sink_6_124578(               A&&);
+seven sink_6_124578(volatile       A&&);
+eight sink_6_124578(const volatile A&&);
+
+int test6_124578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_124578(a))           == 1> t1;
+    sa<sizeof(sink_6_124578(ca))          == 2> t2;
+    sa<sizeof(sink_6_124578(va))          == 4> t3;
+    sa<sizeof(sink_6_124578(cva))         == 4> t4;
+    sa<sizeof(sink_6_124578(source()))    == 5> t5;
+    sa<sizeof(sink_6_124578(c_source()))  == 8> t6;
+    sa<sizeof(sink_6_124578(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_124578(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_124678(               A&);
+two   sink_6_124678(const          A&);
+four  sink_6_124678(const volatile A&);
+six   sink_6_124678(const          A&&);
+seven sink_6_124678(volatile       A&&);
+eight sink_6_124678(const volatile A&&);
+
+int test6_124678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_124678(a))           == 1> t1;
+    sa<sizeof(sink_6_124678(ca))          == 2> t2;
+    sa<sizeof(sink_6_124678(va))          == 4> t3;
+    sa<sizeof(sink_6_124678(cva))         == 4> t4;
+    sa<sizeof(sink_6_124678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_124678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_124678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_125678(               A&);
+two   sink_6_125678(const          A&);
+five  sink_6_125678(               A&&);
+six   sink_6_125678(const          A&&);
+seven sink_6_125678(volatile       A&&);
+eight sink_6_125678(const volatile A&&);
+
+int test6_125678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_125678(a))           == 1> t1;
+    sa<sizeof(sink_6_125678(ca))          == 2> t2;
+    sa<sizeof(sink_6_125678(va))          == 7> t3;
+    sa<sizeof(sink_6_125678(cva))         == 8> t4;
+    sa<sizeof(sink_6_125678(source()))    == 5> t5;
+    sa<sizeof(sink_6_125678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_125678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_125678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_134567(               A&);
+three sink_6_134567(volatile       A&);
+four  sink_6_134567(const volatile A&);
+five  sink_6_134567(               A&&);
+six   sink_6_134567(const          A&&);
+seven sink_6_134567(volatile       A&&);
+
+int test6_134567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_134567(a))           == 1> t1;
+    sa<sizeof(sink_6_134567(ca))          == 4> t2;
+    sa<sizeof(sink_6_134567(va))          == 3> t3;
+    sa<sizeof(sink_6_134567(cva))         == 4> t4;
+    sa<sizeof(sink_6_134567(source()))    == 5> t5;
+    sa<sizeof(sink_6_134567(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_134567(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_6_134568(               A&);
+three sink_6_134568(volatile       A&);
+four  sink_6_134568(const volatile A&);
+five  sink_6_134568(               A&&);
+six   sink_6_134568(const          A&&);
+eight sink_6_134568(const volatile A&&);
+
+int test6_134568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_134568(a))           == 1> t1;
+    sa<sizeof(sink_6_134568(ca))          == 4> t2;
+    sa<sizeof(sink_6_134568(va))          == 3> t3;
+    sa<sizeof(sink_6_134568(cva))         == 4> t4;
+    sa<sizeof(sink_6_134568(source()))    == 5> t5;
+    sa<sizeof(sink_6_134568(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_134568(v_source()))  == 8> t7;
+    sa<sizeof(sink_6_134568(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_134578(               A&);
+three sink_6_134578(volatile       A&);
+four  sink_6_134578(const volatile A&);
+five  sink_6_134578(               A&&);
+seven sink_6_134578(volatile       A&&);
+eight sink_6_134578(const volatile A&&);
+
+int test6_134578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_134578(a))           == 1> t1;
+    sa<sizeof(sink_6_134578(ca))          == 4> t2;
+    sa<sizeof(sink_6_134578(va))          == 3> t3;
+    sa<sizeof(sink_6_134578(cva))         == 4> t4;
+    sa<sizeof(sink_6_134578(source()))    == 5> t5;
+    sa<sizeof(sink_6_134578(c_source()))  == 8> t6;
+    sa<sizeof(sink_6_134578(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_134578(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_134678(               A&);
+three sink_6_134678(volatile       A&);
+four  sink_6_134678(const volatile A&);
+six   sink_6_134678(const          A&&);
+seven sink_6_134678(volatile       A&&);
+eight sink_6_134678(const volatile A&&);
+
+int test6_134678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_134678(a))           == 1> t1;
+    sa<sizeof(sink_6_134678(ca))          == 4> t2;
+    sa<sizeof(sink_6_134678(va))          == 3> t3;
+    sa<sizeof(sink_6_134678(cva))         == 4> t4;
+    sa<sizeof(sink_6_134678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_134678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_134678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_135678(               A&);
+three sink_6_135678(volatile       A&);
+five  sink_6_135678(               A&&);
+six   sink_6_135678(const          A&&);
+seven sink_6_135678(volatile       A&&);
+eight sink_6_135678(const volatile A&&);
+
+int test6_135678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_135678(a))           == 1> t1;
+    sa<sizeof(sink_6_135678(ca))          == 6> t2;
+    sa<sizeof(sink_6_135678(va))          == 3> t3;
+    sa<sizeof(sink_6_135678(cva))         == 8> t4;
+    sa<sizeof(sink_6_135678(source()))    == 5> t5;
+    sa<sizeof(sink_6_135678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_135678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_135678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_6_145678(               A&);
+four  sink_6_145678(const volatile A&);
+five  sink_6_145678(               A&&);
+six   sink_6_145678(const          A&&);
+seven sink_6_145678(volatile       A&&);
+eight sink_6_145678(const volatile A&&);
+
+int test6_145678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_145678(a))           == 1> t1;
+    sa<sizeof(sink_6_145678(ca))          == 4> t2;
+    sa<sizeof(sink_6_145678(va))          == 4> t3;
+    sa<sizeof(sink_6_145678(cva))         == 4> t4;
+    sa<sizeof(sink_6_145678(source()))    == 5> t5;
+    sa<sizeof(sink_6_145678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_145678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_145678(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_6_234567(const          A&);
+three sink_6_234567(volatile       A&);
+four  sink_6_234567(const volatile A&);
+five  sink_6_234567(               A&&);
+six   sink_6_234567(const          A&&);
+seven sink_6_234567(volatile       A&&);
+
+int test6_234567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_234567(ca))          == 2> t2;
+    sa<sizeof(sink_6_234567(va))          == 3> t3;
+    sa<sizeof(sink_6_234567(cva))         == 4> t4;
+    sa<sizeof(sink_6_234567(source()))    == 5> t5;
+    sa<sizeof(sink_6_234567(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_234567(v_source()))  == 7> t7;
+    return 0;
+}
+
+two   sink_6_234568(const          A&);
+three sink_6_234568(volatile       A&);
+four  sink_6_234568(const volatile A&);
+five  sink_6_234568(               A&&);
+six   sink_6_234568(const          A&&);
+eight sink_6_234568(const volatile A&&);
+
+int test6_234568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_234568(ca))          == 2> t2;
+    sa<sizeof(sink_6_234568(va))          == 3> t3;
+    sa<sizeof(sink_6_234568(cva))         == 4> t4;
+    sa<sizeof(sink_6_234568(source()))    == 5> t5;
+    sa<sizeof(sink_6_234568(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_234568(v_source()))  == 8> t7;
+    sa<sizeof(sink_6_234568(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_6_234578(const          A&);
+three sink_6_234578(volatile       A&);
+four  sink_6_234578(const volatile A&);
+five  sink_6_234578(               A&&);
+seven sink_6_234578(volatile       A&&);
+eight sink_6_234578(const volatile A&&);
+
+int test6_234578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_234578(ca))          == 2> t2;
+    sa<sizeof(sink_6_234578(va))          == 3> t3;
+    sa<sizeof(sink_6_234578(cva))         == 4> t4;
+    sa<sizeof(sink_6_234578(source()))    == 5> t5;
+    sa<sizeof(sink_6_234578(c_source()))  == 8> t6;
+    sa<sizeof(sink_6_234578(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_234578(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_6_234678(const          A&);
+three sink_6_234678(volatile       A&);
+four  sink_6_234678(const volatile A&);
+six   sink_6_234678(const          A&&);
+seven sink_6_234678(volatile       A&&);
+eight sink_6_234678(const volatile A&&);
+
+int test6_234678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_234678(ca))          == 2> t2;
+    sa<sizeof(sink_6_234678(va))          == 3> t3;
+    sa<sizeof(sink_6_234678(cva))         == 4> t4;
+    sa<sizeof(sink_6_234678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_234678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_234678(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_6_235678(const          A&);
+three sink_6_235678(volatile       A&);
+five  sink_6_235678(               A&&);
+six   sink_6_235678(const          A&&);
+seven sink_6_235678(volatile       A&&);
+eight sink_6_235678(const volatile A&&);
+
+int test6_235678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_235678(ca))          == 2> t2;
+    sa<sizeof(sink_6_235678(va))          == 3> t3;
+    sa<sizeof(sink_6_235678(cva))         == 8> t4;
+    sa<sizeof(sink_6_235678(source()))    == 5> t5;
+    sa<sizeof(sink_6_235678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_235678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_235678(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_6_245678(const          A&);
+four  sink_6_245678(const volatile A&);
+five  sink_6_245678(               A&&);
+six   sink_6_245678(const          A&&);
+seven sink_6_245678(volatile       A&&);
+eight sink_6_245678(const volatile A&&);
+
+int test6_245678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_245678(a))           == 2> t1;
+    sa<sizeof(sink_6_245678(ca))          == 2> t2;
+    sa<sizeof(sink_6_245678(va))          == 4> t3;
+    sa<sizeof(sink_6_245678(cva))         == 4> t4;
+    sa<sizeof(sink_6_245678(source()))    == 5> t5;
+    sa<sizeof(sink_6_245678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_245678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_245678(cv_source())) == 8> t8;
+    return 0;
+}
+
+three sink_6_345678(volatile       A&);
+four  sink_6_345678(const volatile A&);
+five  sink_6_345678(               A&&);
+six   sink_6_345678(const          A&&);
+seven sink_6_345678(volatile       A&&);
+eight sink_6_345678(const volatile A&&);
+
+int test6_345678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_6_345678(a))           == 3> t1;
+    sa<sizeof(sink_6_345678(ca))          == 4> t2;
+    sa<sizeof(sink_6_345678(va))          == 3> t3;
+    sa<sizeof(sink_6_345678(cva))         == 4> t4;
+    sa<sizeof(sink_6_345678(source()))    == 5> t5;
+    sa<sizeof(sink_6_345678(c_source()))  == 6> t6;
+    sa<sizeof(sink_6_345678(v_source()))  == 7> t7;
+    sa<sizeof(sink_6_345678(cv_source())) == 8> t8;
+    return 0;
+}
+
+int main()
+{
+    return test6_123456() + test6_123457() + test6_123458() + test6_123467() +
+           test6_123468() + test6_123478() + test6_123567() + test6_123568() +
+           test6_123578() + test6_123678() + test6_124567() + test6_124568() +
+           test6_124578() + test6_124678() + test6_125678() + test6_134567() +
+           test6_134568() + test6_134578() + test6_134678() + test6_135678() +
+           test6_145678() + test6_234567() + test6_234568() + test6_234578() +
+           test6_234678() + test6_235678() + test6_245678() + test6_345678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv7n.C b/gcc/testsuite/g++.dg/cpp0x/rv7n.C
new file mode 100644
index 000000000000..acd884bdde4c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv7n.C
@@ -0,0 +1,90 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 7 at a time
+
+one   sink_7_1234567(               A&);  // { dg-error "" }
+two   sink_7_1234567(const          A&);  // { dg-error "" }
+three sink_7_1234567(volatile       A&);  // { dg-error "" }
+four  sink_7_1234567(const volatile A&);  // { dg-error "" }
+five  sink_7_1234567(               A&&);  // { dg-error "" }
+six   sink_7_1234567(const          A&&);  // { dg-error "" }
+seven sink_7_1234567(volatile       A&&);  // { dg-error "" }
+
+int test7_1234567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_7_1234567(cv_source());  // { dg-error "no match" }
+    return 0;
+}
+
+two   sink_7_2345678(const          A&);  // { dg-error "" }
+three sink_7_2345678(volatile       A&);  // { dg-error "" }
+four  sink_7_2345678(const volatile A&);  // { dg-error "" }
+five  sink_7_2345678(               A&&);  // { dg-error "" }
+six   sink_7_2345678(const          A&&);  // { dg-error "" }
+seven sink_7_2345678(volatile       A&&);  // { dg-error "" }
+eight sink_7_2345678(const volatile A&&);  // { dg-error "" }
+
+int test7_2345678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_7_2345678(a);  // { dg-error "ambiguous" }
+    return 0;
+}
+
+one   sink_7_1234678(               A&);
+two   sink_7_1234678(const          A&);  // { dg-error "" }
+three sink_7_1234678(volatile       A&);
+four  sink_7_1234678(const volatile A&);
+six   sink_7_1234678(const          A&&);  // { dg-error "" }
+seven sink_7_1234678(volatile       A&&);  // { dg-error "" }
+eight sink_7_1234678(const volatile A&&);  // { dg-error "" }
+
+int test7_1234678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sink_7_1234678(source());  // { dg-error "ambiguous" }
+    return 0;
+}
+
+int main()
+{
+    return test7_2345678() + test7_1234678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv7p.C b/gcc/testsuite/g++.dg/cpp0x/rv7p.C
new file mode 100644
index 000000000000..d3e1474ff106
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv7p.C
@@ -0,0 +1,234 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 7 at a time
+
+one   sink_7_1234567(               A&);
+two   sink_7_1234567(const          A&);
+three sink_7_1234567(volatile       A&);
+four  sink_7_1234567(const volatile A&);
+five  sink_7_1234567(               A&&);
+six   sink_7_1234567(const          A&&);
+seven sink_7_1234567(volatile       A&&);
+
+int test7_1234567()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_7_1234567(a))           == 1> t1;
+    sa<sizeof(sink_7_1234567(ca))          == 2> t2;
+    sa<sizeof(sink_7_1234567(va))          == 3> t3;
+    sa<sizeof(sink_7_1234567(cva))         == 4> t4;
+    sa<sizeof(sink_7_1234567(source()))    == 5> t5;
+    sa<sizeof(sink_7_1234567(c_source()))  == 6> t6;
+    sa<sizeof(sink_7_1234567(v_source()))  == 7> t7;
+    return 0;
+}
+
+one   sink_7_1234568(               A&);
+two   sink_7_1234568(const          A&);
+three sink_7_1234568(volatile       A&);
+four  sink_7_1234568(const volatile A&);
+five  sink_7_1234568(               A&&);
+six   sink_7_1234568(const          A&&);
+eight sink_7_1234568(const volatile A&&);
+
+int test7_1234568()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_7_1234568(a))           == 1> t1;
+    sa<sizeof(sink_7_1234568(ca))          == 2> t2;
+    sa<sizeof(sink_7_1234568(va))          == 3> t3;
+    sa<sizeof(sink_7_1234568(cva))         == 4> t4;
+    sa<sizeof(sink_7_1234568(source()))    == 5> t5;
+    sa<sizeof(sink_7_1234568(c_source()))  == 6> t6;
+    sa<sizeof(sink_7_1234568(v_source()))  == 8> t7;
+    sa<sizeof(sink_7_1234568(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_7_1234578(               A&);
+two   sink_7_1234578(const          A&);
+three sink_7_1234578(volatile       A&);
+four  sink_7_1234578(const volatile A&);
+five  sink_7_1234578(               A&&);
+seven sink_7_1234578(volatile       A&&);
+eight sink_7_1234578(const volatile A&&);
+
+int test7_1234578()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_7_1234578(a))           == 1> t1;
+    sa<sizeof(sink_7_1234578(ca))          == 2> t2;
+    sa<sizeof(sink_7_1234578(va))          == 3> t3;
+    sa<sizeof(sink_7_1234578(cva))         == 4> t4;
+    sa<sizeof(sink_7_1234578(source()))    == 5> t5;
+    sa<sizeof(sink_7_1234578(c_source()))  == 8> t6;
+    sa<sizeof(sink_7_1234578(v_source()))  == 7> t7;
+    sa<sizeof(sink_7_1234578(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_7_1234678(               A&);
+two   sink_7_1234678(const          A&);
+three sink_7_1234678(volatile       A&);
+four  sink_7_1234678(const volatile A&);
+six   sink_7_1234678(const          A&&);
+seven sink_7_1234678(volatile       A&&);
+eight sink_7_1234678(const volatile A&&);
+
+int test7_1234678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_7_1234678(a))           == 1> t1;
+    sa<sizeof(sink_7_1234678(ca))          == 2> t2;
+    sa<sizeof(sink_7_1234678(va))          == 3> t3;
+    sa<sizeof(sink_7_1234678(cva))         == 4> t4;
+    sa<sizeof(sink_7_1234678(c_source()))  == 6> t6;
+    sa<sizeof(sink_7_1234678(v_source()))  == 7> t7;
+    sa<sizeof(sink_7_1234678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_7_1235678(               A&);
+two   sink_7_1235678(const          A&);
+three sink_7_1235678(volatile       A&);
+five  sink_7_1235678(               A&&);
+six   sink_7_1235678(const          A&&);
+seven sink_7_1235678(volatile       A&&);
+eight sink_7_1235678(const volatile A&&);
+
+int test7_1235678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_7_1235678(a))           == 1> t1;
+    sa<sizeof(sink_7_1235678(ca))          == 2> t2;
+    sa<sizeof(sink_7_1235678(va))          == 3> t3;
+    sa<sizeof(sink_7_1235678(cva))         == 8> t4;
+    sa<sizeof(sink_7_1235678(source()))    == 5> t5;
+    sa<sizeof(sink_7_1235678(c_source()))  == 6> t6;
+    sa<sizeof(sink_7_1235678(v_source()))  == 7> t7;
+    sa<sizeof(sink_7_1235678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_7_1245678(               A&);
+two   sink_7_1245678(const          A&);
+four  sink_7_1245678(const volatile A&);
+five  sink_7_1245678(               A&&);
+six   sink_7_1245678(const          A&&);
+seven sink_7_1245678(volatile       A&&);
+eight sink_7_1245678(const volatile A&&);
+
+int test7_1245678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_7_1245678(a))           == 1> t1;
+    sa<sizeof(sink_7_1245678(ca))          == 2> t2;
+    sa<sizeof(sink_7_1245678(va))          == 4> t3;
+    sa<sizeof(sink_7_1245678(cva))         == 4> t4;
+    sa<sizeof(sink_7_1245678(source()))    == 5> t5;
+    sa<sizeof(sink_7_1245678(c_source()))  == 6> t6;
+    sa<sizeof(sink_7_1245678(v_source()))  == 7> t7;
+    sa<sizeof(sink_7_1245678(cv_source())) == 8> t8;
+    return 0;
+}
+
+one   sink_7_1345678(               A&);
+three sink_7_1345678(volatile       A&);
+four  sink_7_1345678(const volatile A&);
+five  sink_7_1345678(               A&&);
+six   sink_7_1345678(const          A&&);
+seven sink_7_1345678(volatile       A&&);
+eight sink_7_1345678(const volatile A&&);
+
+int test7_1345678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_7_1345678(a))           == 1> t1;
+    sa<sizeof(sink_7_1345678(ca))          == 4> t2;
+    sa<sizeof(sink_7_1345678(va))          == 3> t3;
+    sa<sizeof(sink_7_1345678(cva))         == 4> t4;
+    sa<sizeof(sink_7_1345678(source()))    == 5> t5;
+    sa<sizeof(sink_7_1345678(c_source()))  == 6> t6;
+    sa<sizeof(sink_7_1345678(v_source()))  == 7> t7;
+    sa<sizeof(sink_7_1345678(cv_source())) == 8> t8;
+    return 0;
+}
+
+two   sink_7_2345678(const          A&);
+three sink_7_2345678(volatile       A&);
+four  sink_7_2345678(const volatile A&);
+five  sink_7_2345678(               A&&);
+six   sink_7_2345678(const          A&&);
+seven sink_7_2345678(volatile       A&&);
+eight sink_7_2345678(const volatile A&&);
+
+int test7_2345678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_7_2345678(ca))          == 2> t2;
+    sa<sizeof(sink_7_2345678(va))          == 3> t3;
+    sa<sizeof(sink_7_2345678(cva))         == 4> t4;
+    sa<sizeof(sink_7_2345678(source()))    == 5> t5;
+    sa<sizeof(sink_7_2345678(c_source()))  == 6> t6;
+    sa<sizeof(sink_7_2345678(v_source()))  == 7> t7;
+    sa<sizeof(sink_7_2345678(cv_source())) == 8> t8;
+    return 0;
+}
+
+int main()
+{
+    return test7_1234567() + test7_1234568() + test7_1234578() + test7_1234678() +
+           test7_1235678() + test7_1245678() + test7_1345678() + test7_2345678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv8p.C b/gcc/testsuite/g++.dg/cpp0x/rv8p.C
new file mode 100644
index 000000000000..95a72d5105b7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv8p.C
@@ -0,0 +1,62 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test overlaod resolution among referece types
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+struct three {char x[3];};
+struct four  {char x[4];};
+struct five  {char x[5];};
+struct six   {char x[6];};
+struct seven {char x[7];};
+struct eight {char x[8];};
+
+struct A
+{
+    A();
+    A(const volatile A&&);
+};
+
+               A    source();
+const          A  c_source();
+      volatile A  v_source();
+const volatile A cv_source();
+
+// 8 at a time
+
+one   sink_8_12345678(               A&);
+two   sink_8_12345678(const          A&);
+three sink_8_12345678(volatile       A&);
+four  sink_8_12345678(const volatile A&);
+five  sink_8_12345678(               A&&);
+six   sink_8_12345678(const          A&&);
+seven sink_8_12345678(volatile       A&&);
+eight sink_8_12345678(const volatile A&&);
+
+int test8_12345678()
+{
+                   A a;
+    const          A ca = a;
+          volatile A va;
+    const volatile A cva = a;
+    sa<sizeof(sink_8_12345678(a))           == 1> t1;
+    sa<sizeof(sink_8_12345678(ca))          == 2> t2;
+    sa<sizeof(sink_8_12345678(va))          == 3> t3;
+    sa<sizeof(sink_8_12345678(cva))         == 4> t4;
+    sa<sizeof(sink_8_12345678(source()))    == 5> t5;
+    sa<sizeof(sink_8_12345678(c_source()))  == 6> t6;
+    sa<sizeof(sink_8_12345678(v_source()))  == 7> t7;
+    sa<sizeof(sink_8_12345678(cv_source())) == 8> t8;
+    return 0;
+}
+
+int main()
+{
+    return test8_12345678();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rvo.C b/gcc/testsuite/g++.dg/cpp0x/rvo.C
new file mode 100644
index 000000000000..b52ce7495db3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rvo.C
@@ -0,0 +1,25 @@
+// { dg-do "run" }
+// { dg-options "-std=c++0x" }
+// Contributed by Sylvain Pion
+static int rvalue_constructions = 0;
+
+struct A {
+  A ()         { }
+  A (const A&) { }
+  A (A&&)      { ++rvalue_constructions; }
+  ~A ()        { }
+};
+
+A f() {  return A(); }
+
+extern "C" {
+  void abort(void);
+}
+
+int main()
+{
+  A c = f();
+
+  if (rvalue_constructions != 0)
+    abort();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/temp-constructor-bug.C b/gcc/testsuite/g++.dg/cpp0x/temp-constructor-bug.C
new file mode 100644
index 000000000000..a06720702050
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/temp-constructor-bug.C
@@ -0,0 +1,15 @@
+// { dg-options "--std=c++0x" }
+
+struct S { };
+
+struct T
+{
+  S s;
+};
+
+void f(T const &);
+
+void g()
+{
+  f((T){S()});
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C b/gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C
new file mode 100644
index 000000000000..5314b24d1e00
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/temp-va-arg-bug.C
@@ -0,0 +1,10 @@
+// { dg-options "--std=c++0x" }
+#include <stdarg.h>
+
+struct S { };
+void f(S const &);
+
+void g(va_list args)
+{
+  f(va_arg(args, S));
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/template_deduction.C b/gcc/testsuite/g++.dg/cpp0x/template_deduction.C
new file mode 100644
index 000000000000..ee48fb305d03
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/template_deduction.C
@@ -0,0 +1,68 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test the "Augmented" template argument deduction when binding an lvalue to an rvalue reference.
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+template <class T, T v>
+struct integral_constant
+{
+	static const T                  value = v;
+	typedef T                       value_type;
+	typedef integral_constant<T, v> type;
+};
+
+typedef integral_constant<bool, true>  true_type;
+typedef integral_constant<bool, false> false_type;
+
+template <class T> struct is_lvalue_reference     : public integral_constant<bool, false> {};
+template <class T> struct is_lvalue_reference<T&> : public integral_constant<bool, true> {};
+
+template <class T> struct is_rvalue_reference      : public integral_constant<bool, false> {};
+template <class T> struct is_rvalue_reference<T&&> : public integral_constant<bool, true> {};
+
+template <bool is_lvalue_ref, bool is_rvalue_ref, class T>
+void
+test1(T&&)
+{
+    sa<is_lvalue_reference<T&&>::value == is_lvalue_ref> t1;
+    sa<is_rvalue_reference<T&&>::value == is_rvalue_ref> t2;
+}
+
+template <bool is_lvalue_ref, bool is_rvalue_ref, class T>
+void
+test2(const T&&)
+{
+    sa<is_lvalue_reference<const T&&>::value == is_lvalue_ref> t1;
+    sa<is_rvalue_reference<const T&&>::value == is_rvalue_ref> t2;
+}
+
+template <bool is_lvalue_ref, bool is_rvalue_ref, class T>
+void
+test3(T*&&)
+{
+    sa<is_lvalue_reference<T*&&>::value == is_lvalue_ref> t1;
+    sa<is_rvalue_reference<T*&&>::value == is_rvalue_ref> t2;
+}
+
+struct A {};
+
+A a;
+
+A source() {return A();}
+A* sourcep() {return 0;}
+
+int main()
+{
+    test1<true, false>(a);
+    test1<false, true>(source());
+    test2<false, true>(a);
+    test2<false, true>(source());
+    test3<false, true>(&a);
+    test3<false, true>(sourcep());
+    return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/unnamed_refs.C b/gcc/testsuite/g++.dg/cpp0x/unnamed_refs.C
new file mode 100644
index 000000000000..06311856d69b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/unnamed_refs.C
@@ -0,0 +1,30 @@
+// I, Howard Hinnant, hereby place this code in the public domain.
+
+// Test: Unamed rvalue references are treated as lvalues.
+
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <bool> struct sa;
+template <> struct sa<true> {};
+
+struct one   {char x[1];};
+struct two   {char x[2];};
+
+struct A {};
+
+one foo(const A&) {return one();}
+two foo(A&&)      {return two();}
+
+A&& source() {static A a; return a;}
+
+int test1()
+{
+    sa<sizeof(foo(source())) == 2> t1;
+    return 0;
+}
+
+int main()
+{
+    return test1();
+}
diff --git a/gcc/testsuite/g++.dg/init/copy7.C b/gcc/testsuite/g++.dg/init/copy7.C
index 0f604371504b..8c23c546d5d6 100644
--- a/gcc/testsuite/g++.dg/init/copy7.C
+++ b/gcc/testsuite/g++.dg/init/copy7.C
@@ -1,3 +1,4 @@
+// { dg-options "-std=c++98" }
 // PR c++/12226
 
 class foo {
diff --git a/gcc/testsuite/g++.dg/overload/arg1.C b/gcc/testsuite/g++.dg/overload/arg1.C
index 6ac6a7e5c298..ba0f6f0781e6 100644
--- a/gcc/testsuite/g++.dg/overload/arg1.C
+++ b/gcc/testsuite/g++.dg/overload/arg1.C
@@ -1,3 +1,4 @@
+// { dg-options "-std=c++98" }
 // { dg-do compile }
 
 // Copyright (C) 2004 Free Software Foundation, Inc.
diff --git a/gcc/testsuite/g++.dg/overload/arg4.C b/gcc/testsuite/g++.dg/overload/arg4.C
index 34aa62506836..1461928958f2 100644
--- a/gcc/testsuite/g++.dg/overload/arg4.C
+++ b/gcc/testsuite/g++.dg/overload/arg4.C
@@ -1,3 +1,4 @@
+// { dg-options "-std=c++98" }
 // { dg-do compile }
 
 // Copyright (C) 2004 Free Software Foundation, Inc.
-- 
GitLab