Example #1
0
/****************************************************************************
 * Entry point to pointer analysis and other DFA analysis for newly
 * created statement. remember some analysis has already been done during the
 * statement generation, some analysis work is only possible with a complete
 * statement, we do it here
 ****************************************************************************/
void
Statement::post_creation_analysis(vector<const Fact*>& pre_facts, const Effect& pre_effect, CGContext& cg_context) const
{
	FactMgr* fm = get_fact_mgr_for_func(func);
	if (eType == eIfElse) {
		((const StatementIf*)this)->combine_branch_facts(pre_facts);
	} else {
		fm->makeup_new_var_facts(pre_facts, fm->global_facts);
	}

	// save the effect for this statement if this is a simple statement
	// for compound statements, it's effect is saved in make_random
	if (!is_compound(eType)) {
		fm->map_stm_effect[this] = cg_context.get_effect_stm();
	}

	bool special_handled = false;
	// special handling for non-looping statements in func_1, which we never re-visit to
	// save run-time
	if (cg_context.get_current_func()->name == "func_1" && !(cg_context.flags & IN_LOOP) ) {
		if (has_uncertain_call_recursive()) {
			FactVec outputs = pre_facts;
			cg_context.reset_effect_accum(pre_effect);
			//if (stm_id == 573)
				/*if (this->eType == eAssign) {
					((const StatementAssign*)this)->get_rhs()->indented_output(cout, 0);
				}
				cout << endl;
				Output(cout, fm);*/
			//}
			if (!validate_and_update_facts(outputs, cg_context)) {
				assert(0);
			}
			fm->global_facts = outputs;
			special_handled = true;
		}
	}

	if (!special_handled) {
		// for if...else..., we don't want to walk through the true branch and false branch again
		// compute the output with consideration of return statement(s) in both branches
		if (eType == eAssign) {
			const StatementAssign* sa = (const StatementAssign*)this;
			// abstract fact for assignment itself. No analysis on function calls
			// on RHS since they are already handled during statement generation
			FactMgr::update_fact_for_assign(sa, fm->global_facts);
		}
		else if (eType == eReturn) {
			const StatementReturn* sr = (const StatementReturn*)this;
			FactMgr::update_fact_for_return(sr, fm->global_facts);
		}
	}
	fm->remove_rv_facts(fm->global_facts);
	fm->set_fact_in(this, pre_facts);
	fm->set_fact_out(this, fm->global_facts);
	fm->map_accum_effect[this] = *(cg_context.get_effect_accum());
	fm->map_visited[this] = true;
}
Example #2
0
/**********************************************************************
 * once generated the loop body, verify whether some statement caused
 * the analyzer to fail during the 2nd iteration of the loop body (in
 * most case, a null/dead pointer dereference would do it), if so, delete
 * the statement in which analyzer fails and all subsequent statemets
 *
 * also performs effect analysis
 *********************************************************************/
void
Block::post_creation_analysis(CGContext& cg_context, const Effect& pre_effect)
{
	int index;
	FactMgr* fm = get_fact_mgr(&cg_context);
	fm->map_visited[this] = true;
	// compute accumulated effect
	set_accumulated_effect(cg_context);
	//fm->print_facts(fm->global_facts);
	vector<const Fact*> post_facts = fm->global_facts;
	FactMgr::update_facts_for_oos_vars(local_vars, fm->global_facts);
	fm->remove_rv_facts(fm->global_facts);
	fm->set_fact_out(this, fm->global_facts);

	// find out if fixed-point-searching is required
	bool is_loop_body = !must_break_or_return() && looping;
	bool self_back_edge = false;
	if (is_loop_body || need_revisit || has_edge_in(false, true)) {
		if (is_loop_body && from_tail_to_head()) {
			self_back_edge = true;
			fm->create_cfg_edge(this, this, false, true);
		}
		vector<const Fact*> facts_copy = fm->map_facts_in[this];
		// reset the accumulative effect
		cg_context.reset_effect_accum(pre_effect);
		while (!find_fixed_point(facts_copy, post_facts, cg_context, index, need_revisit)) {
			size_t i, len;
			len = stms.size();
			for (i=index; i<len; i++) {
				remove_stmt(stms[i]);
				i = index-1;
				len = stms.size();
			}
			// if we delete some statements, next visit must go through statements (no shortcut)
			need_revisit = true;
			// clean up in/out map from previous analysis that might include facts caused by deleted statements
			fm->reset_stm_fact_maps(this);
			// sometimes a loop would emerge after we delete the "return" statement in body
			if (!self_back_edge && from_tail_to_head()) {
				self_back_edge = true;
				fm->create_cfg_edge(this, this, false, true);
			}
			// reset incoming effects
			cg_context.reset_effect_accum(pre_effect);
		}
		fm->global_facts = fm->map_facts_out[this];
	}
	// make sure we add back return statement for blocks that require it and had such statement deleted
	// only do this for top-level block of a function which requires a return statement
	if (parent == 0 && func->need_return_stmt() && !must_return()) {
		fm->global_facts = post_facts;
		Statement* sr = append_return_stmt(cg_context);
		fm->set_fact_out(this, fm->map_facts_out[sr]);
	}
}
Example #3
0
bool
Statement::stm_visit_facts(vector<const Fact*>& inputs, CGContext& cg_context) const
{
	cg_context.get_effect_stm().clear();
	cg_context.curr_blk = parent;
	FactMgr* fm = get_fact_mgr(&cg_context);
	//static int g = 0;
	//int h = g++;
	bool ok = visit_facts(inputs, cg_context);


	if (!ok && !is_compound(eType)) {
		failed_stm = this;
	}
	//if (!FactPointTo::is_valid_ptr("g_75", inputs))
	//	Output(cout, fm);
	fm->remove_rv_facts(inputs);
	fm->map_accum_effect[this] = *(cg_context.get_effect_accum());
	fm->map_visited[this] = true;
	return ok;
}