This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Division by zero in store_split_bit_field


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)
___________________________________________________________________

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]