Пример #1
0
void goto_symext::symex_other(
  const goto_functionst &goto_functions,
  statet &state)
{
  const goto_programt::instructiont &instruction=*state.source.pc;

  const codet &code=to_code(instruction.code);

  const irep_idt &statement=code.get_statement();
  
  if(statement==ID_expression)
  {
    // ignore
  }
  else if(statement==ID_cpp_delete ||
          statement=="cpp_delete[]")
  {
    codet clean_code=code;
    clean_expr(clean_code, state, false);
    symex_cpp_delete(state, clean_code);
  }
  else if(statement==ID_free)
  {
    // ignore
  }
  else if(statement==ID_printf)
  {
    codet clean_code=code;
    clean_expr(clean_code, state, false);
    symex_printf(state, nil_exprt(), clean_code);
  }
  else if(statement==ID_input)
  {
    codet clean_code(code);
    clean_expr(clean_code, state, false);
    symex_input(state, clean_code);
  }
  else if(statement==ID_output)
  {
    codet clean_code(code);
    clean_expr(clean_code, state, false);
    symex_output(state, clean_code);
  }
  else if(statement==ID_decl)
  {
    assert(false); // see symex_decl.cpp
  }
  else if(statement==ID_nondet)
  {
    // like skip
  }
  else if(statement==ID_asm)
  {
    // we ignore this for now
  }
  else if(statement==ID_array_copy)
  {
    assert(code.operands().size()==2);

    codet clean_code(code);
    
    // we need to add dereferencing for both operands
    dereference_exprt d0, d1;
    d0.op0()=code.op0();
    d0.type()=code.op0().type().subtype();
    d1.op0()=code.op1();
    d1.type()=code.op1().type().subtype();
    
    clean_code.op0()=d0;
    clean_code.op1()=d1;
    
    clean_expr(clean_code, state, false);
    
    process_array_expr(clean_code.op0());
    process_array_expr(clean_code.op1());
    
    if(ns.follow(clean_code.op0().type()).id()!=ID_array)
      throw "array_copy expects array operand";
    
    if(!base_type_eq(clean_code.op0().type(),
                     clean_code.op1().type(), ns))
      throw "array_copy expects matching array types";
    
    code_assignt assignment;
    assignment.lhs()=clean_code.op0();
    assignment.rhs()=clean_code.op1();
    basic_symext::symex_assign(state, assignment);    
  }
  else if(statement==ID_array_set)
  {
    assert(code.operands().size()==2);
    
    codet clean_code(code);

    // we need to add dereferencing for the first operand
    dereference_exprt d0;
    d0.op0()=code.op0();
    d0.type()=code.op0().type().subtype();
    
    clean_code.op0()=d0;

    clean_expr(clean_code, state, false);
    
    process_array_expr(clean_code.op0());
    
    const typet &array_type=ns.follow(clean_code.op0().type());
    
    if(array_type.id()!=ID_array)
      throw "array_set expects array operand";

    if(!base_type_eq(array_type.subtype(),
                     clean_code.op1().type(), ns))
      clean_code.op1().make_typecast(array_type.subtype());
    
    code_assignt assignment;
    assignment.lhs()=clean_code.op0();
    assignment.rhs()=array_of_exprt(clean_code.op1(), clean_code.op0().type());
    basic_symext::symex_assign(state, assignment);    
  }
  else if(statement==ID_user_specified_predicate || statement==ID_user_specified_parameter_predicates || statement == ID_user_specified_return_predicates)
  {
	  // like skip
  }
  else
    throw "unexpected statement: "+id2string(statement);
}
Пример #2
0
void goto_symext::symex_other()
{
  const goto_programt::instructiont &instruction = *cur_state->source.pc;

  expr2tc code2 = instruction.code;

  if(is_code_expression2t(code2))
  {
    // Represents an expression that gets evaluated, but does not have any
    // other effect on execution, i.e. doesn't contain a call or assignment.
    // This can, however, cause the program to fail if it dereferences an
    // invalid pointer. Therefore, dereference it.
    const code_expression2t &expr = to_code_expression2t(code2);
    expr2tc operand = expr.operand;
    dereference(operand, dereferencet::READ);
  }
  else if(is_code_cpp_del_array2t(code2) || is_code_cpp_delete2t(code2))
  {
    expr2tc deref_code(code2);

    replace_dynamic_allocation(deref_code);
    replace_nondet(deref_code);
    dereference(deref_code, dereferencet::READ);

    symex_cpp_delete(deref_code);
  }
  else if(is_code_free2t(code2))
  {
    symex_free(code2);
  }
  else if(is_code_printf2t(code2))
  {
    replace_dynamic_allocation(code2);
    replace_nondet(code2);
    dereference(code2, dereferencet::READ);
    symex_printf(expr2tc(), code2);
  }
  else if(is_code_decl2t(code2))
  {
    replace_dynamic_allocation(code2);
    replace_nondet(code2);
    dereference(code2, dereferencet::READ);

    const code_decl2t &decl_code = to_code_decl2t(code2);

    // just do the L2 renaming to preseve locality
    const irep_idt &identifier = decl_code.value;

    // Generate dummy symbol as a vehicle for renaming.
    symbol2tc l1_sym(get_empty_type(), identifier);

    cur_state->top().level1.get_ident_name(l1_sym);
    symbol2t &l1_symbol = to_symbol2t(l1_sym);

    // increase the frame if we have seen this declaration before
    while(cur_state->top().declaration_history.find(
            renaming::level2t::name_record(l1_symbol)) !=
          cur_state->top().declaration_history.end())
    {
      unsigned &index = cur_state->variable_instance_nums[identifier];
      cur_state->top().level1.rename(l1_sym, ++index);
      l1_symbol.level1_num = index;
    }

    renaming::level2t::name_record tmp_name(l1_symbol);
    cur_state->top().declaration_history.insert(tmp_name);
    cur_state->top().local_variables.insert(tmp_name);

    // seen it before?
    // it should get a fresh value
    if(cur_state->level2.current_number(l1_sym) != 0)
    {
      // Dummy assignment - blank constant value isn't considered for const
      // propagation, variable number will be bumped to result in a new free
      // variable. Invalidates l1_symbol reference?
      cur_state->level2.make_assignment(l1_sym, expr2tc(), expr2tc());
    }
  }
  else if(is_code_asm2t(code2))
  {
    // Assembly statement -> do nothing.
    return;
  }
  else
    throw "goto_symext: unexpected statement: " + get_expr_id(code2);
}