Bug 45253

Summary: [c++0x] make_pair / cannot bind bitfield to unsigned&.
Product: gcc Reporter: Pawel Sikora <pawel_sikora>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Severity: normal CC: gcc-bugs, jason
Priority: P3    
Version: 4.5.1   
Target Milestone: ---   
Host: x86_64-gnu-linux Target: x86_64-gnu-linux
Build: x86_64-gnu-linux Known to work:
Known to fail: Last reconfirmed:

Description Pawel Sikora 2010-08-11 04:45:32 UTC
#include <utility>
struct S { unsigned addr : 31; };
struct X { static S s; };
int main() { std::make_pair( X::s.addr, true ); }

$ g++ -c t.cpp -std=c++0x                 
t.cpp: In function 'int main()':
t.cpp:4:46: error: cannot bind bitfield 'X::s.S::addr' to 'unsigned int&'

comeau online accepts this code.
Comment 1 Paolo Carlini 2010-08-11 07:06:13 UTC
Indeed, the library side of this is rather straightforward, we are already implementing the FCD correctly (I also checked there no DRs or NBCs open):

    template<class _T1, class _T2>
    inline pair<typename __decay_and_strip<_T1>::__type,
		typename __decay_and_strip<_T2>::__type>
    make_pair(_T1&& __x, _T2&& __y)

thus, if something is wrong isn't the GNU library. CCing Jason in case he can spot something about the C++ front-end...
Comment 2 Jason Merrill 2010-08-11 13:06:51 UTC
This result, while unfortunate, is not a bug; template argument deduction only uses the type and lvalueness of the function argument (unsigned, lvalue) and therefore deduces the type of __x to be unsigned&.  But an reference cannot bind to a bitfield, so the call is ill-formed.

You can work around this issue by using the unary + to make the argument an rvalue:

std::make_pair ( + X::s.addr, true );