This is gcc-4.2.0-0.20060806r115974

Source:

----------------------------------------------------------------------
typedef struct descr *descr_t;
typedef descr_t *value_t;
struct descr {descr_t descr;};
typedef struct {descr_t descr; value_t fields[2];} object_t_2;
value_t **marked_top, **marked_limit;
void gc(void);
object_t_2 pair_12138, list_12140, pair_12196, list_12198, pair_12319,
           list_12321, list_12328, pair_12334, pair_12336, record_12376,
           pair_12413, list_12415, record_12420;
value_t symbol_7584, symbol_12137, symbol_7525, symbol_11238, symbol_7778,
        symbol_12326, symbol_11917, symbol_7927, symbol_7525, symbol_11238,
        symbol_12335, CheckArity, symbol_7584, symbol_7583, BadArguments;

static inline void
set_global_field(value_t obj, int i, value_t value) {
   value_t *ptr = (value_t *)obj + i + 1;
   *ptr = value;
   *marked_top++ = ptr;
   if (marked_limit < marked_top) gc();
}

int test(void) {
   set_global_field(&pair_12138.descr, 0, symbol_7584);
   set_global_field(&list_12140.descr, 0, symbol_12137);
   set_global_field(&pair_12196.descr, 0, symbol_7525);
   set_global_field(&list_12198.descr, 0, symbol_7778);
   set_global_field(&pair_12319.descr, 1, symbol_11238);
   set_global_field(&list_12321.descr, 0, symbol_7778);
   set_global_field(&list_12328.descr, 0, symbol_11917);
   set_global_field(&pair_12334.descr, 0, symbol_7525);
   set_global_field(&pair_12334.descr, 1, symbol_11238);
   set_global_field(&pair_12336.descr, 0, symbol_12335);
   set_global_field(&record_12376.descr, 0, CheckArity);
   set_global_field(&pair_12413.descr, 0, symbol_7584);
   set_global_field(&list_12415.descr, 0, symbol_7583);
   set_global_field(&record_12420.descr, 0, BadArguments);
   return 0;
}
----------------------------------------------------------------------

When compiled with gcc -S -O2 source.c, the last set_global_field call
generates the following code:

        leal    4(%edx), %eax
        cmpl    marked_limit, %eax
        movl    BadArguments, %ecx
        movl    $record_12420+4, (%edx)
        movl    %eax, marked_top
        jbe     .L28
        movl    %ecx, record_12420+4
        call    gc
.L28:
        leave
        xorl    %eax, %eax
        ret

The assignment of BadArguments to the field of record_12420
is performed only in one branch, while it should be done
unconditionally.

Reducing the number of set_global_field calls avoids the bug.

-- 
   __("<         Marcin Kowalczyk
   \__/       [EMAIL PROTECTED]
    ^^     http://qrnik.knm.org.pl/~qrczak/

Reply via email to