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 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, | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue