[Bug c++/84516] New: bitfield temporaries > 32-bits have wrong type

2018-02-22 Thread gnu at mllr dot cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84516

Bug ID: 84516
   Summary: bitfield temporaries > 32-bits have wrong type
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gnu at mllr dot cc
  Target Milestone: ---

(Disclaimer: I'm not a compiler guy, so I may accidentally use the wrong
terminology)

Example: https://godbolt.org/g/brhTMw


#include 
struct A {
long x : 32;
long y : 33;
};
int main() {
A a;
std::cout << a.x;  // OK
std::cout << a.y;  // OK
std::cout << +a.x;  // OK
std::cout << +a.y;  // BREAKS on gcc
}

The problem is the last line. The type of the expression `+a.y` is 'long
int:33', which is not a type that operator<<() has an overload for. The type of
the expression `a.y` is 'long int' and so op<<() has an overload and works.

This issue seems to be affected by

(a) The size of the bit field; <= 32 bits works, > 32 bits breaks.
(b) Whether the bitfield is used in an expression producing a temporary;
>32-bit size AND a temporary breaks, <= 32-bit size and an lvalue works.

I confirmed this behavior on x86-64 gcc trunk using godbolt.org. (link again:
https://godbolt.org/g/brhTMw)

[Bug c++/84516] bitfield temporaries > 32-bits have wrong type

2018-02-22 Thread gnu at mllr dot cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84516

--- Comment #1 from Greg Miller  ---
The issue is not related to iostream. So, here's perhaps a simpler reproduction
example that may focus more on the issue at hand.

Link: https://godbolt.org/g/vA2rPN

struct A {
long x : 32;
long y : 33;
};

void F(int) {}
void F(long) {}
template 
void F(T) = delete;

int main() {
A a;
F(a.x);   // Calls F(long)
F(+a.x);  // Calls F(int)
F(a.y);   // Calls F(long)
F(+a.y);  // error: use of deleted function 'void F(T) [with T = long
int:33]'
}

Here we can see that the type of the expression `+a.y` is `long int:33`, which
I suspect is a problem. I think the type of that expression should be `long
int`.