Bug 15250 - [3.4/4.0 Regression] Option -mms-bitfields support on GCC 3.4 is not conformant to MS layout
Summary: [3.4/4.0 Regression] Option -mms-bitfields support on GCC 3.4 is not conforma...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.4.0
: P2 critical
Target Milestone: 3.4.1
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2004-05-02 17:41 UTC by Pascal Obry
Modified: 2004-09-13 14:15 UTC (History)
3 users (show)

See Also:
Host: pentium-mingw32msv
Target:
Build: pentium-mingw32msv
Known to work:
Known to fail:
Last reconfirmed: 2004-05-26 11:39:53


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pascal Obry 2004-05-02 17:41:55 UTC
I have used for a long time the MinGW compiler for the -mms-bitfields support 
without trouble. GCC 3.4 has support for this option too, but it seems to not 
be compatible with the previous version and worst than that it is not 
compatible with the way Microsft layout is done.

To reproduce you can use an old test case from Donn Terry. Here is a copy of 
this test.

-----------------TEST CASE bittest.h --------------------------------------
struct a_type {
   int a;
   unsigned char b;
   unsigned c:7;
   int d;
   unsigned e:3;
   unsigned f:9;
   unsigned char g:7;
   int h;
   unsigned int i:6;
   unsigned int :0;
   unsigned int j:6;
} NATIVE ;

struct b_type {
   int a;
   unsigned char b;
   unsigned int c:7;
   int d;
   unsigned int e:3;
   unsigned int f:9;
   unsigned char g:7;
   int h;
   unsigned char i:6;
   unsigned char :0;
   unsigned char j:6;

} NATIVE ;

struct c_type {
   int a;
   unsigned char b;
   unsigned short c:7;
   int d;
   unsigned short e:3;
   unsigned short f:9;
   unsigned char g:7;
   short h;
   unsigned short i:6;
   unsigned short :0;
   unsigned short j:6;
} NATIVE ;

struct d_type {
   int a:3;
   int b:4;
   int c:4;
   int d:6;
   int e:5;
   int f:5;
   int g:5;
} NATIVE ;

/* Bitfields of size 0 have some truly odd behaviors. */

struct e_type {   /* should be size 2! */
   char a;
   int :0;        /* ignored; prior field is not a bitfield. */
   char b;
};

struct f_type {   /* should be size 8! */
   char a:8;
   int :0;	  /* not ignored; prior field IS a bitfield, causes struct
		     alignment as well. */
   char b;
};

struct g_type {   /* should be size 2! */
   char a:8;
   char :0;
   int  :0;	  /* Ignored; prior field is zero size bitfield. */
   char b;
};

struct h_type {   /* should be size 3! */
   short a:3;
   char  b;
};

#ifdef _MSC_VER
#define LONGLONG __int64
#else
#define LONGLONG long long
#endif

union i_type {   /* should be size 2! */
   LONGLONG a:3;
   char  b;
};
-----------------TEST CASE bittest_nat.c --------------------------------------
#define NATIVE   /* as nothing */
#include "bittest.h"
#include <stddef.h>
#define poffset(a,b) printf("   %s: %d\n", #b, offsetof(struct a,b));

struct a_type a;
struct b_type b;
struct c_type c;
struct d_type d;
struct e_type e;
struct f_type f;
struct g_type g;
struct h_type h;
union i_type i;

int a_offsets[]={offsetof(struct a_type,b),
             offsetof(struct a_type,d),
             offsetof(struct a_type,h),
	     sizeof(struct a_type)};

int b_offsets[]={offsetof(struct b_type,b),
             offsetof(struct b_type,d),
             offsetof(struct b_type,h),
	     sizeof(struct b_type)};

int c_offsets[]={offsetof(struct c_type,b),
             offsetof(struct c_type,d),
             offsetof(struct c_type,h),
	     sizeof(struct c_type)};

int d_size = sizeof(struct d_type);
int e_size = sizeof(struct e_type);
int f_size = sizeof(struct f_type);
int g_size = sizeof(struct g_type);
int h_size = sizeof(struct h_type);
int i_size = sizeof(union i_type);

main()
{

    a.a=1;
    a.b=2;
    a.c=3;
    a.d=4;
    a.e=5;
    a.f=6;
    a.g=7;
    a.h=8;
    a.i=9;
    a.j=10;

    b.a=1;
    b.b=2;
    b.c=3;
    b.d=4;
    b.e=5;
    b.f=6;
    b.g=7;
    b.h=8;
    b.i=9;
    b.j=10;

    c.a=1;
    c.b=2;
    c.c=3;
    c.d=4;
    c.e=5;
    c.f=6;
    c.g=7;
    c.h=8;
    c.i=9;
    c.j=10;

    d.a=1;
    d.b=2;
    d.c=3;
    d.d=4;
    d.e=5;
    d.f=6;
    d.g=7;

    e.a=1;
    e.b=2;

    f.a=1;
    f.b=2;

    g.a=1;
    g.b=2;

    h.a=1;
    h.b=2;

    i.a=1;
    i.b=2;

    check_results();
}
-----------------TEST CASE bittest_gcc.c --------------------------------------
#define NATIVE 
//#define NATIVE __attribute__((__native_struct__))
#include "bittest.h"
#include <stddef.h>

#define check(s,f,v) if (s.f != v) { \
        printf(#s"."#f " was %d not " #v "\n", s.f); exit_code = 1;}

#define ckoff(a) for (ii=0; ii<3; ii++) { \
		if (a##_offsets[ii] != my_##a##_offsets[ii]) {\
		    printf(#a" offset field %d did not match: nat: %d v gcc: %
d\n", \
			ii, a##_offsets[ii], my_##a##_offsets[ii]); \
			exit_code = 1; } }

#define cksize(a) if (a##_size != my_##a##_size) { \
		    printf(#a" size did not match: nat %d v gcc %d\n", \
		       a##_size, my_##a##_size); \
		       exit_code = 1; } 

extern int a_offsets[];
extern int b_offsets[];
extern int c_offsets[];

int my_a_offsets[]={offsetof(struct a_type,b),
             offsetof(struct a_type,d),
             offsetof(struct a_type,h),
	     sizeof(struct a_type)};

int my_b_offsets[]={offsetof(struct b_type,b),
             offsetof(struct b_type,d),
             offsetof(struct b_type,h),
	     sizeof(struct b_type)};

int my_c_offsets[]={offsetof(struct c_type,b),
             offsetof(struct c_type,d),
             offsetof(struct c_type,h),
	     sizeof(struct c_type)};

int my_d_size = sizeof(struct d_type);
int my_e_size = sizeof(struct e_type);
int my_f_size = sizeof(struct f_type);
int my_g_size = sizeof(struct g_type);
int my_h_size = sizeof(struct h_type);
int my_i_size = sizeof(union i_type);

extern int d_size;
extern int e_size;
extern int f_size;
extern int g_size;
extern int h_size;
extern int i_size;

extern struct a_type a;
extern struct b_type b;
extern struct c_type c;
extern struct d_type d;
extern struct e_type e;
extern struct f_type f;
extern struct g_type g;
extern struct h_type h;
extern union i_type i;

check_results()
{
    int ii;
    int exit_code = 0;

    ckoff(a);
    ckoff(b);
    ckoff(c);

    cksize(d);
    cksize(e);
    cksize(f);
    cksize(g);
    cksize(h);
    cksize(i);

    check(a,a,1);
    check(a,b,2);
    check(a,c,3);
    check(a,d,4);
    check(a,e,5);
    check(a,f,6);
    check(a,g,7);
    check(a,h,8);
    check(a,i,9);
    check(a,j,10);

    check(b,a,1);
    check(b,b,2);
    check(b,c,3);
    check(b,d,4);
    check(b,e,5);
    check(b,f,6);
    check(b,g,7);
    check(b,h,8);
    check(b,i,9);
    check(b,j,10);

    check(c,a,1);
    check(c,b,2);
    check(c,c,3);
    check(c,d,4);
    check(c,e,5);
    check(c,f,6);
    check(c,g,7);
    check(c,h,8);
    check(c,i,9);
    check(c,j,10);

    check(d,a,1);
    check(d,b,2);
    check(d,c,3);
    check(d,d,4);
    check(d,e,5);
    check(d,f,6);
    check(d,g,7);

    check(e,a,1);
    check(e,b,2);

    check(f,a,1);
    check(f,b,2);

    check(g,a,1);
    check(g,b,2);

    check(h,a,1);
    check(h,b,2);

    check(i,b,2);

    exit(exit_code);
}
-----------------TEST CASE driver script --------------------------------------
cc -c  -mms-bitfields bittest_nat.c
# be sure to point gcc at the right gcc. (use the MinGW v3.2 for example)
# you can obtain the same result by using Microsoft C compiler. In that
# case use: cl /c bittest_nat.c and change bittest_nat.o by bittest_nat.obj
# below.

#This should pass and say nothing.
gcc -c -fnative-struct bittest_gcc.c 
echo NATIVE:
gcc bittest_nat.o bittest_gcc.o
a.out

#...This should fail and list errors.
gcc -c -fgcc-struct bittest_gcc.c 
echo GNU:
gcc bittest_nat.o bittest_gcc.o
a.out
Comment 1 Danny Smith 2004-05-02 21:31:21 UTC
gcc-dg/bf-ms-layout.c has been failing since at least 4 Sept 2003:

http://gcc.gnu.org/ml/gcc-testresults/2003-09/msg00126.html

Danny
Comment 2 Danny Smith 2004-05-03 01:35:51 UTC
This delta was part of large patchset committed by DJ Delorie on 2003-09-03.

It is not recorded in ChangeLog.  

Reverting it restores correct ms-bitfield-layout.

 ===================================================================
RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v
retrieving revision 1.166
retrieving revision 1.167
diff -u -r1.166 -r1.167
--- gcc/gcc/stor-layout.c	2003/08/20 12:24:18	1.166
+++ gcc/gcc/stor-layout.c	2003/09/04 03:17:50	1.167
@@ -1093,6 +1093,7 @@
 		rli->prev_field = NULL;
 	    }
 
+	  rli->offset_align = tree_low_cst (TYPE_SIZE (type), 0);
 	  normalize_rli (rli);
         }
 
Comment 3 DJ Delorie 2004-05-03 02:35:20 UTC
Subject: Re:  Option -mms-bitfields support on GCC 3.4 is not conformant to MS layout


> This delta was part of large patchset committed by DJ Delorie on 2003-09-03.
> 
> It is not recorded in ChangeLog.  

Accident :-P
Comment 4 pascal@obry.org 2004-05-03 17:14:16 UTC
Subject: Re:  Option -mms-bitfields support on GCC 3.4 is not conformant to MS layout


dannysmith at users dot sourceforge dot net writes:
 > 
 > ------- Additional Comments From dannysmith at users dot sourceforge dot net  2004-05-03 01:35 -------
 > This delta was part of large patchset committed by DJ Delorie on 2003-09-03.
 > 
 > It is not recorded in ChangeLog.  
 > 
 > Reverting it restores correct ms-bitfield-layout.

I confirm that reverting this patch does fix the problem on my side. Do you
think this will be part of GCC 3.4.1 ?

Thanks,
Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595

Comment 5 Andrew Pinski 2004-05-26 11:39:52 UTC
Confirmed.
Comment 6 Mark Mitchell 2004-05-28 22:04:50 UTC
DJ --

Would you please revert the erroneous part of the patch ASAP?

-- Mark
Comment 7 DJ Delorie 2004-05-28 23:16:48 UTC
Subject: Re:  [3.4/3.5 Regression] Option -mms-bitfields support on GCC 3.4 is not conformant to MS layout


> DJ --
> 
> Would you please revert the erroneous part of the patch ASAP?
> 
> -- Mark
> 
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15250

Done, for head and 3.4

2004-05-28  DJ Delorie  <dj@redhat.com>

	* stor-layout.c (place_field): Revert erroneous commit.
  
Index: stor-layout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v
retrieving revision 1.190
diff -p -C2 -r1.190 stor-layout.c
*** stor-layout.c       19 May 2004 17:53:45 -0000      1.190
--- stor-layout.c       28 May 2004 23:11:34 -0000
*************** place_field (record_layout_info rli, tre
*** 1128,1132 ****
            }
  
-         rli->offset_align = tree_low_cst (TYPE_SIZE (type), 0);
          normalize_rli (rli);
          }
--- 1128,1131 ----

Comment 8 Andrew Pinski 2004-05-29 00:12:49 UTC
Okay only a 3.5.0 regression now.
Comment 9 Andrew Pinski 2004-05-29 00:13:16 UTC
Fixed.