(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
bf-ms-layout-2.c
       1  /* bf-ms-layout.c */
       2  
       3  /* Test for MS bitfield layout */
       4  /* Adapted from Donn Terry <donnte@microsoft.com> testcase
       5     posted to GCC-patches
       6     http://gcc.gnu.org/ml/gcc-patches/2000-08/msg00577.html */
       7  
       8  /* { dg-do run { target i?86-*-* x86_64-*-* } } */
       9  /* { dg-options "-D_TEST_MS_LAYOUT" } */
      10  /* This test uses the attribute instead of the command line option.  */
      11  
      12  #include <stddef.h>
      13  #include <string.h>
      14  
      15  extern void abort();
      16  
      17  #pragma pack(8)
      18  
      19  #ifdef __GNUC__
      20  #define ATTR __attribute__ ((ms_struct))
      21  #endif
      22  
      23  struct one {
      24    int d;
      25    unsigned char a;
      26    unsigned short b:7;
      27    char c;
      28  } ATTR;
      29  
      30  struct two {
      31    int d;
      32    unsigned char a;
      33    unsigned int b:7;
      34    char c;
      35  } ATTR;
      36  
      37  struct three {
      38    short d;
      39    unsigned short a:3;
      40    unsigned short b:9;
      41    unsigned char c:7;
      42  } ATTR;
      43  
      44  
      45  /* Bitfields of size 0 have some truly odd behaviors. */
      46  
      47  struct four {
      48    unsigned short a:3;
      49    unsigned short b:9;
      50    unsigned int :0;  /* forces struct alignment to int */
      51    unsigned char c:7;
      52  } ATTR;
      53  
      54  struct five {
      55    char a;
      56    int :0;        /* ignored; prior field is not a bitfield. */
      57    char b;
      58    char c;
      59  } ATTR;
      60  
      61  struct six {
      62    char a :8;
      63    int :0;	/* not ignored; prior field IS a bitfield, causes
      64  		   struct alignment as well. */
      65    char b;
      66    char c;
      67  } ATTR;
      68  
      69  struct seven {
      70    char a:8;
      71    char :0;
      72    int  :0;	/* Ignored; prior field is zero size bitfield. */
      73    char b;
      74    char c;
      75  } ATTR;
      76  
      77  struct eight { /* ms size 4 */
      78    short b:3;
      79    char  c;
      80  } ATTR;
      81  
      82  #ifdef _MSC_VER
      83  #define LONGLONG __int64
      84  #else
      85  #define LONGLONG long long
      86  #endif
      87  
      88  union nine {   /* ms size 8 */
      89    LONGLONG a:3;
      90    char  c;
      91  } ATTR;
      92  
      93  struct ten {   /* ms size 16 */
      94    LONGLONG a:3;
      95    LONGLONG b:3;
      96    char  c;
      97  } ATTR;
      98  
      99  
     100  #define val(s,f) (s.f)
     101  
     102  #define check_struct(_X) \
     103  { \
     104    if (sizeof (struct _X) != exp_sizeof_##_X )	\
     105      abort();					\
     106    memcpy(&test_##_X, filler, sizeof(test_##_X));\
     107    if (val(test_##_X,c) != exp_##_X##_c) 	\
     108       abort();					\
     109  }
     110  
     111  #define check_union(_X) \
     112  { \
     113    if (sizeof (union _X) != exp_sizeof_##_X )	\
     114      abort();                                    \
     115    memcpy(&test_##_X, filler, sizeof(test_##_X));\
     116    if (val(test_##_X,c) != exp_##_X##_c) 	\
     117       abort();					\
     118  }
     119  
     120  #define check_struct_size(_X) \
     121  { \
     122    if (sizeof (struct _X) != exp_sizeof_##_X )	\
     123      abort();                                    \
     124  }
     125  
     126  #define check_struct_off(_X) \
     127  { \
     128    memcpy(&test_##_X, filler, sizeof(test_##_X));\
     129    if (val(test_##_X,c) != exp_##_X##_c) 	\
     130      abort();                                    \
     131  }
     132  
     133  #define check_union_size(_X) \
     134  { \
     135    if (sizeof (union _X) != exp_sizeof_##_X )	\
     136      abort();                                    \
     137  }
     138  
     139  #define check_union_off(_X) \
     140  { \
     141    memcpy(&test_##_X, filler, sizeof(test_##_X));\
     142    if (val(test_##_X,c) != exp_##_X##_c) 	\
     143      abort();                                    \
     144  }
     145  
     146  int main(){
     147  
     148    unsigned char filler[16];
     149    struct one test_one;
     150    struct two test_two;
     151    struct three test_three;
     152    struct four test_four;
     153    struct five test_five;
     154    struct six test_six;
     155    struct seven test_seven;
     156    struct eight test_eight;
     157    union nine test_nine;
     158    struct ten test_ten;
     159  
     160  #if defined (_TEST_MS_LAYOUT) || defined (_MSC_VER)
     161    size_t exp_sizeof_one = 12;
     162    size_t exp_sizeof_two = 16;
     163    size_t exp_sizeof_three =6;
     164    size_t exp_sizeof_four = 8;
     165    size_t exp_sizeof_five = 3;
     166    size_t exp_sizeof_six = 8;
     167    size_t exp_sizeof_seven = 3;
     168    size_t exp_sizeof_eight = 4;
     169    size_t exp_sizeof_nine = 8;
     170    size_t exp_sizeof_ten = 16;
     171  
     172    unsigned char exp_one_c = 8;
     173    unsigned char exp_two_c  = 12;
     174    unsigned char exp_three_c = 4;
     175    unsigned char exp_four_c = 4;
     176    char exp_five_c = 2;
     177    char exp_six_c = 5;
     178    char exp_seven_c = 2;
     179    char exp_eight_c = 2;
     180    char exp_nine_c = 0;
     181    char exp_ten_c = 8;
     182  
     183  #else /* testing -mno-ms-bitfields */
     184  
     185    size_t exp_sizeof_one = 8;
     186    size_t exp_sizeof_two = 8;
     187    size_t exp_sizeof_three = 6;
     188    size_t exp_sizeof_four = 6;
     189    size_t exp_sizeof_five = 6;
     190    size_t exp_sizeof_six = 6;
     191    size_t exp_sizeof_seven = 6;
     192    size_t exp_sizeof_eight = 2;
     193    size_t exp_sizeof_nine = 8;
     194    size_t exp_sizeof_ten = 8;
     195  
     196    unsigned short exp_one_c = 6;
     197    unsigned int exp_two_c  = 6;
     198    unsigned char exp_three_c = 64;
     199    unsigned char exp_four_c = 4;
     200    char exp_five_c = 5;
     201    char exp_six_c = 5;
     202    char exp_seven_c = 5;
     203    char exp_eight_c = 1;
     204    char exp_nine_c = 0;
     205    char exp_ten_c = 1;
     206  
     207  #endif
     208  
     209    unsigned char i;
     210    for ( i = 0; i < 16; i++ )
     211      filler[i] = i;
     212  
     213    check_struct_off (one);
     214    check_struct_off (two);
     215    check_struct_off (three);
     216    check_struct_off (four);
     217    check_struct_off (five);
     218    check_struct_off (six);
     219    check_struct_off (seven);
     220    check_struct_off (eight);
     221    check_union_off (nine);
     222    check_struct_off (ten);
     223  
     224    check_struct_size (one);
     225    check_struct_size (two);
     226    check_struct_size (three);
     227    check_struct_size (four);
     228    check_struct_size (five);
     229    check_struct_size (six);
     230    check_struct_size (seven);
     231    check_struct_size (eight);
     232    check_union_size (nine);
     233    check_struct_size (ten);
     234  
     235    return 0;
     236  };