[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc-bugs
Subject:    Division by zero in store_split_bit_field
From:       Jakub Jelinek <jakub () redhat ! com>
Date:       2000-03-31 9:15:19
[Download RAW message or body]

Hi!

As I'm not 100% familiar with the front end, I thought it might be quicker
to ask about this:

Following program causes division by zero on sparc64-linux in:
#0  0x700dd208 in .udiv () at soinit.c:59
#1  0x344ef0 in __udivdi3 (n=0, d=0)
#2  0xa4850 in store_split_bit_field (op0=0x70162f00, bitsize=64, bitpos=0, \
value=0x70162a60, align=0)  at /usr/src/egcs-rw/gcc/expmed.c:849
#3  0xa3e04 in store_fixed_bit_field (op0=0x70162f00, offset=0, bitsize=64, bitpos=0, \
value=0x70162a60, struct_align=0)  at /usr/src/egcs-rw/gcc/expmed.c:685
#4  0xa3b14 in store_bit_field (str_rtx=0x70162f00, bitsize=64, bitnum=0, \
fieldmode=DImode, value=0x70162a60, align=0,  total_size=576) at \
/usr/src/egcs-rw/gcc/expmed.c:620 #5  0x84a48 in store_field (target=0x70162f00, \
bitsize=64, bitpos=0, mode=DImode, exp=0x70162bc0, value_mode=VOIDmode,  unsignedp=1, \
align=0, total_size=576, alias_set=3) at /usr/src/egcs-rw/gcc/expr.c:4867 #6  0x7fa38 \
in expand_assignment (to=0x70162b80, from=0x70162bc0, want_value=0, suggest_reg=1)  \
at /usr/src/egcs-rw/gcc/expr.c:3477 #7  0x9027c in expand_expr (exp=0x70162be0, \
target=0x0, tmode=VOIDmode, modifier=EXPAND_NORMAL)  at \
/usr/src/egcs-rw/gcc/expr.c:8166 #8  0x63044 in expand_expr_stmt (exp=0x70162be0) at \
/usr/src/egcs-rw/gcc/stmt.c:1866 #9  0x341b2c in expand_stmt_with_iterators_1 \
(stmt=0x70162be0, iter_list=0x0) at /usr/src/egcs-rw/gcc/c-iterate.c:168 #10 0x341af4 \
in iterator_expand (stmt=0x70162be0) at /usr/src/egcs-rw/gcc/c-iterate.c:158 #11 \
0x30a888 in yyparse () at c-parse.y:1709 #12 0x15620 in compile_file (name=0x700242e8 \
"spec.i") at /usr/src/egcs-rw/gcc/toplev.c:2462 #13 0x1bf9c in main (argc=18, \
argv=0xeffff9f4) at /usr/src/egcs-rw/gcc/toplev.c:4955

(this particular dump is from sparc-linux -> sparc64-linux cross but the
same happens in native sparc64-linux).
The issue is that expand_assignment gets 0 alignment returned from \
get_inner_reference and passes it down up to store_split_bit_field which divides by \
the alignment.
If I change the aligned(32) to aligned(16) (BIGGEST_ALIGNMENT on
sparc64 is 128, ie. right 16 bytes), then get_inner_reference returns
64 and everything is fine. aligned(8) and lower works as well.
The place where it sets alignment to 0 if aligned(32) is:
5025              if (! host_integerp (offset, 0))
5026                alignment = MIN (alignment, DECL_OFFSET_ALIGN (field));
because in that moment:
(gdb) p field->decl.u1
$1 = {i = 70368744177664, f = 16384, a = {align = 64, off_align = 0}}
off_align is 0.

Anyone knows what's going on?
I can provide more info on request.

struct _pthread_descr_struct {
  void *p_foo [40];
  void ** p_specific[((1024 + 32 - 1)    / 32)];  
} __attribute__ ((aligned(32)));  
typedef struct _pthread_descr_struct *pthread_descr;
register struct _pthread_descr_struct *__thread_self __asm__("%g6");
static inline pthread_descr thread_self (void)
{
  return __thread_self;
}
int __pthread_setspecific(unsigned int key, const void * pointer)
{
  pthread_descr self = thread_self();
  unsigned int idx1st, idx2nd;
  idx1st = key / 32;
  idx2nd = key % 32;
  if (__thread_self-> p_specific[idx1st] == ((void *)0)) {
    void *newp = (void *)pointer;
    __thread_self-> p_specific[idx1st] = ( newp);
  }
  return 0;
}

Cheers,
    Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.99-pre2 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic