bug fixes:

- assignment operators for bit fields were wrong
- some conversions for characters were wrong
- result of assignment operator sometimes had wrong size
- character constant \377 was 255, not -1
- string constant generation was clumsy
This commit is contained in:
ceriel 1987-02-23 13:08:54 +00:00
parent af2b497fdf
commit ca1655c25e
5 changed files with 82 additions and 42 deletions

View file

@ -309,6 +309,7 @@ firstline:
LineNumber++;
ch = quoted(ch);
}
if (ch >= 128) ch -= 256;
val = val*256 + ch;
size++;
LoadChar(ch);

View file

@ -32,22 +32,35 @@ conversion(from_type, to_type)
if (from_type == to_type) /* a little optimisation */
return;
if (to_size < word_size) to_size = word_size;
switch (fundamental(from_type)) {
case T_SIGNED:
switch (fundamental(to_type)) {
case T_SIGNED:
C_loc(from_size);
C_loc(to_size < word_size ? word_size : to_size);
C_loc(to_size);
C_cii();
break;
case T_UNSIGNED:
C_loc(from_size < word_size ? word_size : from_size);
C_loc(to_size < word_size ? word_size : to_size);
if (from_size < word_size) {
C_loc(from_size);
C_loc(word_size);
C_cii();
from_size = word_size;
}
C_loc(from_size);
C_loc(to_size);
C_ciu();
break;
#ifndef NOFLOAT
case T_FLOATING:
C_loc(from_size < word_size ? word_size : from_size);
if (from_size < word_size) {
C_loc(from_size);
C_loc(word_size);
C_cii();
from_size = word_size;
}
C_loc(from_size);
C_loc(to_size);
C_cif();
break;
@ -55,8 +68,9 @@ conversion(from_type, to_type)
}
break;
case T_UNSIGNED:
C_loc(from_size < word_size ? word_size : from_size);
C_loc(to_size < word_size ? word_size : to_size);
if (from_size < word_size) from_size = word_size;
C_loc(from_size);
C_loc(to_size);
switch (fundamental(to_type)) {
case T_SIGNED:
C_cui();
@ -74,7 +88,7 @@ conversion(from_type, to_type)
#ifndef NOFLOAT
case T_FLOATING:
C_loc(from_size);
C_loc(to_size < word_size ? word_size : to_size);
C_loc(to_size);
switch (fundamental(to_type)) {
case T_SIGNED:
C_cfi();

View file

@ -395,32 +395,42 @@ EVAL(expr, val, code, true_label, false_label)
}
}
if (newcode) {
conversion(left->ex_type, tp);
if (gencode && (oper == POSTINCR ||
oper == POSTDECR))
C_dup(tp->tp_size);
C_dup(ATW(left->ex_type->tp_size));
conversion(left->ex_type, tp);
}
EVAL(right, RVAL, newcode, NO_LABEL, NO_LABEL);
if (newcode) {
int dupval = gencode && oper != POSTINCR &&
oper != POSTDECR;
assop(tp, oper);
if (gencode && oper != POSTINCR &&
oper != POSTDECR)
C_dup(tp->tp_size);
conversion(tp, left->ex_type);
}
if (newcode && compl == 0)
store_val(&(left->ex_object.ex_value),
left->ex_type);
else
if (compl == 1) {
EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL);
if (newcode) C_sti(left->ex_type->tp_size);
}
else if (newcode) {
C_lal(tmp); /* always init'd */
C_loi(pointer_size);
C_sti(left->ex_type->tp_size);
free_tmp_var(old_offset);
if (compl == 0) {
store_val(&(left->ex_object.ex_value),
left->ex_type);
if (dupval) load_val(left, RVAL);
}
else if (compl == 1) {
EVAL(left, LVAL,1, NO_LABEL, NO_LABEL);
C_sti(left->ex_type->tp_size);
if (dupval) {
EVAL(left, LVAL, 1, NO_LABEL,
NO_LABEL);
C_loi(left->ex_type->tp_size);
}
}
else {
C_lal(tmp); /* always init'd */
C_loi(pointer_size);
C_sti(left->ex_type->tp_size);
if (dupval) {
C_lal(tmp);
C_loi(pointer_size);
C_loi(left->ex_type->tp_size);
}
free_tmp_var(old_offset);
}
}
break;
}

View file

@ -99,13 +99,19 @@ eval_field(expr, code)
C_sti(pointer_size);
C_loi(asize);
}
C_loc((arith)fd->fd_shift);
if (atype->tp_unsigned)
if (atype->tp_unsigned) {
C_loc((arith)fd->fd_shift);
C_sru(asize);
else
C_loc(fd->fd_mask);
C_and(asize);
}
else {
arith bits_in_type = asize * 8;
C_loc(bits_in_type - (fd->fd_width + fd->fd_shift));
C_sli(asize);
C_loc(bits_in_type - fd->fd_width);
C_sri(asize);
C_loc(fd->fd_mask);
C_and(asize);
}
if (code == TRUE && (op == POSTINCR || op == POSTDECR))
C_dup(asize);
conversion(atype, rightop->ex_type);

View file

@ -4,6 +4,7 @@
#include "nofloat.h"
#include <em.h>
#include "debug.h"
#include <alloc.h>
#include "nobitfield.h"
#include "arith.h"
#include "align.h"
@ -469,12 +470,11 @@ ch_array(tpp, ex)
struct expr *ex;
{
register struct type *tp = *tpp;
register arith length;
register char *s = ex->SG_VALUE;
register arith ntopad;
register arith length = ex->SG_LEN;
char *s;
arith ntopad;
ASSERT(ex->ex_class == String);
length = ex->SG_LEN;
if (tp->tp_size == (arith)-1) {
/* set the dimension */
tp = *tpp = construct_type(ARRAY, tp->tp_up, length);
@ -497,19 +497,28 @@ ch_array(tpp, ex)
ntopad = align(dim, word_align) - length;
}
/* throw out the characters of the already prepared string */
while (length-- > 0)
C_con_ucon(long2str((long)*s++ & 0xFF, 10), (arith)1);
/* pad the allocated memory (the alignment has been calculated) */
while (ntopad-- > 0)
con_nullbyte();
s = Malloc((int) (length + ntopad));
clear(s, (int) (length + ntopad));
strncpy(s, ex->SG_VALUE, (int) length);
str_cst(s, (int) (length + ntopad));
free(s);
}
/* As long as some parts of the pipeline cannot handle very long string
constants, string constants are written out in chunks
*/
str_cst(str, len)
register char *str;
register int len;
{
while (len-- > 0)
C_con_ucon(long2str((long)*str++ & 0xFF, 10), (arith)1);
arith chunksize = ((127 + word_size) / word_size) * word_size;
while (len > chunksize) {
C_con_scon(str, chunksize);
len -= chunksize;
str += chunksize;
}
C_con_scon(str, (arith) len);
}
#ifndef NOBITFIELD