* */
| 55 | * |
| 56 | */ |
| 57 | ExpressionVariable * |
| 58 | ExpressionVariable::make_random(CGContext &cg_context, const Type* type, const CVQualifiers* qfer, bool as_param, bool as_return) |
| 59 | { |
| 60 | DEPTH_GUARD_BY_TYPE_RETURN(dtExpressionVariable, NULL); |
| 61 | Function *curr_func = cg_context.get_current_func(); |
| 62 | FactMgr* fm = get_fact_mgr_for_func(curr_func); |
| 63 | vector<const Variable*> dummy; |
| 64 | |
| 65 | // save current effects, in case we need to reset |
| 66 | Effect eff_accum = cg_context.get_accum_effect(); |
| 67 | Effect eff_stmt = cg_context.get_effect_stm(); |
| 68 | |
| 69 | ExpressionVariable *ev = 0; |
| 70 | do { |
| 71 | const Variable* var = 0; |
| 72 | // try to use one of must_read_vars in CGContext |
| 73 | var = VariableSelector::select_must_use_var(Effect::READ, cg_context, type, qfer); |
| 74 | if (var == NULL) { |
| 75 | var = VariableSelector::select(Effect::READ, cg_context, type, qfer, dummy, eFlexible); |
| 76 | } |
| 77 | ERROR_GUARD(NULL); |
| 78 | if (!var) |
| 79 | continue; |
| 80 | if (!type->is_float() && var->type->is_float()) |
| 81 | continue; |
| 82 | // forbid a parameter to take the address of an argument |
| 83 | // this is to simplify the path shortcutting delta |
| 84 | if (as_param && var->is_argument() && var->type->is_dereferenced_from(type)) { |
| 85 | continue; |
| 86 | } |
| 87 | if (!CGOptions::addr_taken_of_locals() |
| 88 | && var->type->is_dereferenced_from(type) |
| 89 | && (var->is_argument() || var->is_local())) { |
| 90 | continue; |
| 91 | } |
| 92 | |
| 93 | // forbid a escaping pointer to take the address of an argument or a local variable |
| 94 | int indirection = var->type->get_indirect_level() - type->get_indirect_level(); |
| 95 | if (as_return && CGOptions::no_return_dead_ptr() && |
| 96 | FactPointTo::is_pointing_to_locals(var, cg_context.get_current_block(), indirection, fm->global_facts)) { |
| 97 | continue; |
| 98 | } |
| 99 | int valid = FactPointTo::opportunistic_validate(var, type, fm->global_facts); |
| 100 | if (valid) { |
| 101 | ExpressionVariable tmp(*var, type); |
| 102 | if (tmp.visit_facts(fm->global_facts, cg_context)) { |
| 103 | ev = tmp.get_indirect_level() == 0 ? new ExpressionVariable(*var) : new ExpressionVariable(*var, type); |
| 104 | cg_context.curr_blk = cg_context.get_current_block(); |
| 105 | break; |
| 106 | } |
| 107 | else { |
| 108 | cg_context.reset_effect_accum(eff_accum); |
| 109 | cg_context.reset_effect_stm(eff_stmt); |
| 110 | } |
| 111 | } |
| 112 | dummy.push_back(var); |
| 113 | } while (true); |
| 114 |
nothing calls this directly
no test coverage detected