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++; LineNumber++;
ch = quoted(ch); ch = quoted(ch);
} }
if (ch >= 128) ch -= 256;
val = val*256 + ch; val = val*256 + ch;
size++; size++;
LoadChar(ch); LoadChar(ch);

View file

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

View file

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

View file

@ -99,13 +99,19 @@ eval_field(expr, code)
C_sti(pointer_size); C_sti(pointer_size);
C_loi(asize); 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); 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_sri(asize);
C_loc(fd->fd_mask); }
C_and(asize);
if (code == TRUE && (op == POSTINCR || op == POSTDECR)) if (code == TRUE && (op == POSTINCR || op == POSTDECR))
C_dup(asize); C_dup(asize);
conversion(atype, rightop->ex_type); conversion(atype, rightop->ex_type);

View file

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