corrected the treatment of the <<= and >>= operators

This commit is contained in:
erikb 1986-09-10 10:23:26 +00:00
parent b9bce39f1e
commit ecf5219493
3 changed files with 32 additions and 24 deletions

View file

@ -324,6 +324,7 @@ ch7asgn(expp, oper, expr)
EVAL should however take care of evaluating (typeof (f op e))f EVAL should however take care of evaluating (typeof (f op e))f
*/ */
int fund = (*expp)->ex_type->tp_fund; int fund = (*expp)->ex_type->tp_fund;
struct type *tp;
/* We expect an lvalue */ /* We expect an lvalue */
if (!(*expp)->ex_lvalue) { if (!(*expp)->ex_lvalue) {
@ -333,6 +334,7 @@ ch7asgn(expp, oper, expr)
} }
if (oper == '=') { if (oper == '=') {
ch7cast(&expr, oper, (*expp)->ex_type); ch7cast(&expr, oper, (*expp)->ex_type);
tp = expr->ex_type;
} }
else { /* turn e into e' where typeof(e') = typeof (f op e) */ else { /* turn e into e' where typeof(e') = typeof (f op e) */
struct expr *extmp = intexpr((arith)0, INT); struct expr *extmp = intexpr((arith)0, INT);
@ -341,13 +343,14 @@ ch7asgn(expp, oper, expr)
extmp->ex_lvalue = 1; extmp->ex_lvalue = 1;
extmp->ex_type = (*expp)->ex_type; extmp->ex_type = (*expp)->ex_type;
ch7bin(&extmp, oper, expr); 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), ((typeof (f op e))f op (typeof (f op e))e),
where f ~ extmp and e ~ expr; where f ~ extmp and e ~ expr.
we have to use (typeof (f op e))e We want to use (typeof (f op e))e.
Ch7bin does not create a tree if both operands Ch7bin does not create a tree if both operands
were illegal or constants! were illegal or constants!
*/ */
tp = extmp->ex_type; /* perform the arithmetic in type tp */
if (extmp->ex_class == Oper) { if (extmp->ex_class == Oper) {
expr = extmp->OP_RIGHT; expr = extmp->OP_RIGHT;
extmp->OP_RIGHT = NILEXPR; extmp->OP_RIGHT = NILEXPR;
@ -356,13 +359,17 @@ ch7asgn(expp, oper, expr)
else else
expr = extmp; expr = extmp;
} }
#ifndef NOBITFIELD #ifndef NOBITFIELD
if (fund == FIELD) if (fund == FIELD)
*expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr); *expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr);
else else
#endif NOBITFIELD
*expp = new_oper((*expp)->ex_type, *expp, oper, expr); *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. /* Some interesting (?) questions answered.

View file

@ -156,7 +156,8 @@ ch7bin(expp, oper, expr)
case RIGHTAB: case RIGHTAB:
opnd2integral(expp, oper); opnd2integral(expp, oper);
opnd2integral(&expr, 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); non_commutative_binop(expp, oper, expr);
break; break;
case '<': case '<':

View file

@ -35,7 +35,7 @@
#include "atw.h" #include "atw.h"
#define CRASH() crash("EVAL: CRASH at line %u", __LINE__) #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 *symbol2str();
char *long2str(); char *long2str();
@ -374,6 +374,10 @@ EVAL(expr, val, code, true_label, false_label)
case ANDAB: case ANDAB:
case XORAB: case XORAB:
case ORAB: case ORAB:
{
arith old_offset;
arith tmpvar = tmp_pointer_var(&old_offset);
#ifndef NOBITFIELD #ifndef NOBITFIELD
if (leftop->ex_type->tp_fund == FIELD) { if (leftop->ex_type->tp_fund == FIELD) {
eval_field(expr, code); eval_field(expr, code);
@ -381,34 +385,29 @@ EVAL(expr, val, code, true_label, false_label)
} }
#endif NOBITFIELD #endif NOBITFIELD
if (leftop->ex_class != Value) { if (leftop->ex_class != Value) {
arith old_offset;
arith tmpvar = tmp_pointer_var(&old_offset);
EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL); EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
C_lal(tmpvar); C_lal(tmpvar);
C_sti(pointer_size); C_sti(pointer_size);
C_lal(tmpvar); C_lal(tmpvar);
C_loi(pointer_size); C_loi(pointer_size);
C_loi(leftop->ex_type->tp_size); C_loi(leftop->ex_type->tp_size);
conversion(leftop->ex_type, tp); }
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL); else {
assop(tp, oper); load_val(leftop, RVAL);
conversion(tp, leftop->ex_type); }
if (gencode) conversion(leftop->ex_type, tp);
C_dup(roundup(leftop->ex_type->tp_size)); 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_lal(tmpvar);
C_loi(pointer_size); C_loi(pointer_size);
C_sti(leftop->ex_type->tp_size); C_sti(leftop->ex_type->tp_size);
free_tmp_var(old_offset); free_tmp_var(old_offset);
} }
else { 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));
store_val( store_val(
&(leftop->ex_object.ex_value), &(leftop->ex_object.ex_value),
leftop->ex_type leftop->ex_type
@ -417,6 +416,7 @@ EVAL(expr, val, code, true_label, false_label)
if (gencode) if (gencode)
conversion(leftop->ex_type, expr->ex_type); conversion(leftop->ex_type, expr->ex_type);
break; break;
}
case '(': case '(':
{ {
register struct expr *expr; register struct expr *expr;