void fold_expr_assign_compound(expr *e, symtable *stab) { const char *const desc = "compound assignment"; #define lvalue e->lhs fold_inc_writes_if_sym(lvalue, stab); fold_expr_nodecay(e->lhs, stab); FOLD_EXPR(e->rhs, stab); fold_check_expr(e->lhs, FOLD_CHK_NO_ST_UN, desc); fold_check_expr(e->rhs, FOLD_CHK_NO_ST_UN, desc); /* skip the addr we inserted */ if(!expr_must_lvalue(lvalue, desc)){ /* prevent ICE from type_size(vla), etc */ e->tree_type = lvalue->tree_type; return; } expr_assign_const_check(lvalue, &e->where); fold_check_restrict(lvalue, e->rhs, desc, &e->where); UCC_ASSERT(op_can_compound(e->bits.compoundop.op), "non-compound op in compound expr"); /*expr_promote_int_if_smaller(&e->lhs, stab); * lhs int promotion is handled in code-gen */ expr_promote_int_if_smaller(&e->rhs, stab); { type *tlhs, *trhs; type *resolved = op_required_promotion( e->bits.compoundop.op, lvalue, e->rhs, &e->where, desc, &tlhs, &trhs); if(tlhs){ /* must cast the lvalue, then down cast once the operation is done * special handling for expr_kind(e->lhs, cast) is done in the gen-code */ e->bits.compoundop.upcast_ty = tlhs; }else if(trhs){ fold_insert_casts(trhs, &e->rhs, stab); } e->tree_type = lvalue->tree_type; (void)resolved; /*type_free_1(resolved); XXX: memleak */ } /* type check is done in op_required_promotion() */ #undef lvalue }
void fold_expr_assign_compound(expr *e, symtable *stab) { expr *const lvalue = e->lhs; fold_inc_writes_if_sym(lvalue, stab); fold_expr_no_decay(e->lhs, stab); FOLD_EXPR(e->rhs, stab); fold_check_expr(e->lhs, FOLD_CHK_NO_ST_UN, "compound assignment"); fold_check_expr(e->rhs, FOLD_CHK_NO_ST_UN, "compound assignment"); /* skip the addr we inserted */ expr_must_lvalue(lvalue); expr_assign_const_check(lvalue, &e->where); fold_check_restrict(lvalue, e->rhs, "compound assignment", &e->where); UCC_ASSERT(op_can_compound(e->op), "non-compound op in compound expr"); { type *tlhs, *trhs; type *resolved = op_required_promotion(e->op, lvalue, e->rhs, &e->where, &tlhs, &trhs); if(tlhs){ /* must cast the lvalue, then down cast once the operation is done * special handling for expr_kind(e->lhs, cast) is done in the gen-code */ fold_insert_casts(tlhs, &e->lhs, stab); /* casts may be inserted anyway, and don't want to rely on * .implicit_cast stuff */ e->bits.compound_upcast = 1; }else if(trhs){ fold_insert_casts(trhs, &e->rhs, stab); } e->tree_type = lvalue->tree_type; (void)resolved; /*type_free_1(resolved); XXX: memleak */ } /* type check is done in op_required_promotion() */ }