示例#1
0
void create_safety_solution(safety_goto_solutiont &solution,
    const safety_programt &prog, const goto_tracet &trace,
    const operand_variable_idst &var_ids, const size_t max_sz)
{
  solution.clear();
  const goto_programt &execute_body=get_execute_body(prog.gf);
  const instruction_sett instr_set(extract_instruction_set(execute_body));
  invariant_variable_namest var_names;
  reverse_invariant_var_ids(var_names, var_ids);
  invariant_variable_namest result_var_names;
  assert(max_sz > 0);
  const size_t idx=create_temps(result_var_names, max_sz - 1);
  size_t loop_idx=0;
  for (const goto_trace_stept &step : trace.steps)
  {
    if (!is_program_individual_decl(step)) continue;
    const exprt::operandst &instrs=step.full_lhs_value.operands();
    set_result_var(result_var_names, idx, loop_idx++);
    solution.push_back(goto_programt::instructionst());
    extract_program(solution.back(), prog.st, instr_set, var_names,
        result_var_names, instrs);
  }
}
示例#2
0
static int cgc_eval_expression(interp_t *interp, expr_t *expr)
{
    const char *s;
    int i, t1, t2;
    var_t tmp;

#ifdef PATCHED
    if (expr == NULL)
        return 0;
#endif

    switch(expr->op)
    {
    case OP_CONST_STRING:
        if (!set_result_string(interp, cgc_strdup(expr->e_cstring.value)))
            return 0;
        break;
    case OP_CONST_INT:
        if (!set_result_number(interp, expr->e_cint.value))
            return 0;
        break;
    case OP_FIELD:
        s = cgc_get_field(interp, expr->e_cint.value);
        if (s == NULL)
            return 0;
        if (!set_result_string(interp, cgc_strdup(s)))
            return 0;
        break;
    case OP_FIELD_VAR:
        if (!get_number(interp, expr->e_var.name, &i))
            return 0;
        s = cgc_get_field(interp, i);
        if (s == NULL)
            return 0;
        if (!set_result_string(interp, cgc_strdup(s)))
            return 0;
        break;
    case OP_VAR:
        if (!set_result_var(interp, get_var(interp, expr->e_var.name)))
            return 0;
        break;
    case OP_ASSIGN:
        if (!cgc_eval_expression(interp, expr->e_binop.rhs))
            return 0;
        // set lhs to interp->result
        if (!cgc_assign_result(interp, expr->e_binop.lhs))
            return 0;
        break;
    case OP_CONDITIONAL:
        if (!cgc_eval_expression(interp, expr->e_cond.cond))
            return 0;
        if (coerce_bool(interp, &interp->result))
        {
            if (!cgc_eval_expression(interp, expr->e_cond.vtrue))
                return 0;
        }
        else
        {
            if (!cgc_eval_expression(interp, expr->e_cond.vfalse))
                return 0;
        }
        break;
    case OP_OR:
        if (!cgc_eval_expression(interp, expr->e_binop.lhs))
            return 0;
        if (coerce_bool(interp, &interp->result))
        {
            if (!set_result_number(interp, TRUE))
                return 0;
        }
        else
        {
            if (!cgc_eval_expression(interp, expr->e_binop.rhs))
                return 0;
            if (!set_result_number(interp,
                    coerce_bool(interp, &interp->result) ? TRUE : FALSE))
                return 0;
        }
        break; 
    case OP_AND:
        if (!cgc_eval_expression(interp, expr->e_binop.lhs))
            return 0;
        if (!coerce_bool(interp, &interp->result))
        {
            if (!set_result_number(interp, FALSE))
                return 0;
        }
        else
        {
            if (!cgc_eval_expression(interp, expr->e_binop.rhs))
                return 0;
            if (!set_result_number(interp,
                    coerce_bool(interp, &interp->result) ? TRUE : FALSE))
                return 0;
        }
        break; 
    case OP_MATCH:
    case OP_NOT_MATCH:
        if (!cgc_do_match(interp, expr->e_binop.lhs, expr->e_binop.rhs))
            return 0;
        if (expr->op == OP_NOT_MATCH)
            interp->result.v_number.value = interp->result.v_number.value == TRUE ? FALSE : TRUE;
        break;
    case OP_CONST_REGEXP:
        if (!cgc_do_match(interp, NULL, expr))
            return 0;
        break;
    case OP_LT:
    case OP_GT:
    case OP_LTE:
    case OP_GTE:
    case OP_EQ:
    case OP_NEQ:
        if (!cgc_eval_expression(interp, expr->e_binop.lhs))
            return 0;
        move_var(&tmp, &interp->result);
        if (!cgc_eval_expression(interp, expr->e_binop.rhs))
            return 0;
        t1 = compare_value(&tmp, &interp->result);
        if ((expr->op == OP_LT && t1 < 0) ||
            (expr->op == OP_GT && t1 > 0) ||
            (expr->op == OP_LTE && t1 <= 0) ||
            (expr->op == OP_GTE && t1 >= 0) ||
            (expr->op == OP_EQ && t1 == 0) ||
            (expr->op == OP_NEQ && t1 != 0))
        {
            if (!set_result_number(interp, TRUE))
                return 0;
        }
        else
        {
            if (!set_result_number(interp, FALSE))
                return 0;
        }
        cgc_free_var(&tmp);
        break;
    case OP_ADD:
    case OP_ASSIGN_ADD:
    case OP_SUB:
    case OP_ASSIGN_SUB:
    case OP_MUL:
    case OP_ASSIGN_MUL:
    case OP_DIV:
    case OP_ASSIGN_DIV:
    case OP_MOD:
    case OP_ASSIGN_MOD:
        if (!cgc_eval_expression(interp, expr->e_binop.lhs))
            return 0;
        t1 = coerce_number(interp, &interp->result);
        if (!cgc_eval_expression(interp, expr->e_binop.rhs))
            return 0;
        t2 = coerce_number(interp, &interp->result);
        if (expr->op == OP_ADD || expr->op == OP_ASSIGN_ADD)
            t1 = t1 + t2;
        else if (expr->op == OP_SUB || expr->op == OP_ASSIGN_SUB)
            t1 = t1 - t2;
        else if (expr->op == OP_MUL || expr->op == OP_ASSIGN_MUL)
            t1 = t1 * t2;
        else if (expr->op == OP_DIV || expr->op == OP_ASSIGN_DIV)
        {
            if (t2 == 0)
                return 0;
            t1 = t1 / t2;
        }
        else if (expr->op == OP_MOD || expr->op == OP_ASSIGN_MOD)
        {
            if (t2 == 0)
                return 0;
            t1 = t1 % t2;
        }
        if (!set_result_number(interp, t1))
            return 0;

        if (expr->op == OP_ASSIGN_ADD ||
            expr->op == OP_ASSIGN_SUB ||
            expr->op == OP_ASSIGN_MUL ||
            expr->op == OP_ASSIGN_DIV ||
            expr->op == OP_ASSIGN_MOD)
        {
            if (!cgc_assign_result(interp, expr->e_binop.lhs))
                return 0;
        }
        break;
    case OP_INC_PRE:
    case OP_DEC_PRE:
    case OP_INC_POST:
    case OP_DEC_POST:
        if (!cgc_eval_expression(interp, expr->e_unop.expr))
            return 0;
        move_var(&tmp, &interp->result);
        t1 = coerce_number(interp, &tmp);
        if (expr->op == OP_INC_PRE || expr->op == OP_INC_POST)
            t2 = t1 + 1;
        else
            t2 = t1 - 1;
        if (!set_result_number(interp, t2))
            return 0;
        if (!cgc_assign_result(interp, expr->e_unop.expr))
            return 0;

        if (expr->op == OP_INC_POST || expr->op == OP_DEC_POST)
            move_var(&interp->result, &tmp);
        else
            cgc_free_var(&tmp);
        break;
    case OP_NEGATE:
    case OP_NOT:
        if (!cgc_eval_expression(interp, expr->e_unop.expr))
            return 0;
        t1 = coerce_number(interp, &interp->result);
        if (expr->op == OP_NEGATE)
            t2 = -t1;
        else
            t2 = coerce_bool(interp, &interp->result) == TRUE ? FALSE : TRUE;
        if (!set_result_number(interp, t2))
            return 0;
        break;
    case OP_CONCAT:
        if (!do_concat(interp, expr->e_binop.lhs, expr->e_binop.rhs))
            return 0;
        break;
    default:
        return 0;
    }

    return 1;
}