本文整理汇总了C++中FactMgr类的典型用法代码示例。如果您正苦于以下问题:C++ FactMgr类的具体用法?C++ FactMgr怎么用?C++ FactMgr使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了FactMgr类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: RandomReturnType
Function *
Function::make_first(void)
{
const Type *ty = RandomReturnType();
ERROR_GUARD(NULL);
Function *f = new Function(RandomFunctionName(), ty);
// dummy variable representing return variable, we don't care about the type, so use 0
string rvname = f->name + "_" + "rv";
CVQualifiers ret_qfer = CVQualifiers::random_qualifiers(ty);
ERROR_GUARD(NULL);
f->rv = Variable::CreateVariable(rvname, ty, NULL, &ret_qfer);
// create a fact manager for this function, with empty global facts
FactMgr* fm = new FactMgr(f);
FMList.push_back(fm);
ExtensionMgr::GenerateFirstParameterList(*f);
// No Parameter List
f->GenerateBody(CGContext::get_empty_context());
if (CGOptions::inline_function() && rnd_flipcoin(InlineFunctionProb))
f->is_inlined = true;
fm->setup_in_out_maps(true);
// update global facts to merged facts at all possible function exits
fm->global_facts = fm->map_facts_out[f->body];
f->body->add_back_return_facts(fm, fm->global_facts);
// collect info about global dangling pointers
fm->find_dangling_global_ptrs(f);
return f;
}
示例2: get_fact_mgr
StatementContinue *
StatementContinue::make_random(CGContext &cg_context)
{
//static int g =0;
FactMgr* fm = get_fact_mgr(&cg_context);
// find the closest looping parent block: the one "continue"
// would apply to
//int h = g++;
const Block* b = cg_context.get_current_block();
const Statement* prev_stm = b->get_last_stm();
// don't generate "continue" as the first statement in a block
if (prev_stm == 0) {
return 0;
}
while (b && !b->looping) {
b = b->parent;
}
assert(b);
cg_context.get_effect_stm().clear();
Expression *expr = HYPOTHESIS_DRAW(Expression, cg_context, get_int_type(), 0, true, true, eVariable);
ERROR_GUARD(NULL);
StatementContinue* sc = new StatementContinue(cg_context.get_current_block(), *expr, *b);
fm->create_cfg_edge(sc, b, false, true);
return sc;
}
示例3: get_fact_mgr_for_func
void
StatementIf::combine_branch_facts(vector<const Fact*>& pre_facts) const
{
FactMgr* fm = get_fact_mgr_for_func(func);
FactVec& outputs = fm->global_facts;
fm->makeup_new_var_facts(pre_facts, fm->map_facts_out[&if_true]);
fm->makeup_new_var_facts(pre_facts, fm->map_facts_out[&if_false]);
bool true_must_return = if_true.must_return();
bool false_must_return = if_false.must_return();
// take return statement into consideration to achieve better precision
if (true_must_return && false_must_return) {
outputs = pre_facts;
}
else if (true_must_return) {
// since false branch is created after true branch, it's output should
// have all the variables created in true branch already
outputs = fm->map_facts_out[&if_false];
}
else if (false_must_return) {
outputs = fm->map_facts_out[&if_true];
// if skip the outcome from false branch, don't forget facts of those variables
// created in false branch
fm->makeup_new_var_facts(outputs, fm->map_facts_in[&if_false]);
}
else {
outputs = fm->map_facts_out[&if_true];
merge_facts(outputs, fm->map_facts_out[&if_false]);
}
}
示例4: get_fact_mgr_for_func
/***************************************************************************************
* for a given input env, abstract a given statement, generate an output env, and
* update both input/output env for this statement
*
* shortcut: if this input env matches previous input env, use previous output env directly
***************************************************************************************/
bool
Statement::validate_and_update_facts(vector<const Fact*>& inputs, CGContext& cg_context) const
{
FactMgr* fm = get_fact_mgr_for_func(func);
int shortcut = shortcut_analysis(inputs, cg_context);
if (shortcut==0) {
/* mark the goto statements inside this statement as visited
this is to fix scenario like the following:
lbl: s1
for (...) {
goto lbl;
}
where the "for" statement is bypassed, but the output from "goto lbl"
must be feed into s1 in order to achieve a fixed point */
for (size_t i=0; i<fm->cfg_edges.size(); i++) {
const Statement* s = fm->cfg_edges[i]->src;
if (s->eType == eGoto && contains_stmt(s)) {
fm->map_visited[s] = true;
}
}
return true;
}
if (shortcut==1) return false;
vector<const Fact*> inputs_copy = inputs;
if (!stm_visit_facts(inputs, cg_context)) {
return false;
}
fm->set_fact_in(this, inputs_copy);
fm->set_fact_out(this, inputs);
return true;
}
示例5: ExpressionFunctionProbability
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;
}
示例6: get_fact_mgr
/**************************************************************************************************
* DFA analysis for a block:
*
* we must considers all kinds of blocks: block for for-loops; block for if-true and if-false; block for
* function body; block that loops; block has jump destination insdie; block being a jump destination itself
* (in the case of "continue" in for-loops). All of them must be taken care in this function.
*
* params:
* inputs: the inputs env before entering block
* cg_context: code generation context
* fail_index: records which statement in this block caused analyzer to fail
* visit_one: when is true, the statements in this block must be visited at least once
****************************************************************************************************/
bool
Block::find_fixed_point(vector<const Fact*> inputs, vector<const Fact*>& post_facts, CGContext& cg_context, int& fail_index, bool visit_once) const
{
FactMgr* fm = get_fact_mgr(&cg_context);
// include outputs from all back edges leading to this block
size_t i;
static int g = 0;
vector<const CFGEdge*> edges;
int cnt = 0;
do {
// if we have never visited the block, force the visitor to go through all statements at least once
if (fm->map_visited[this]) {
if (cnt++ > 7) {
// takes too many iterations to reach a fixed point, must be something wrong
assert(0);
}
find_edges_in(edges, false, true);
for (i=0; i<edges.size(); i++) {
const Statement* src = edges[i]->src;
//assert(fm->map_visited[src]);
merge_facts(inputs, fm->map_facts_out[src]);
}
}
if (!visit_once) {
int shortcut = shortcut_analysis(inputs, cg_context);
if (shortcut == 0) return true;
}
//if (shortcut == 1) return false;
FactVec outputs = inputs;
// add facts for locals
for (i=0; i<local_vars.size(); i++) {
const Variable* v = local_vars[i];
FactMgr::add_new_var_fact(v, outputs);
}
// revisit statements with new inputs
for (i=0; i<stms.size(); i++) {
int h = g++;
if (h == 2585)
BREAK_NOP; // for debugging
if (!stms[i]->analyze_with_edges_in(outputs, cg_context)) {
fail_index = i;
return false;
}
}
fm->set_fact_in(this, inputs);
post_facts = outputs;
FactMgr::update_facts_for_oos_vars(local_vars, outputs);
fm->set_fact_out(this, outputs);
fm->map_visited[this] = true;
// compute accumulated effect
set_accumulated_effect(cg_context);
visit_once = false;
} while (true);
return true;
}
示例7: DEPTH_GUARD_BY_TYPE_RETURN
StatementIf *
StatementIf::make_random(CGContext &cg_context)
{
DEPTH_GUARD_BY_TYPE_RETURN(dtStatementIf, NULL);
FactMgr* fm = get_fact_mgr(&cg_context);
FactVec pre_facts;
Effect pre_effect;
// func_1 hacking, save the env in case we need to re-analyze
if (cg_context.get_current_func()->name == "func_1" && !(cg_context.flags & IN_LOOP)) {
pre_effect = cg_context.get_accum_effect();
pre_facts = fm->global_facts;
}
cg_context.get_effect_stm().clear();
Expression *expr = Expression::make_random(cg_context, get_int_type(), NULL, false, !CGOptions::const_as_condition());
ERROR_GUARD(NULL);
// func_1 hacking, re-analyze for multiple function calls
if (cg_context.get_current_func()->name == "func_1" && !(cg_context.flags & IN_LOOP)) {
if (expr->has_uncertain_call_recursive()) {
fm->makeup_new_var_facts(pre_facts, fm->global_facts);
cg_context.reset_effect_accum(pre_effect);
cg_context.curr_blk = cg_context.get_current_block();
bool ok = expr->visit_facts(pre_facts, cg_context);
if (!ok) {
// print_facts(pre_facts);
// expr->indented_output(cout, 0);
}
assert(ok);
fm->global_facts = pre_facts;
}
}
Effect eff = cg_context.get_effect_stm();
// this will save global_facts to map_facts_in[if_true], and update
// facts for new variables created while generating if_true
Block *if_true = Block::make_random(cg_context);
ERROR_GUARD_AND_DEL1(NULL, expr);
// generate false branch with the same env as true branch
fm->global_facts = fm->map_facts_in[if_true];
Block *if_false = Block::make_random(cg_context);
ERROR_GUARD_AND_DEL2(NULL, expr, if_true);
StatementIf* si = new StatementIf(cg_context.get_current_block(), *expr, *if_true, *if_false);
// compute accumulated effect for this statement
si->set_accumulated_effect_after_block(eff, if_true, cg_context);
si->set_accumulated_effect_after_block(eff, if_false, cg_context);
return si;
}
示例8: get_fact_mgr_for_func
void
FactMgr::update_fact_for_return(const StatementReturn* sr, FactVec& inputs)
{
size_t i, j;
for (i=0; i<FactMgr::meta_facts.size(); i++) {
std::vector<const Fact*> facts = FactMgr::meta_facts[i]->abstract_fact_for_return(inputs, sr->get_var(), sr->func);
for (j=0; j<facts.size(); j++) {
// merge with other return statements
if (merge_fact(inputs, facts[j])) {
sr->func->fact_changed = true;
}
}
}
// incorporate current facts into return facts
FactMgr* fm = get_fact_mgr_for_func(sr->func);
fm->set_fact_out(sr, inputs);
}
示例9: assert
Block *
Block::make_dummy_block(CGContext &cg_context)
{
Function *curr_func = cg_context.get_current_func();
assert(curr_func);
Block *b = new Block(cg_context.get_current_block(), 0);
b->func = curr_func;
b->in_array_loop = !(cg_context.iv_bounds.empty());
curr_func->blocks.push_back(b);
curr_func->stack.push_back(b);
FactMgr* fm = get_fact_mgr_for_func(curr_func);
fm->set_fact_in(b, fm->global_facts);
Effect pre_effect = cg_context.get_accum_effect();
b->post_creation_analysis(cg_context, pre_effect);
curr_func->stack.pop_back();
return b;
}
示例10: get_fact_mgr
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);
}
示例11: get_fact_mgr
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;
}
示例12: get_fact_mgr_for_func
Statement*
Block::append_return_stmt(CGContext& cg_context)
{
FactMgr* fm = get_fact_mgr_for_func(func);
FactVec pre_facts = fm->global_facts;
cg_context.get_effect_stm().clear();
Statement* sr = Statement::make_random(cg_context, eReturn);
ERROR_GUARD(NULL);
stms.push_back(sr);
fm->makeup_new_var_facts(pre_facts, fm->global_facts);
assert(sr->visit_facts(fm->global_facts, cg_context));
fm->set_fact_in(sr, pre_facts);
fm->set_fact_out(sr, fm->global_facts);
fm->map_accum_effect[sr] = *(cg_context.get_effect_accum());
fm->map_visited[sr] = true;
//sr->post_creation_analysis(pre_facts, cg_context);
fm->map_accum_effect[this] = *(cg_context.get_effect_accum());
fm->map_stm_effect[this].add_effect(fm->map_stm_effect[sr]);
return sr;
}
示例13: if
void
Function::make_builtin_function(const string &function_string)
{
vector<string> v;
StringUtils::split_string(function_string, v, ";");
if (v.size() == 4) {
if (!CGOptions::enabled_builtin(v[3]))
return;
}
else if (v.size() == 3) {
if (!CGOptions::enabled_builtin("generic"))
return;
}
else {
assert(0 && "Invalid builtin function format!");
}
const Type *ty = Type::get_type_from_string(v[0]);
Function *f = new Function(v[1], ty, /*is_builtin*/true);
// dummy variable representing return variable, we don't care about the type, so use 0
string rvname = f->name + "_" + "rv";
CVQualifiers ret_qfer = CVQualifiers::random_qualifiers(ty);
f->rv = Variable::CreateVariable(rvname, ty, NULL, &ret_qfer);
// create a fact manager for this function, with empty global facts
FactMgr* fm = new FactMgr(f);
FMList.push_back(fm);
GenerateParameterListFromString(*f, StringUtils::get_substring(v[2], '(', ')'));
f->GenerateBody(CGContext::get_empty_context());
// update global facts to merged facts at all possible function exits
fm->global_facts = fm->map_facts_out[f->body];
f->body->add_back_return_facts(fm, fm->global_facts);
// collect info about global dangling pointers
fm->find_dangling_global_ptrs(f);
++builtin_functions_cnt;
}
示例14: get_fact_mgr_for_func
Statement*
Block::append_nested_loop(CGContext& cg_context)
{
FactMgr* fm = get_fact_mgr_for_func(func);
FactVec pre_facts = fm->global_facts;
cg_context.get_effect_stm().clear();
Statement* sf = HYPOTHESIS_DRAW(Statement, cg_context, eFor);
ERROR_GUARD(NULL);
stms.push_back(sf);
fm->makeup_new_var_facts(pre_facts, fm->global_facts);
//assert(sf->visit_facts(fm->global_facts, cg_context));
fm->set_fact_in(sf, pre_facts);
fm->set_fact_out(sf, fm->global_facts);
fm->map_accum_effect[sf] = *(cg_context.get_effect_accum());
fm->map_visited[sf] = true;
//sf->post_creation_analysis(pre_facts, cg_context);
fm->map_accum_effect[this] = *(cg_context.get_effect_accum());
fm->map_stm_effect[this].add_effect(fm->map_stm_effect[sf]);
return sf;
}
示例15: DEPTH_GUARD_BY_TYPE_RETURN
FunctionInvocation *
FunctionInvocation::make_random_binary(CGContext &cg_context, const Type* type)
{
DEPTH_GUARD_BY_TYPE_RETURN(dtFunctionInvocationRandomBinary, NULL);
if (rnd_flipcoin(10) && Type::has_pointer_type() && type->eType != eVector) {
ERROR_GUARD(NULL);
return make_random_binary_ptr_comparison(cg_context);
}
eBinaryOps op = (eBinaryOps)(rnd_upto(MAX_BINARY_OP, BINARY_OPS_PROB_FILTER));
ERROR_GUARD(NULL);
assert(type);
SafeOpFlags *flags = SafeOpFlags::make_random(sOpBinary, op);
assert(flags);
ERROR_GUARD(NULL);
// Special stuff for vectors.
if (type->eType == eVector) {
// Only signed type can use logicals. Also no div or mod.
// TODO: Instead of changing the op, flip the sign of the type.
if (!type->is_signed() && (
op==eCmpGt || op==eCmpLt || op==eCmpGe || op==eCmpLe ||
op==eCmpEq || op==eCmpNe || op==eAnd || op==eOr ||
op==eDiv || op==eMod)) {
op = eAdd;
}
// Only unsigned can use unsafe ops.
if (type->is_signed() && (
op==eAdd || op==eSub || op==eMul || op==eDiv ||
op==eMod || op==eRShift || op==eLShift)) {
op = eAnd;
}
delete flags;
flags = SafeOpFlags::make_dummy_flags();
}
FunctionInvocationBinary *fi = FunctionInvocationBinary::CreateFunctionInvocationBinary(cg_context, op, flags);
Effect lhs_eff_accum;
CGContext lhs_cg_context(cg_context, cg_context.get_effect_context(), &lhs_eff_accum);
// Generate an expression with the correct type required by safe math operands
const Type* lhs_type = flags->get_lhs_type();
const Type* rhs_type = flags->get_rhs_type();
// More special stuff for vectors.
if (type->eType == eVector) {
lhs_type = type;
rhs_type = type;
}
assert(lhs_type && rhs_type);
Expression *lhs = Expression::make_random(lhs_cg_context, lhs_type);
ERROR_GUARD_AND_DEL1(NULL, fi);
Expression *rhs = 0;
cg_context.merge_param_context(lhs_cg_context, true);
FactMgr* fm = get_fact_mgr(&cg_context);
vector<const Fact*> facts_copy = fm->global_facts;
#if 0
if (lhs->term_type == eVariable) {
lhs_eff_accum.read_deref_volatile((ExpressionVariable*)lhs);
}
#endif
// If we are guaranteed that the LHS will be evaluated before the RHS,
// or if the LHS is pure (not merely side-effect-free),
// then we can generate the RHS under the original effect context.
if (IsOrderedStandardFunc(op)) { // || lhs_eff_accum.is_pure()) { TODO: need more thoughts on the purity issue.
rhs = Expression::make_random(cg_context, rhs_type);
}
else {
// Otherwise, the RHS must be generated under the combined effect
// of the original effect and the LHS effect.
Effect rhs_eff_context(cg_context.get_effect_context());
rhs_eff_context.add_effect(lhs_eff_accum, true);
Effect rhs_eff_accum;
CGContext rhs_cg_context(cg_context, rhs_eff_context, &rhs_eff_accum);
if (op == eLShift || op == eRShift) {
eTermType tt = MAX_TERM_TYPES;
bool not_constant = rnd_flipcoin(ShiftByNonConstantProb);
// avoid shifting negative or too much
if (!not_constant) {
rhs = lhs_type->eType == eVector ?
dynamic_cast<Expression*>(CLSmith::ExpressionVector::make_constant(rhs_type, lhs_type->SizeInBytes() * 8)) :
dynamic_cast<Expression*>(Constant::make_random_upto(lhs_type->SizeInBytes() * 8));
} else {
rhs = Expression::make_random(rhs_cg_context, rhs_type, NULL, false, true, tt);
}
}
else {
rhs = Expression::make_random(rhs_cg_context, rhs_type);
// avoid divide by zero or possible zero (reached by pointer comparison)
if ((op == eMod || op == eDiv) && (rhs->equals(0) || rhs->is_0_or_1())) {
VectorFilter f;
f.add(eMod).add(eDiv).add(eLShift).add(eRShift);
op = (eBinaryOps)(rnd_upto(MAX_BINARY_OP, &f));
fi->set_operation(op);
}
}
cg_context.merge_param_context(rhs_cg_context, true);
}
//.........这里部分代码省略.........