Expression * ExpressionFuncall::make_random(CGContext &cg_context, const Type* type, const TypeQualifiers* qfer) { Expression *e = 0; bool std_func = ExpressionFunctionProbability(cg_context); // unary/binary "functions" produce scalar types only if (type && (type->eType != eSimple || type->simple_type == eVoid)) std_func = false; Effect effect_accum = cg_context.get_accum_effect(); Effect effect_stm = cg_context.get_effect_stm(); FactMgr* fm = get_fact_mgr(&cg_context); vector<const Fact*> facts_copy = fm->global_facts; FunctionInvocation *fi = FunctionInvocation::make_random(std_func, cg_context, type, qfer); if (fi->failed) { // if it's a invalid invocation, (see FunctionInvocationUser::revisit) // restore the env, and replace invocation with a simple var cg_context.reset_effect_accum(effect_accum); cg_context.reset_effect_stm(effect_stm); fm->restore_facts(facts_copy); e = ExpressionVariable::make_random(cg_context, type, qfer); delete fi; } else { e = new ExpressionFuncall(*fi); } return e; }
void StatementFor::post_loop_analysis(CGContext& cg_context, vector<const Fact*>& pre_facts, Effect& pre_effect) { FactMgr* fm = get_fact_mgr(&cg_context); assert(fm); // if the control reached the end of this for-loop with must-return body, it means // the loop is never entered. restore facts to pre-loop env fm->global_facts = fm->map_facts_in[&body]; if (body.must_return()) { fm->restore_facts(pre_facts); } // add forward edges introduced by "break" for (size_t i=0; i<body.break_stms.size(); i++) { const StatementBreak* stm = dynamic_cast<const StatementBreak*>(body.break_stms[i]); fm->create_cfg_edge(stm, this, true, false); FactMgr::merge_jump_facts(fm->global_facts, fm->map_facts_out[stm]); } // compute accumulated effect set_accumulated_effect_after_block(pre_effect, &body, cg_context); }