bool Reducer::is_ptr_written_in_stm(const Statement* stm) { size_t i; FactMgr* fm = get_fact_mgr_for_func(stm->func); const vector<const Variable *>& write_vars = fm->map_stm_effect[stm].get_write_vars(); for (i=0; i<write_vars.size(); i++) { const Variable* wvar = write_vars[i]; if (wvar->is_pointer()) { const Block* blk = (stm->eType == eBlock) ? (const Block*)stm : stm->parent; if (wvar->is_visible(blk) && is_var_used(wvar)) { return true; } } } return false; }
ExpressionVariable * ExpressionVariable::make_random(CGContext &cg_context, const Type* type, const CVQualifiers* qfer, bool as_param, bool as_return) { DEPTH_GUARD_BY_TYPE_RETURN(dtExpressionVariable, NULL); Function *curr_func = cg_context.get_current_func(); FactMgr* fm = get_fact_mgr_for_func(curr_func); vector<const Variable*> dummy; // save current effects, in case we need to reset Effect eff_accum = cg_context.get_accum_effect(); Effect eff_stmt = cg_context.get_effect_stm(); ExpressionVariable *ev = 0; do { const Variable* var = 0; // try to use one of must_read_vars in CGContext var = VariableSelector::select_must_use_var(Effect::READ, cg_context, type, qfer); if (var == NULL) { var = VariableSelector::select(Effect::READ, cg_context, type, qfer, dummy, eFlexible); } ERROR_GUARD(NULL); if (!var) continue; if (!type->is_float() && var->type->is_float()) continue; // forbid a parameter to take the address of an argument // this is to simplify the path shortcutting delta if (as_param && var->is_argument() && var->type->is_dereferenced_from(type)) { continue; } if (!CGOptions::addr_taken_of_locals() && var->type->is_dereferenced_from(type) && (var->is_argument() || var->is_local())) { continue; } // forbid a escaping pointer to take the address of an argument or a local variable int indirection = var->type->get_indirect_level() - type->get_indirect_level(); if (as_return && CGOptions::no_return_dead_ptr() && FactPointTo::is_pointing_to_locals(var, cg_context.get_current_block(), indirection, fm->global_facts)) { continue; } int valid = FactPointTo::opportunistic_validate(var, type, fm->global_facts); if (valid) { ExpressionVariable tmp(*var, type); if (tmp.visit_facts(fm->global_facts, cg_context)) { ev = tmp.get_indirect_level() == 0 ? new ExpressionVariable(*var) : new ExpressionVariable(*var, type); cg_context.curr_blk = cg_context.get_current_block(); break; } else { cg_context.reset_effect_accum(eff_accum); cg_context.reset_effect_stm(eff_stmt); } } dummy.push_back(var); } while (true); // statistics int deref_level = ev->get_indirect_level(); if (deref_level > 0) { incr_counter(Bookkeeper::read_dereference_cnts, deref_level); } if (deref_level < 0) { Bookkeeper::record_address_taken(ev->get_var()); } Bookkeeper::record_volatile_access(ev->get_var(), deref_level, false); return ev; }