diff --git a/lang/cem/cemcom/ch7.c b/lang/cem/cemcom/ch7.c index d73052fc0..0cb13fb56 100644 --- a/lang/cem/cemcom/ch7.c +++ b/lang/cem/cemcom/ch7.c @@ -324,6 +324,7 @@ ch7asgn(expp, oper, expr) EVAL should however take care of evaluating (typeof (f op e))f */ int fund = (*expp)->ex_type->tp_fund; + struct type *tp; /* We expect an lvalue */ if (!(*expp)->ex_lvalue) { @@ -333,6 +334,7 @@ ch7asgn(expp, oper, expr) } if (oper == '=') { ch7cast(&expr, oper, (*expp)->ex_type); + tp = expr->ex_type; } else { /* turn e into e' where typeof(e') = typeof (f op e) */ struct expr *extmp = intexpr((arith)0, INT); @@ -341,13 +343,14 @@ ch7asgn(expp, oper, expr) extmp->ex_lvalue = 1; extmp->ex_type = (*expp)->ex_type; ch7bin(&extmp, oper, expr); - /* note that ch7bin creates a tree of the expression + /* Note that ch7bin creates a tree of the expression ((typeof (f op e))f op (typeof (f op e))e), - where f ~ extmp and e ~ expr; - we have to use (typeof (f op e))e + where f ~ extmp and e ~ expr. + We want to use (typeof (f op e))e. Ch7bin does not create a tree if both operands were illegal or constants! */ + tp = extmp->ex_type; /* perform the arithmetic in type tp */ if (extmp->ex_class == Oper) { expr = extmp->OP_RIGHT; extmp->OP_RIGHT = NILEXPR; @@ -356,13 +359,17 @@ ch7asgn(expp, oper, expr) else expr = extmp; } + #ifndef NOBITFIELD if (fund == FIELD) *expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr); else -#endif NOBITFIELD *expp = new_oper((*expp)->ex_type, *expp, oper, expr); - (*expp)->OP_TYPE = expr->ex_type; /* for EVAL() */ +#else NOBITFIELD + *expp = new_oper((*expp)->ex_type, *expp, oper, expr); +#endif NOBITFIELD + + (*expp)->OP_TYPE = tp; /* for EVAL() */ } /* Some interesting (?) questions answered. diff --git a/lang/cem/cemcom/ch7bin.c b/lang/cem/cemcom/ch7bin.c index 970e8b764..c34e1c219 100644 --- a/lang/cem/cemcom/ch7bin.c +++ b/lang/cem/cemcom/ch7bin.c @@ -156,7 +156,8 @@ ch7bin(expp, oper, expr) case RIGHTAB: opnd2integral(expp, oper); opnd2integral(&expr, oper); - ch7cast(&expr, oper, int_type); /* leftop should be int */ + fund = arithbalance(expp, oper, &expr); /* ch. 7.5 */ + ch7cast(&expr, oper, int_type); /* cvt. rightop to int */ non_commutative_binop(expp, oper, expr); break; case '<': diff --git a/lang/cem/cemcom/eval.c b/lang/cem/cemcom/eval.c index 2ce3f8256..ac14d2d23 100644 --- a/lang/cem/cemcom/eval.c +++ b/lang/cem/cemcom/eval.c @@ -35,7 +35,7 @@ #include "atw.h" #define CRASH() crash("EVAL: CRASH at line %u", __LINE__) -#define roundup(n) ((n) < word_size ? word_size : (n)) +#define toword(n) ((n) < word_size ? word_size : (n)) char *symbol2str(); char *long2str(); @@ -374,6 +374,10 @@ EVAL(expr, val, code, true_label, false_label) case ANDAB: case XORAB: case ORAB: + { + arith old_offset; + arith tmpvar = tmp_pointer_var(&old_offset); + #ifndef NOBITFIELD if (leftop->ex_type->tp_fund == FIELD) { eval_field(expr, code); @@ -381,34 +385,29 @@ EVAL(expr, val, code, true_label, false_label) } #endif NOBITFIELD if (leftop->ex_class != Value) { - arith old_offset; - arith tmpvar = tmp_pointer_var(&old_offset); - EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL); C_lal(tmpvar); C_sti(pointer_size); C_lal(tmpvar); C_loi(pointer_size); C_loi(leftop->ex_type->tp_size); - conversion(leftop->ex_type, tp); - EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL); - assop(tp, oper); - conversion(tp, leftop->ex_type); - if (gencode) - C_dup(roundup(leftop->ex_type->tp_size)); + } + else { + load_val(leftop, RVAL); + } + conversion(leftop->ex_type, tp); + EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL); + assop(tp, oper); + conversion(tp, leftop->ex_type); + if (gencode) + C_dup(toword(leftop->ex_type->tp_size)); + if (leftop->ex_class != Value) { C_lal(tmpvar); C_loi(pointer_size); C_sti(leftop->ex_type->tp_size); free_tmp_var(old_offset); } - else { - load_val(leftop, RVAL); - conversion(leftop->ex_type, tp); - EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL); - assop(tp, oper); - conversion(tp, leftop->ex_type); - if (gencode) - C_dup(roundup(leftop->ex_type->tp_size)); + else { store_val( &(leftop->ex_object.ex_value), leftop->ex_type @@ -417,6 +416,7 @@ EVAL(expr, val, code, true_label, false_label) if (gencode) conversion(leftop->ex_type, expr->ex_type); break; + } case '(': { register struct expr *expr;