The code for recognizing problems with binding a glvalue to a reference was using real_lvalue_p, which returns 0 for xvalues, so the code that used that to handle bitfields wasn't handling a bitfield member of an xvalue. Fixed by using lvalue_kind instead.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit be097879a53ff700b0b220671e52ab671ab4ddce Author: Jason Merrill <ja...@redhat.com> Date: Fri Jul 22 13:51:50 2016 -0400 PR c++/71576 - bitfield and rvalue reference * call.c (convert_like_real): Use is_bitfield_expr_with_lowered_type. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 061e708..835b02a 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6771,7 +6771,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, expr, ref_type); return error_mark_node; } - if (lvalue & clk_bitfield) + if (is_bitfield_expr_with_lowered_type (expr)) { expr = convert_bitfield_to_declared_type (expr); expr = fold_convert (type, expr); diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-bitfield3.C b/gcc/testsuite/g++.dg/cpp0x/rv-bitfield3.C new file mode 100644 index 0000000..9d2d872 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/rv-bitfield3.C @@ -0,0 +1,14 @@ +// PR c++/71576 +// { dg-do compile { target c++11 } } + +template < typename T > T && foo (); + +struct A +{ + int i:5; +}; + +void foo () +{ + int &&j = foo < A > ().i; +}