Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Wrong alignment of struct #1034

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants