[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[csmith-dev] Unions, bitfields, and reading bits that have not been initialized



Hello,

I am sorry that I find myself discussing the behavior of a past
version, but I have to juggle a bit with Csmith snapshots and
I assume that different snapshots will give very different
programs when fed the same seed.

I would like to discuss this program (also attached):

/*
 * This is a RANDOMLY GENERATED PROGRAM.
 *
 * Generator: csmith 2.1.0
 * Git version: 20b4710
 * Options:   --unions --max-funcs 2 --max-array-dim 2 --max-array-len-per-dim 3 --max-struct-fields 3 --no-volatiles --no-argc --bitfields
 * Seed:      1285011442
 */

I am interested in the right-hand-side p_6.f2.f0 at line 146.

p_6 is a copy of func_1's local variable l_8, declared
and initialized at line 71:
  union U9 l_8 = {{236541262}};

union U9 is:

union U9 {
   struct S1  f0;
   uint16_t  f1;
   struct S4  f2;
};

and struct S1 is:

struct S1 {
   const signed f0 : _CSMITH_BITFIELD(58);
};

If I understand initialization of structs and unions correctly,
the member initialized at line 71 is l_8.f0.f0, and that
member is a 58-bit bitfield.

Now line 146 reads (a copy of) l_8.f2.f0, a 60-bit bitfield.

Reading bits that have been set through another member 
(or other members) of an union is implementation-defined,
but the program seems to be reading uninitialized bits here.

Even if that does not crash the program,
it risks making it non-deterministic (even for a fixed compiler
and architecture), which makes Csmith less convenient to
use to find and report bugs in compilers.

Did I miss something?

Pascal

/*
 * This is a RANDOMLY GENERATED PROGRAM.
 *
 * Generator: csmith 2.1.0
 * Git version: 20b4710
 * Options:   --unions --max-funcs 2 --max-array-dim 2 --max-array-len-per-dim 3 --max-struct-fields 3 --no-volatiles --no-argc --bitfields --seed 1285011442
 * Seed:      1285011442
 */

#include "csmith.h"


static long __undefined;

/* --- Struct/Union Declarations --- */
struct S0 {
   uint16_t  f0;
};

struct S2 {
   int16_t  f0;
};

struct S4 {
   unsigned f0 : _CSMITH_BITFIELD(60);
   unsigned f1 : _CSMITH_BITFIELD(52);
};

struct S6 {
   int64_t  f0;
};

struct S1 {
   const signed f0 : _CSMITH_BITFIELD(58);
};

union U9 {
   struct S1  f0;
   uint16_t  f1;
   struct S4  f2;
};

/* --- GLOBAL VARIABLES --- */
static int32_t g_2 = 0x9141A9C2L;
static struct S4 g_9 = {994399811,31880924};
static int32_t g_17[2] = {7L, 7L};
static struct S2 *g_33[2] = {0, 0};
static struct S2 **g_32 = &g_33[1];
static int32_t g_35 = (-1L);
static struct S0 g_44 = {1U};
static struct S0 *g_43 = &g_44;
static struct S6 g_47 = {0x545545654A13735CLL};
static int8_t g_52 = 0xA2L;
static int8_t *g_54[2][3] = {{&g_52, &g_52, &g_52}, {&g_52, &g_52, &g_52}};
static int8_t **g_53 = &g_54[1][0];


/* --- FORWARD DECLARATIONS --- */
static int8_t  func_1(void);
static struct S0 * func_5(union U9  p_6, struct S4  p_7);


/* --- FUNCTIONS --- */
/* ------------------------------------------ */
/* 
 * reads : g_9 g_2 g_17 g_35 g_43 g_53 g_54 g_47.f0 g_52
 * writes: g_2 g_17 g_32 g_35 g_43 g_52 g_44.f0
 */
static int8_t  func_1(void)
{ /* block id: 0 */
    union U9 l_8 = {{236541262}};
    int32_t *l_83 = 0;
    int32_t *l_84 = 0;
    int32_t *l_85 = 0;
    int32_t *l_86[3][1];
    int i, j;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 1; j++)
            l_86[i][j] = &g_2;
    }
    for (g_2 = 0; (g_2 < 9); g_2 = safe_add_func_int32_t_s_s(g_2, 5))
    { /* block id: 3 */
        struct S0 **l_63 = &g_43;
        int32_t *l_70 = &g_17[0];
        (*l_63) = func_5(l_8, g_9);
        for (g_35 = 0; (g_35 > 6); g_35 = safe_add_func_int32_t_s_s(g_35, 1))
        { /* block id: 54 */
            for (g_52 = 23; (g_52 < (-17)); g_52 = safe_sub_func_uint8_t_u_u(g_52, 5))
            { /* block id: 57 */
                int32_t *l_68 = 0;
                int32_t *l_69 = &g_17[0];
                (*l_69) = l_8.f2.f1;
            }
        }
        (*l_70) = g_9.f0;
        (*l_70) = g_9.f0;
    }
    for (g_44.f0 = (-30); (g_44.f0 < 33); g_44.f0 = safe_add_func_uint8_t_u_u(g_44.f0, 9))
    { /* block id: 66 */
        uint32_t l_75 = 4294967293U;
        uint64_t l_76 = 7U;
        int32_t *l_77[3];
        int i;
        for (i = 0; i < 3; i++)
            l_77[i] = &g_17[0];
        g_35 |= (+(safe_mod_func_int8_t_s_s(l_75, l_76)));
        for (l_76 = 18; (l_76 >= 4); l_76 = safe_sub_func_int16_t_s_s(l_76, 1))
        { /* block id: 70 */
            int64_t l_80 = 5L;
            g_2 = g_47.f0;
            if (g_17[1])
                continue;
            if (l_80)
                continue;
        }
        g_35 = g_35;
    }
    g_17[1] ^= (l_8.f2.f1 & (safe_add_func_int8_t_s_s((**g_53), (**g_53))));
    return (**g_53);
}


/* ------------------------------------------ */
/* 
 * reads : g_9.f1 g_2 g_17 g_9.f0 g_35 g_43 g_53 g_54
 * writes: g_17 g_32 g_35
 */
static struct S0 * func_5(union U9  p_6, struct S4  p_7)
{ /* block id: 4 */
    uint32_t l_10 = 1U;
    struct S2 l_11 = {1L};
    struct S2 *l_12 = &l_11;
    int16_t l_40 = (-6L);
    int8_t **l_49 = 0;
    uint32_t l_61 = 4294967295U;
    struct S0 *l_62 = &g_44;
    l_10 ^= (g_9.f1 >= g_9.f1);
lbl_34:
    (*l_12) = l_11;
    for (l_11.f0 = 0; (l_11.f0 < 15); l_11.f0 = safe_add_func_int16_t_s_s(l_11.f0, 1))
    { /* block id: 9 */
        int32_t *l_15 = 0;
        int32_t *l_16 = &g_17[1];
        int8_t *l_60 = &g_52;
        (*l_16) = p_6.f2.f0;
        for (p_6.f1 = 0; (p_6.f1 <= 53); p_6.f1 = safe_add_func_int8_t_s_s(p_6.f1, 1))
        { /* block id: 13 */
            int32_t l_22[1];
            int32_t l_28[2];
            struct S2 **l_31[1][2];
            int i, j;
            for (i = 0; i < 1; i++)
                l_22[i] = 0x48792891L;
            for (i = 0; i < 2; i++)
                l_28[i] = 4L;
            for (i = 0; i < 1; i++)
            {
                for (j = 0; j < 2; j++)
                    l_31[i][j] = &l_12;
            }
            l_28[0] &= ((g_2 > (((safe_add_func_int64_t_s_s(l_22[0], g_17[0])) || (safe_unary_minus_func_uint32_t_u(g_2))) < (g_17[1] && (safe_lshift_func_int16_t_s_s((safe_add_func_int8_t_s_s(p_6.f2.f1, l_22[0])), 8))))) != (p_6.f2.f1 & (l_10 <= g_9.f0)));
            for (l_10 = 24; (l_10 >= 55); l_10 = safe_add_func_int32_t_s_s(l_10, 1))
            { /* block id: 17 */
                const uint16_t l_48 = 4U;
                int8_t *l_51[1][3];
                int8_t **l_50 = &l_51[0][0];
                int i, j;
                for (i = 0; i < 1; i++)
                {
                    for (j = 0; j < 3; j++)
                        l_51[i][j] = &g_52;
                }
                g_32 = l_31[0][1];
                if (g_9.f1)
                    goto lbl_34;
                for (g_35 = 0; (g_35 <= 1); g_35 += 1)
                { /* block id: 22 */
                    if ((p_7.f1 < (safe_rshift_func_uint8_t_u_u(((safe_rshift_func_int16_t_s_u(((l_22[0] <= l_40) >= g_17[1]), 6)) <= g_35), 3))))
                    { /* block id: 23 */
                        (*l_16) = l_22[0];
                        (*l_16) |= (((safe_sub_func_int8_t_s_s(p_7.f1, p_7.f0)) | g_35) != (0x732BC12A55B90CB9LL <= g_9.f0));
                    }
                    else
                    { /* block id: 26 */
                        (*l_16) = g_9.f1;
                        return g_43;
                    }
                    for (l_40 = 0; (l_40 <= 1); l_40 += 1)
                    { /* block id: 32 */
                        struct S6 **l_45 = 0;
                        struct S6 *l_46 = &g_47;
                        int8_t ***l_55 = &l_50;
                        l_46 = 0;
                        (*l_16) = l_48;
                        l_50 = l_49;
                        (*l_55) = g_53;
                    }
                }
            }
            (*l_16) &= l_10;
            if (l_28[1])
                continue;
        }
        if (g_17[0])
            continue;
        if (((safe_mul_func_int8_t_s_s((65535U > p_6.f2.f0), (l_49 != l_49))) || ((safe_sub_func_uint8_t_u_u((l_60 == (*g_53)), l_61)) < p_6.f0.f0)))
        { /* block id: 44 */
            if (l_40)
                break;
        }
        else
        { /* block id: 46 */
            (*l_16) |= g_35;
        }
    }
    return l_62;
}




/* ---------------------------------------- */
int main (void)
{
    int i, j;
    int print_hash_value = 0;
    platform_main_begin();
    crc32_gentab();
    func_1();
    transparent_crc(g_2, "g_2", print_hash_value);
    transparent_crc(g_9.f0, "g_9.f0", print_hash_value);
    transparent_crc(g_9.f1, "g_9.f1", print_hash_value);
    for (i = 0; i < 2; i++)
    {
        transparent_crc(g_17[i], "g_17[i]", print_hash_value);
        if (print_hash_value) printf("index = [%d]\n", i);

    }
    transparent_crc(g_35, "g_35", print_hash_value);
    transparent_crc(g_44.f0, "g_44.f0", print_hash_value);
    transparent_crc(g_47.f0, "g_47.f0", print_hash_value);
    transparent_crc(g_52, "g_52", print_hash_value);
    platform_main_end(crc32_context ^ 0xFFFFFFFFUL, print_hash_value);
    return 0;
}

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

XXX non-zero bitfields defined in structs: 2
XXX zero bitfields defined in structs: 0
XXX const bitfields defined in structs: 0
XXX volatile bitfields defined in structs: 0
XXX structs with bitfields in the program: 1
breakdown:
   indirect level: 0, occurrence: 1
XXX full-bitfields structs in the program: 1
breakdown:
   indirect level: 0, occurrence: 1
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: 1
XXX times a single bitfield on LHS: 0
XXX times a single bitfield on RHS: 17

XXX max expression depth: 2
breakdown:
   depth: 0, occurrence: 25
   depth: 1, occurrence: 1
   depth: 2, occurrence: 1

XXX total number of pointers: 27

XXX times a variable address is taken: 7
XXX times a pointer is dereferenced on RHS: 4
breakdown:
   depth: 1, occurrence: 1
   depth: 2, occurrence: 3
XXX times a pointer is dereferenced on LHS: 13
breakdown:
   depth: 1, occurrence: 13
XXX times a pointer is compared with null: 0
XXX times a pointer is compared with address of another variable: 1
XXX times a pointer is compared with another pointer: 1
XXX times a pointer is qualified to be dereferenced: 35

XXX max dereference level: 2
breakdown:
   level: 0, occurrence: 0
   level: 1, occurrence: 41
   level: 2, occurrence: 4
XXX number of pointers point to pointers: 8
XXX number of pointers point to scalars: 13
XXX number of pointers point to structs: 6
XXX percent of pointers has null in alias set: 37
XXX average alias set size: 1.15

XXX times a non-volatile is read: 76
XXX times a non-volatile is write: 45
XXX times a volatile is read: 0
XXX    times read thru a pointer: 0
XXX times a volatile is write: 0
XXX    times written thru a pointer: 0
XXX times a volatile is available for access: 0
XXX percentage of non-volatile access: 100

XXX forward jumps: 0
XXX backward jumps: 1

XXX stmts: 79

XXX percentage a fresh-made variable is used: 28.4
XXX percentage an existing variable is used: 71.6
********************* end of statistics **********************/