* */
| 112 | * |
| 113 | */ |
| 114 | StatementAssign * |
| 115 | StatementAssign::make_random(CGContext &cg_context, const Type* type, const CVQualifiers* qf) |
| 116 | { |
| 117 | // decide assignment operator |
| 118 | eAssignOps op = AssignOpsProbability(type); |
| 119 | // bool stand_alone_assign = false; |
| 120 | |
| 121 | // decide type |
| 122 | if (type == NULL) { |
| 123 | // stand_alone_assign = true; |
| 124 | type = Type::SelectLType(!cg_context.get_effect_context().is_side_effect_free(), op); |
| 125 | } |
| 126 | assert(!type->is_const_struct_union()); |
| 127 | |
| 128 | FactMgr* fm = get_fact_mgr(&cg_context); |
| 129 | assert(fm); |
| 130 | // pre-generation initializations |
| 131 | Lhs *lhs = NULL; |
| 132 | Expression *e = NULL; |
| 133 | Effect running_eff_context(cg_context.get_effect_context()); |
| 134 | Effect rhs_accum, lhs_accum; |
| 135 | CGContext rhs_cg_context(cg_context, running_eff_context, &rhs_accum); |
| 136 | CVQualifiers qfer; |
| 137 | if (qf) qfer = *qf; |
| 138 | |
| 139 | if (need_no_rhs(op)) { |
| 140 | e = Constant::make_int(1); |
| 141 | // if we are creating standalone statements like x++, any qualifers fit |
| 142 | if (qf == NULL) qfer.wildcard = true; |
| 143 | } |
| 144 | else if (CGOptions::strict_volatile_rule()) { |
| 145 | if (type->is_volatile_struct_union()) |
| 146 | return NULL; |
| 147 | |
| 148 | e = Expression::make_random(rhs_cg_context, type, qf); |
| 149 | ERROR_GUARD_AND_DEL1(NULL, e); |
| 150 | if (!qf) { |
| 151 | qfer = e->get_qualifiers(); |
| 152 | // lhs should not has "const" qualifier |
| 153 | qfer.accept_stricter = true; |
| 154 | } |
| 155 | |
| 156 | // for compound assignment, generate LHS in the effect context of RHS |
| 157 | if (op != eSimpleAssign) { |
| 158 | running_eff_context.add_effect(rhs_accum); |
| 159 | // for now, just use non-volatile as LHS for compound assignments |
| 160 | qfer.set_volatile(false); |
| 161 | } |
| 162 | running_eff_context.add_effect(rhs_accum); |
| 163 | // if the rhs is volatile, almost came from dereferencing a pointer, |
| 164 | // then make sure lhs is not a vol |
| 165 | if (qfer.get_volatiles().size() && qfer.is_volatile()) |
| 166 | qfer.set_volatile(false); |
| 167 | } |
| 168 | else { |
| 169 | e = Expression::make_random(rhs_cg_context, type, qf); |
| 170 | ERROR_GUARD_AND_DEL1(NULL, e); |
| 171 | if (!qf) { |
nothing calls this directly
no test coverage detected