unsigned but-fields were sometimes sign-extended when converted to int

This commit is contained in:
ceriel 1990-05-18 10:29:57 +00:00
parent 74147d2b4a
commit c4dabcd9a4
2 changed files with 6 additions and 8 deletions

View file

@ -592,19 +592,17 @@ field2arith(expp)
*/ */
register struct type *tp = (*expp)->ex_type->tp_up; register struct type *tp = (*expp)->ex_type->tp_up;
register struct field *fd = (*expp)->ex_type->tp_field; register struct field *fd = (*expp)->ex_type->tp_field;
register struct type *atype = (tp->tp_unsigned
&& fd->fd_width >= 8 * word_size)
? uword_type
: word_type;
(*expp)->ex_type = atype; (*expp)->ex_type = word_type;
if (tp->tp_unsigned) { /* don't worry about the sign bit */ if (tp->tp_unsigned) { /* don't worry about the sign bit */
if (fd->fd_width >= 8 * word_size)
(*expp)->ex_type = uword_type;
ch3bin(expp, RIGHT, intexpr((arith)fd->fd_shift, INT)); ch3bin(expp, RIGHT, intexpr((arith)fd->fd_shift, INT));
ch3bin(expp, '&', intexpr(fd->fd_mask, INT)); ch3bin(expp, '&', intexpr(fd->fd_mask, INT));
} }
else { /* take care of the sign bit: sign extend if needed */ else { /* take care of the sign bit: sign extend if needed */
arith bits_in_type = atype->tp_size * 8; arith bits_in_type = word_size * 8;
ch3bin(expp, LEFT, ch3bin(expp, LEFT,
intexpr(bits_in_type - fd->fd_width - fd->fd_shift, intexpr(bits_in_type - fd->fd_width - fd->fd_shift,

View file

@ -82,7 +82,7 @@ eval_field(expr, code)
StoreLocal(tmpvar, pointer_size); StoreLocal(tmpvar, pointer_size);
C_loi(word_size); C_loi(word_size);
} }
if (atype->tp_unsigned) { if (tp->tp_unsigned) {
C_loc((arith)fd->fd_shift); C_loc((arith)fd->fd_shift);
C_sru(word_size); C_sru(word_size);
C_loc(fd->fd_mask); C_loc(fd->fd_mask);
@ -117,7 +117,7 @@ eval_field(expr, code)
the bit field (i.e. the value that is got on the bit field (i.e. the value that is got on
retrieval) is on top of stack. retrieval) is on top of stack.
*/ */
if (atype->tp_unsigned == 0) { /* sign extension */ if (tp->tp_unsigned == 0) { /* sign extension */
register arith shift = word_size * 8 - fd->fd_width; register arith shift = word_size * 8 - fd->fd_width;
C_loc(shift); C_loc(shift);