[Bug c++/43393] New: integral promotion of long bit-fields broken in g++ 4.4.0

2010-03-16 Thread vsoni at tilera dot com
The integral promotion behavior of long bit-fields has changed with g++ 4.4.0
on x86_64-linux, and appears broken.  Consider:

#include 
#define T unsigned long
int main()
{
  struct { T f : 33; } s = { 1UL << 32 };
  printf("%lx %lx %lx\n", (T)s.f, (T)(s.f << 1), (T)((s.f << 1) >> 1));

  struct { T f : 16; } t = { 1UL << 15 };
  printf("%lx %lx %lx\n", (T)t.f, (T)(t.f << 17), (T)((t.f << 17) >> 17));

  return 0;
}

In C++, the expected output is (rationale below):

1 2 1
8000 1 8000

The actual output is:

$ g++44 -Wall -pedantic x.c; ./a.out
1 2 1
8000 0 0

Note that 4.1.2 matches the expected output (more recent releases may also
match, but I don't have one handy):

$ g++ -Wall -pedantic x.c; ./a.out
1 2 1
8000 1 8000

$ g++44 -v
Using built-in specs.
Target: x86_64-redhat-linux6E
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla
--enable-bootstrap --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-languages=c,c++,fortran
--disable-libgcj
--with-mpfr=/builddir/build/BUILD/gcc-4.4.0-20090514/obj-x86_64-redhat-linux6E/mpfr-install/
--with-ppl=/builddir/build/BUILD/gcc-4.4.0-20090514/obj-x86_64-redhat-linux6E/ppl-install
--with-cloog=/builddir/build/BUILD/gcc-4.4.0-20090514/obj-x86_64-redhat-linux6E/cloog-install
--with-tune=generic --with-arch_32=i586 --build=x86_64-redhat-linux6E
Thread model: posix
gcc version 4.4.0 20090514 (Red Hat 4.4.0-6) (GCC) 

$ g++ -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk
--disable-dssi --enable-plugin
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic
--host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)


Rationale for expected output:

In C++ the number of bits in bit-field is not part of its type [1][2]; so in
the given example, the bit-field expressions s.f and t.f are of type long. 
Since long is larger than int and unsigned int, no integral promotions apply
[3], so the expected output is:

1 2 1
8000 1 8000

[1] ISO/IEC 14882-1998 [class.bit] The bit-field attribute is not part of the
type of the class member.

[2] http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#303

[3] ISO/IEC 14882-1998 [conv.prom] An rvalue for an integral bit-field can be
converted to an rvalue of type int if int can represent all the values of the
bit-field; otherwise, it can be converted to unsigned int if unsigned int can
represent all the values of the bit-field.  If the bit-field is larger yet, no
integral promotion applies to it.  If the bit-field has an enumerated type, it
is treated as any other value of that type for promotion purposes.


-- 
   Summary: integral promotion of long bit-fields broken in g++
4.4.0
   Product: gcc
   Version: 4.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
    AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: vsoni at tilera dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43393



[Bug c++/43393] integral promotion of long bit-fields broken in g++ 4.4.0

2010-03-16 Thread vsoni at tilera dot com


--- Comment #1 from vsoni at tilera dot com  2010-03-16 17:55 ---
Created an attachment (id=20118)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=20118&action=view)
preprocessed test


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43393



[Bug c++/43393] integral promotion of long bit-fields broken in g++ 4.4.0

2010-03-17 Thread vsoni at tilera dot com


--- Comment #3 from vsoni at tilera dot com  2010-03-17 19:33 ---
(In reply to comment #2)
> 
> I read that t.f promotes to int.  And that is exactly what the C++ frontend
> does:

That's plausible, but the standard, especially it's intent, is unclear I think.

I see three plausible interpretations:

A) int can represent all values of a long:16 bit-field, AND a long:16 bit-field
is not larger than int (if "larger" is interpreted with respect to the number
of bits in the bit-field representation, i.e. 16 bits).  So it is converted to
int.

B) int can represent all values of a long:16 bit-field, BUT a long:16 bit-field
is larger than int and unsigned int (if "larger" is interpreted with respect to
the size of the declared type of the bit-field, i.e. long).  So two clauses of
[3] apply, and the question is order of precedence:

  B1) The clause concerning int-representable values takes precedence, so it is
converted to int.

  B2) The clause concerning the size of the bit-field takes precedence, so no
integer promotions apply, and it remains long.

I agree that [A] seems to be the "simplest" interpretation in some sense, and
perhaps it's the correct one, but I can't reconcile this with the following: 
It seems to me the programmer's intent when declaring a bit-field of type
long:N, is to treat the value as type long, independent of N.  It also seems to
me that's the intent of the standard when it states that the number of bits in
a bit-field is not part of its type; perhaps the intent is something else?

FWIW, I searched but did not find a discussion of rationale, or a conclusive
example, in the supplementary notes of the C++ Standards Committee.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43393



[Bug c++/43393] integral promotion of long bit-fields broken in gcc 4.4.0?

2010-03-24 Thread vsoni at tilera dot com


--- Comment #4 from vsoni at tilera dot com  2010-03-25 00:21 ---
(In reply to comment #2)

> I read that t.f promotes to int.  

I concede to this interpretation for C++.

Note that the behavior for C/C99 also changed:

$ gcc-4.1.2 -std=c99 -Wall -pedantic x.c; ./a.out
x.c: In function ‘main’:
x.c:5: warning: type of bit-field ‘f’ is a GCC extension
x.c:8: warning: type of bit-field ‘f’ is a GCC extension
1 2 0
8000 0 0

$ gcc-4.4.0 -std=c99 -Wall -pedantic x.c; ./a.out
x.c: In function ‘main’:
x.c:5: warning: type of bit-field ‘f’ is a GCC extension
x.c:8: warning: type of bit-field ‘f’ is a GCC extension
1 0 0
8000 0 0

So apparently s.f doesn't promote to long anymore in C99.  Is this change in
behavior also intentional and correct?


-- 

vsoni at tilera dot com changed:

   What|Removed |Added

Summary|integral promotion of long  |integral promotion of long
   |bit-fields broken in g++|bit-fields broken in gcc
   |4.4.0   |4.4.0?


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43393