unsigned but-fields were sometimes sign-extended when converted to int
This commit is contained in:
parent
74147d2b4a
commit
c4dabcd9a4
2 changed files with 6 additions and 8 deletions
|
@ -592,19 +592,17 @@ field2arith(expp)
|
|||
*/
|
||||
register struct type *tp = (*expp)->ex_type->tp_up;
|
||||
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 (fd->fd_width >= 8 * word_size)
|
||||
(*expp)->ex_type = uword_type;
|
||||
ch3bin(expp, RIGHT, intexpr((arith)fd->fd_shift, INT));
|
||||
ch3bin(expp, '&', intexpr(fd->fd_mask, INT));
|
||||
}
|
||||
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,
|
||||
intexpr(bits_in_type - fd->fd_width - fd->fd_shift,
|
||||
|
|
|
@ -82,7 +82,7 @@ eval_field(expr, code)
|
|||
StoreLocal(tmpvar, pointer_size);
|
||||
C_loi(word_size);
|
||||
}
|
||||
if (atype->tp_unsigned) {
|
||||
if (tp->tp_unsigned) {
|
||||
C_loc((arith)fd->fd_shift);
|
||||
C_sru(word_size);
|
||||
C_loc(fd->fd_mask);
|
||||
|
@ -117,7 +117,7 @@ eval_field(expr, code)
|
|||
the bit field (i.e. the value that is got on
|
||||
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;
|
||||
|
||||
C_loc(shift);
|
||||
|
|
Loading…
Reference in a new issue