Skip to content

Wrong alignment of struct #1034

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
fitzgen opened this issue Sep 25, 2017 · 9 comments
Closed

Wrong alignment of struct #1034

fitzgen opened this issue Sep 25, 2017 · 9 comments

Comments

@fitzgen
Copy link
Member

fitzgen commented Sep 25, 2017

Input C/C++ Header

Generated by C-Smith:

/*
 * This is a RANDOMLY GENERATED PROGRAM.
 *
 * Generator: csmith 2.2.0
 * Git version: dcef523
 * Options:   --no-checksum --nomain --max-block-size 1 --max-block-depth 1 -o /tmp/input-d4ucc247.h
 * Seed:      629758572
 */

#include "csmith.h"

volatile uint64_t csmith_sink_ = 0;

static long __undefined;

/* --- Struct/Union Declarations --- */
struct S0 {
   uint64_t  f0;
   int64_t  f1;
   const int32_t  f2;
   uint8_t  f3;
   const uint8_t  f4;
   const int32_t  f5;
   uint8_t  f6;
};

#pragma pack(push)
#pragma pack(1)
struct S2 {
   signed f0 : 18;
   unsigned f1 : 11;
};
#pragma pack(pop)

union U4 {
   volatile unsigned f0 : 31;
   int64_t  f1;
   int64_t  f2;
   uint64_t  f3;
   uint32_t  f4;
};

/* --- GLOBAL VARIABLES --- */
static int8_t g_6 = 0xD9L;
static int8_t *g_5 = &g_6;
static int8_t *g_16 = &g_6;
static int8_t **g_15 = &g_16;
static volatile struct S2 g_19 = {492,24};/* VOLATILE GLOBAL g_19 */
static int32_t g_39 = 8L;
static struct S2 g_46 = {-28,33};
static const int32_t g_54 = 0x708CDB5CL;
static const int32_t *g_53[3] = {&g_54,&g_54,&g_54};
static int32_t g_57 = (-1L);
static int16_t g_58 = 0L;
static int32_t g_61 = (-1L);
static int64_t g_62 = (-1L);
static uint8_t g_63 = 255UL;
static int32_t *g_78 = &g_39;
static int32_t **g_77 = &g_78;
static int8_t g_106 = 5L;
static int64_t g_113 = 1L;
static int64_t *g_112 = &g_113;
static const int8_t g_124 = (-9L);
static int64_t g_131 = (-1L);
static volatile int8_t g_132[6][9][4] = {{{0x38L,0x7DL,0xCDL,0x38L},{(-9L),(-1L),0x7CL,0x72L},{(-10L),0x38L,7L,0L},{0xB3L,0x72L,0xB3L,(-1L)},{0x75L,(-9L),(-9L),0x72L},{0x43L,5L,0x38L,(-9L)},{0xCDL,0x7DL,0x38L,0xB3L},{0x43L,0x75L,(-9L),(-1L)},{0x75L,0x3EL,0xB3L,(-10L)}},{{0xB3L,(-10L),7L,5L},{(-10L),0x75L,0x7CL,5L},{0xCDL,0x25L,0x25L,0xCDL},{0x96L,0x38L,0xC6L,(-1L)},{(-1L),0xCDL,0x43L,0x3EL},{5L,0L,0x49L,0x3EL},{0x7CL,0xCDL,5L,(-1L)},{0xB3L,0x38L,0x7DL,0xCDL},{(-1L),0x25L,0x96L,5L}},{{0xC6L,7L,5L,3L},{0x24L,(-1L),(-1L),(-1L)},{5L,5L,0x7CL,0x38L},{5L,7L,0xC6L,0x49L},{0xCDL,(-1L),0L,0xCDL},{0xCDL,3L,0xC6L,8L},{5L,0xCDL,0x7CL,(-9L)},{5L,0x51L,(-1L),0x3EL},{0x24L,0x96L,5L,8L}},{{0xC6L,0x38L,0x96L,0x96L},{(-1L),(-1L),0x7DL,5L},{0xB3L,0L,5L,0x38L},{0x7CL,(-1L),0x49L,5L},{5L,(-1L),0x43L,0x38L},{(-1L),0L,0xC6L,5L},{0x96L,(-1L),0x25L,0x96L},{0xCDL,0x38L,5L,8L},{(-1L),0x96L,0x7CL,0x3EL}},{{0x49L,0x51L,0x49L,(-9L)},{0x24L,0xCDL,0x72L,8L},{0xB3L,3L,0x96L,0xCDL},{0x25L,(-1L),0x96L,0x49L},{0xB3L,7L,0x72L,0x38L},{0x24L,5L,0x49L,(-1L)},{0x49L,(-1L),0x7CL,3L},{(-1L),7L,5L,5L},{0xCDL,0x25L,0x25L,0xCDL}},{{0x96L,0x38L,0xC6L,(-1L)},{(-1L),0xCDL,0x43L,0x3EL},{5L,0L,0x49L,0x3EL},{0x7CL,0xCDL,5L,(-1L)},{0xB3L,0x38L,0x7DL,0xCDL},{(-1L),0x25L,0x96L,5L},{0xC6L,7L,5L,3L},{0x24L,(-1L),(-1L),(-1L)},{5L,5L,0x7CL,0x38L}}};
static volatile uint16_t g_139 = 65535UL;/* VOLATILE GLOBAL g_139 */
static int8_t *** volatile g_148 = &g_15;/* VOLATILE GLOBAL g_148 */
static union U4 g_149 = {0UL};/* VOLATILE GLOBAL g_149 */


/* --- FORWARD DECLARATIONS --- */
static union U4  func_1(void);
static int8_t ** const  func_2(int8_t * p_3, int8_t ** p_4);
static int8_t ** func_9(int32_t  p_10, int8_t ** p_11, int32_t  p_12, int8_t  p_13, const uint64_t  p_14);
static uint8_t  func_25(uint64_t  p_26, int32_t  p_27, int32_t  p_28);
static int8_t ** const  func_30(int8_t * p_31, int32_t  p_32, int8_t * p_33, int8_t * p_34);
static int8_t * func_35(uint32_t  p_36);
static uint32_t  func_40(uint16_t  p_41, struct S2  p_42, int64_t  p_43, int8_t ** p_44);
static int8_t ** func_47(int8_t  p_48, int8_t  p_49, int8_t * p_50, int8_t * p_51);
static uint32_t  func_68(int8_t ** p_69, int16_t  p_70, int8_t * p_71, uint8_t  p_72, int64_t  p_73);
static int8_t ** func_74(int32_t ** p_75, int64_t  p_76);


/* --- FUNCTIONS --- */
/* ------------------------------------------ */
/* 
 * reads : g_5 g_6 g_15 g_19 g_16 g_46 g_53 g_63 g_77 g_78 g_39 g_54 g_62 g_57 g_106 g_112 g_139 g_148 g_149
 * writes: g_5 g_39 g_53 g_63 g_57 g_78 g_106 g_62 g_139 g_15
 */
static union U4  func_1(void)
{ /* block id: 0 */
    int8_t *l_20[4] = {(void*)0,(void*)0,(void*)0,(void*)0};
    int32_t l_29[4][7] = {{0L,(-3L),(-5L),(-3L),0L,0x6930509BL,0x6930509BL},{0L,(-3L),(-5L),(-3L),0L,0x6930509BL,0x6930509BL},{0x6930509BL,0x0F30385DL,0L,0x0F30385DL,0x6930509BL,(-5L),(-5L)},{0x6930509BL,0x0F30385DL,0L,0x0F30385DL,0x6930509BL,(-5L),(-5L)}};
    const int8_t *l_123[3];
    const int8_t **l_122 = &l_123[2];
    int8_t ***l_147 = &g_15;
    int i, j;
    for (i = 0; i < 3; i++)
        l_123[i] = &g_124;
    (*g_148) = func_2((g_5 = g_5), (((((safe_div_func_uint32_t_u_u((((*l_147) = func_9(g_6, g_15, ((safe_lshift_func_uint16_t_u_u(0x711DL, 6)) != (1UL && ((g_19 , l_20[1]) != ((*l_122) = ((safe_mod_func_uint8_t_u_u((safe_rshift_func_int8_t_s_u((*g_16), func_25(l_29[0][6], g_6, g_6))), 2UL)) , (*g_15)))))), l_29[3][6], g_46.f1)) != &l_20[2]), l_29[0][6])) >= l_29[3][4]) , (*l_122)) == (void*)0) , (*l_147)));
    return g_149;
}


/* ------------------------------------------ */
/* 
 * reads : g_77
 * writes: g_78
 */
static int8_t ** const  func_2(int8_t * p_3, int8_t ** p_4)
{ /* block id: 46 */
    (*g_77) = (void*)0;
    return &g_16;
}


/* ------------------------------------------ */
/* 
 * reads : g_139
 * writes: g_139
 */
static int8_t ** func_9(int32_t  p_10, int8_t ** p_11, int32_t  p_12, int8_t  p_13, const uint64_t  p_14)
{ /* block id: 38 */
    const int32_t l_125 = 9L;
    int32_t l_128 = 0L;
    int32_t l_129 = 0x99A09347L;
    int32_t l_133 = 0x8B77237EL;
    int32_t l_134 = 0xC1B3EE27L;
    int32_t l_135 = 0x6E12AA01L;
    int32_t l_136 = (-7L);
    int32_t l_137 = 0L;
    int32_t l_138 = 0x6387BD1CL;
    if (l_125)
    { /* block id: 39 */
        int32_t *l_126 = &g_57;
        int32_t *l_127[8][9][3];
        int16_t l_130 = (-1L);
        int i, j, k;
        for (i = 0; i < 8; i++)
        {
            for (j = 0; j < 9; j++)
            {
                for (k = 0; k < 3; k++)
                    l_127[i][j][k] = (void*)0;
            }
        }
        ++g_139;
    }
    else
    { /* block id: 41 */
        int32_t *l_142 = &l_137;
        int32_t *l_143[10] = {&l_138,&l_138,&l_138,&l_138,&l_138,&l_138,&l_138,&l_138,&l_138,&l_138};
        uint16_t l_144[10] = {0x1A07L,1UL,0x1A07L,1UL,0x1A07L,1UL,0x1A07L,1UL,0x1A07L,1UL};
        int i;
        l_144[4]++;
    }
    return &g_16;
}


/* ------------------------------------------ */
/* 
 * reads : g_15 g_16 g_6 g_46 g_53 g_63 g_77 g_78 g_39 g_54 g_62 g_57 g_106 g_112
 * writes: g_39 g_53 g_63 g_57 g_78 g_106 g_62
 */
static uint8_t  func_25(uint64_t  p_26, int32_t  p_27, int32_t  p_28)
{ /* block id: 2 */
    uint32_t l_37 = 18446744073709551615UL;
    int16_t l_45 = 0x72BEL;
    int8_t *l_52[4][6][4] = {{{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6}},{{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6}},{{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6}},{{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6},{&g_6,&g_6,&g_6,&g_6}}};
    int32_t *l_66 = &g_57;
    int8_t **l_120 = &g_16;
    int8_t ***l_119[5] = {&g_15,&g_15,&g_15,&g_15,&g_15};
    int8_t ***l_121 = &l_120;
    int i, j, k;
    (*l_121) = func_30(func_35(l_37), ((*l_66) = (g_6 >= func_40(l_45, g_46, g_46.f1, func_47(l_45, (**g_15), l_52[0][0][3], (*g_15))))), l_52[0][0][3], (*g_15));
    return g_106;
}


/* ------------------------------------------ */
/* 
 * reads : g_77 g_78 g_39 g_54 g_46.f0 g_63 g_62 g_57 g_16 g_6 g_106 g_112 g_46
 * writes: g_78 g_63 g_106 g_62
 */
static int8_t ** const  func_30(int8_t * p_31, int32_t  p_32, int8_t * p_33, int8_t * p_34)
{ /* block id: 13 */
    uint32_t l_79[1][2][4] = {{{0xAC7196A4L,0x8F974433L,0xAC7196A4L,0xAC7196A4L},{0x8F974433L,0x8F974433L,18446744073709551615UL,0x8F974433L}}};
    int8_t *l_80 = &g_6;
    int64_t **l_114[9] = {(void*)0,&g_112,&g_112,(void*)0,&g_112,&g_112,(void*)0,&g_112,&g_112};
    int64_t *l_115 = &g_113;
    int i, j, k;
    if (func_40(((((!func_68(func_74(g_77, p_32), l_79[0][1][1], l_80, g_39, l_79[0][1][2])) > ((l_115 = g_112) != &g_113)) >= l_79[0][1][1]) , g_63), g_46, l_79[0][1][1], &l_80))
    { /* block id: 29 */
        int32_t * const l_116 = &g_39;
        int32_t **l_117 = &g_78;
        (*l_117) = l_116;
    }
    else
    { /* block id: 31 */
        int8_t ** const l_118 = &l_80;
        return &g_16;
    }
    return &g_16;
}


/* ------------------------------------------ */
/* 
 * reads : g_15 g_16
 * writes: g_39
 */
static int8_t * func_35(uint32_t  p_36)
{ /* block id: 3 */
    int32_t *l_38 = &g_39;
    (*l_38) = p_36;
    return (*g_15);
}


/* ------------------------------------------ */
/* 
 * reads : g_63
 * writes: g_63
 */
static uint32_t  func_40(uint16_t  p_41, struct S2  p_42, int64_t  p_43, int8_t ** p_44)
{ /* block id: 9 */
    int32_t *l_56[2];
    int32_t l_59[7][9] = {{0xD7B1ECBCL,0x2D8C20E5L,6L,0x624E194EL,6L,0x2D8C20E5L,0xD7B1ECBCL,(-1L),0xF9094207L},{(-1L),5L,0xD7B1ECBCL,0x624E194EL,0L,0x2E4BCB81L,(-1L),6L,(-1L)},{(-1L),0L,0x7A880E1BL,0x7A880E1BL,0L,(-1L),0xF9094207L,(-1L),0xD7B1ECBCL},{6L,1L,0x7A880E1BL,0x2E4BCB81L,(-1L),0x61EA52FAL,0L,0L,0x61EA52FAL},{0x7A880E1BL,0L,0x624E194EL,6L,0x2D8C20E5L,0xD7B1ECBCL,(-1L),0xF9094207L,(-1L)},{0x61EA52FAL,6L,0xD7B1ECBCL,(-1L),7L,0x287676E3L,0L,0x287676E3L,7L},{(-1L),7L,7L,(-1L),5L,0xD7B1ECBCL,0x624E194EL,0L,0x2E4BCB81L}};
    int16_t l_60 = 0x09D5L;
    int i, j;
    for (i = 0; i < 2; i++)
        l_56[i] = &g_57;
    g_63++;
    return p_42.f0;
}


/* ------------------------------------------ */
/* 
 * reads : g_53
 * writes: g_53
 */
static int8_t ** func_47(int8_t  p_48, int8_t  p_49, int8_t * p_50, int8_t * p_51)
{ /* block id: 6 */
    const int32_t **l_55 = &g_53[0];
    (*l_55) = g_53[0];
    return &g_16;
}


/* ------------------------------------------ */
/* 
 * reads : g_54 g_46.f0 g_63 g_62 g_57 g_16 g_6 g_106 g_77
 * writes: g_63 g_106 g_62 g_78
 */
static uint32_t  func_68(int8_t ** p_69, int16_t  p_70, int8_t * p_71, uint8_t  p_72, int64_t  p_73)
{ /* block id: 17 */
    uint64_t l_81[1];
    int32_t l_93 = (-1L);
    uint8_t *l_94 = &g_63;
    const struct S0 l_103 = {0UL,0x133A9B92FD598C55LL,0xA0DA2B3CL,0x8CL,1UL,5L,0UL};
    const uint32_t l_104[8][6] = {{0x3E519B98L,0UL,0UL,0x3E519B98L,18446744073709551615UL,18446744073709551615UL},{0x3E519B98L,18446744073709551615UL,18446744073709551615UL,0x706978B3L,0UL,18446744073709551615UL},{18446744073709551606UL,0xDF25B48FL,0UL,9UL,0UL,0xDF25B48FL},{0x706978B3L,18446744073709551615UL,0x09415F90L,9UL,18446744073709551615UL,0UL},{18446744073709551606UL,0UL,0x09415F90L,0x706978B3L,0xDF25B48FL,0xDF25B48FL},{0x3E519B98L,0UL,0UL,0x3E519B98L,18446744073709551615UL,18446744073709551615UL},{0x3E519B98L,18446744073709551615UL,18446744073709551615UL,0x706978B3L,0UL,18446744073709551615UL},{18446744073709551606UL,0xDF25B48FL,0UL,9UL,0UL,0xDF25B48FL}};
    int8_t *l_105[8][2] = {{(void*)0,&g_106},{(void*)0,(void*)0},{(void*)0,&g_106},{(void*)0,(void*)0},{(void*)0,&g_106},{(void*)0,(void*)0},{(void*)0,&g_106},{(void*)0,(void*)0}};
    int64_t *l_107 = (void*)0;
    int64_t *l_108 = (void*)0;
    int64_t *l_109 = &g_62;
    int i, j;
    for (i = 0; i < 1; i++)
        l_81[i] = 0UL;
    if ((l_81[0] > (safe_lshift_func_int16_t_s_u((p_70 |= (g_54 && l_81[0])), (safe_mul_func_int16_t_s_s(((((*l_109) = (safe_mul_func_int8_t_s_s((g_46.f0 > (+p_72)), (g_106 &= ((safe_sub_func_int64_t_s_s((safe_mod_func_int64_t_s_s(((--(*l_94)) || (safe_unary_minus_func_uint64_t_u((p_72 ^ ((safe_rshift_func_int16_t_s_u((safe_unary_minus_func_int16_t_s((safe_sub_func_uint64_t_u_u((l_103 , p_73), g_62)))), g_63)) != g_63))))), l_104[3][1])), g_57)) , (*g_16)))))) , 0x718CL) <= g_54), g_54))))))
    { /* block id: 22 */
        int32_t *l_110 = &g_39;
        (*g_77) = l_110;
    }
    else
    { /* block id: 24 */
        int32_t *l_111 = &g_39;
        (*g_77) = l_111;
    }
    return g_63;
}


/* ------------------------------------------ */
/* 
 * reads : g_78
 * writes: g_78
 */
static int8_t ** func_74(int32_t ** p_75, int64_t  p_76)
{ /* block id: 14 */
    (*p_75) = (*p_75);
    return &g_16;
}



/************************ statistics *************************
XXX max struct depth: 1
breakdown:
   depth: 0, occurrence: 41
   depth: 1, occurrence: 3
XXX total union variables: 1

XXX non-zero bitfields defined in structs: 3
XXX zero bitfields defined in structs: 0
XXX const bitfields defined in structs: 0
XXX volatile bitfields defined in structs: 1
XXX structs with bitfields in the program: 3
breakdown:
   indirect level: 0, occurrence: 3
XXX full-bitfields structs in the program: 2
breakdown:
   indirect level: 0, occurrence: 2
XXX times a bitfields struct's address is taken: 0
XXX times a bitfields struct on LHS: 0
XXX times a bitfields struct on RHS: 4
XXX times a single bitfield on LHS: 0
XXX times a single bitfield on RHS: 4

XXX max expression depth: 28
breakdown:
   depth: 1, occurrence: 34
   depth: 16, occurrence: 1
   depth: 17, occurrence: 1
   depth: 22, occurrence: 1
   depth: 28, occurrence: 1

XXX total number of pointers: 54

XXX times a variable address is taken: 58
XXX times a pointer is dereferenced on RHS: 10
breakdown:
   depth: 1, occurrence: 9
   depth: 2, occurrence: 1
XXX times a pointer is dereferenced on LHS: 14
breakdown:
   depth: 1, occurrence: 14
XXX times a pointer is compared with null: 0
XXX times a pointer is compared with address of another variable: 0
XXX times a pointer is compared with another pointer: 0
XXX times a pointer is qualified to be dereferenced: 296

XXX max dereference level: 2
breakdown:
   level: 0, occurrence: 0
   level: 1, occurrence: 30
   level: 2, occurrence: 5
XXX number of pointers point to pointers: 21
XXX number of pointers point to scalars: 33
XXX number of pointers point to structs: 0
XXX percent of pointers has null in alias set: 13
XXX average alias set size: 1.15

XXX times a non-volatile is read: 78
XXX times a non-volatile is write: 33
XXX times a volatile is read: 1
XXX    times read thru a pointer: 0
XXX times a volatile is write: 2
XXX    times written thru a pointer: 0
XXX times a volatile is available for access: 9
XXX percentage of non-volatile access: 97.4

XXX forward jumps: 0
XXX backward jumps: 0

XXX stmts: 26
XXX max block depth: 1
breakdown:
   depth: 0, occurrence: 20
   depth: 1, occurrence: 6

XXX percentage a fresh-made variable is used: 31.7
XXX percentage an existing variable is used: 68.3
FYI: the random generator makes assumptions about the integer size. See platform.info for more details.
********************* end of statistics **********************/

Bindgen Invocation

$ bindgen input.h --with-derive-partialeq --with-derive-eq

Actual Results

running 3 tests
test bindgen_test_layout_S0 ... ok
test bindgen_test_layout_U4 ... FAILED
test bindgen_test_layout_S2 ... FAILED

failures:

---- bindgen_test_layout_U4 stdout ----
	thread 'bindgen_test_layout_U4' panicked at 'assertion failed: `(left == right)`
  left: `16`,
 right: `8`: Size of: U4', /tmp/output-7qjh2751.rs:6:5485
note: Run with `RUST_BACKTRACE=1` for a backtrace.

---- bindgen_test_layout_S2 stdout ----
	thread 'bindgen_test_layout_S2' panicked at 'assertion failed: `(left == right)`
  left: `4`,
 right: `1`: Alignment of S2', /tmp/output-7qjh2751.rs:6:2289


failures:
    bindgen_test_layout_S2
    bindgen_test_layout_U4

test result: FAILED. 1 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out

Expected Results

No layout test failures.

@pepyakin
Copy link
Contributor

Reduced by Alignment of S2

struct S2 {
  unsigned : 11
};

Reduced by Size of: U4:

union U4 {
  unsigned : 1
};

@pepyakin
Copy link
Contributor

pepyakin commented Oct 2, 2017

For alignment problem:

#include <stdio.h>

struct S2 {
  unsigned : 11;
};

int main() {
  printf("sizeof(S2)=%lu,alignof(S2)=%lu\n", alignof(S2), alignof(S2));
}

this little program outputs sizeof(S2)=1,alignof(S2)=1

Generated bindings looks like:

#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]


#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct S2 {
    pub _bitfield_1: u16,
    pub __bindgen_align: [u8; 0usize],
}
#[test]
fn bindgen_test_layout_S2() {
    assert_eq!(
        ::std::mem::size_of::<S2>(),
        2usize,
        concat!("Size of: ", stringify!(S2))
    );
    assert_eq!(
        ::std::mem::align_of::<S2>(),
        1usize,
        concat!("Alignment of ", stringify!(S2))
    );
}
impl Clone for S2 {
    fn clone(&self) -> Self {
        *self
    }
}
impl S2 {
    #[inline]
    pub fn new_bitfield_1() -> u16 {
        0
    }
}

And this is how it looks in IR
ir

@fitzgen
Copy link
Member Author

fitzgen commented Oct 2, 2017

Interesting -- it looks like the layout libclang gives us says size = 2. What compiler are you using to compile the C program?

@pepyakin
Copy link
Contributor

pepyakin commented Oct 2, 2017

I compiled with clang++ --std=c++14 main.c

clang++ --version gives me

Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

@pepyakin
Copy link
Contributor

pepyakin commented Oct 3, 2017

I've moved issue around size to seperate issue #1056

UPDATE: Turned out that this is a known issue #744

@pepyakin pepyakin changed the title Wrong size and alignment of struct Wrong alignment of struct Oct 3, 2017
@pepyakin
Copy link
Contributor

pepyakin commented Oct 3, 2017

Oops, my comment #1034 (comment) contains copy-pasta issue. It tells that it outputs sizeof(S2)=1,alignof(S2)=1 but actually it outputs alignof(S2), alignof(S2).

Sorry about that!

Fixed version:

#include <stdio.h>

struct S2 {
  unsigned : 11;
};

int main() {
  printf("sizeof(S2)=%lu,alignof(S2)=%lu\n", sizeof(S2), alignof(S2)); 
}

returns sizeof(S2)=2,alignof(S2)=1.

This makes things a little clearer.

@pepyakin
Copy link
Contributor

pepyakin commented Oct 3, 2017

Is it possible to solve now?

If I understand correctly to make this struct

#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct S2 {
    pub _bitfield_1: u16,
    pub __bindgen_align: [u8; 0usize],
}

to have alignment of 1 we should have #[repr(align)] attribute...

@fitzgen
Copy link
Member Author

fitzgen commented Oct 3, 2017

Depends on #849 and rust-lang/rust#33626

@pepyakin
Copy link
Contributor

It seems that repr(align(N)) on struct S has no effect if N is less than alignment of the S. Here is playground link.

It appears that we actually need to use repr(packed(N)) here.
Good news: repr(packed(1)) is a synonym of the repr(packed).

bors-servo pushed a commit that referenced this issue Oct 11, 2017
Use `repr(packed)` If struct requires explicit alignment of 1.

Fixes #1034
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

2 participants