void goto_convertt::convert_CPROVER_try_catch(
  const codet &code,
  goto_programt &dest)
{
  if(code.operands().size()!=2)
  {
    err_location(code);
    throw "CPROVER_try_catch expects two arguments";
  }

  // this is where we go after 'throw'
  goto_programt tmp;
  tmp.add_instruction(SKIP)->source_location=code.source_location();

  // set 'throw' target
  throw_targett throw_target(targets);
  targets.set_throw(tmp.instructions.begin());
  
  // now put 'catch' code onto destructor stack
  code_ifthenelset catch_code;
  catch_code.cond()=exception_flag();
  catch_code.add_source_location()=code.source_location();
  catch_code.then_case()=to_code(code.op1());

  targets.destructor_stack.push_back(catch_code);

  // now convert 'try' code
  convert(to_code(code.op0()), dest);

  // pop 'catch' code off stack
  targets.destructor_stack.pop_back();
  
  // add 'throw' target
  dest.destructive_append(tmp);
}
Exemple #2
0
DexMethod* MethodCreator::create() {
  if (method->is_concrete()) {
    method->set_code(std::move(to_code()));
  } else {
    method->make_concrete(access, std::move(to_code()),
        !(access & (ACC_STATIC | ACC_PRIVATE | ACC_CONSTRUCTOR)));
  }
  return method;
}
Exemple #3
0
DexMethod* MethodCreator::create() {
  if (method->is_concrete()) {
    method->set_code(to_code());
  } else {
    auto access = method->get_access();
    bool is_virtual = !(access & (ACC_STATIC | ACC_PRIVATE | ACC_CONSTRUCTOR));
    method->make_concrete(access, to_code(), is_virtual);
  }
  return method;
}
Exemple #4
0
void jsil_typecheckt::typecheck_ifthenelse(code_ifthenelset &code)
{
  exprt &cond=code.cond();
  typecheck_expr(cond);
  make_type_compatible(cond, bool_typet(), true);

  typecheck_code(to_code(code.then_case()));

  if(!code.else_case().is_nil())
    typecheck_code(to_code(code.else_case()));
}
Exemple #5
0
void goto_convertt::convert_try_catch(
  const codet &code,
  goto_programt &dest)
{
  assert(code.operands().size()>=2);
  
  // add the CATCH-push instruction to 'dest'
  goto_programt::targett catch_push_instruction=dest.add_instruction();
  catch_push_instruction->make_catch();
  catch_push_instruction->code.set_statement(ID_catch);
  catch_push_instruction->source_location=code.source_location();
  
  // the CATCH-push instruction is annotated with a list of IDs,
  // one per target
  irept::subt &exception_list=
    catch_push_instruction->code.add(ID_exception_list).get_sub();

  // add a SKIP target for the end of everything
  goto_programt end;
  goto_programt::targett end_target=end.add_instruction();
  end_target->make_skip();
  
  // the first operand is the 'try' block
  convert(to_code(code.op0()), dest);
  
  // add the CATCH-pop to the end of the 'try' block
  goto_programt::targett catch_pop_instruction=dest.add_instruction();
  catch_pop_instruction->make_catch();
  catch_pop_instruction->code.set_statement(ID_catch);
  
  // add a goto to the end of the 'try' block
  dest.add_instruction()->make_goto(end_target);

  for(unsigned i=1; i<code.operands().size(); i++)
  {
    const codet &block=to_code(code.operands()[i]);
  
    // grab the ID and add to CATCH instruction
    exception_list.push_back(irept(block.get(ID_exception_id)));
    
    goto_programt tmp;
    convert(block, tmp);
    catch_push_instruction->targets.push_back(tmp.instructions.begin());
    dest.destructive_append(tmp);

    // add a goto to the end of the 'catch' block
    dest.add_instruction()->make_goto(end_target);
  }

  // add the end-target  
  dest.destructive_append(end);
}
Exemple #6
0
void c_typecheck_baset::typecheck_ifthenelse(code_ifthenelset &code)
{
  if(code.operands().size()!=3)
  {
    err_location(code);
    error() << "ifthenelse expected to have three operands" << eom;
    throw 0;
  }

  exprt &cond=code.cond();

  typecheck_expr(cond);

  #if 0
  if(cond.id()==ID_sideeffect &&
     cond.get(ID_statement)==ID_assign)
  {
    warning("warning: assignment in if condition");
  }
  #endif

  implicit_typecast_bool(cond);

  if(to_code(code.then_case()).get_statement()==ID_decl_block)
  {
    code_blockt code_block;
    code_block.add_source_location()=code.then_case().source_location();

    code_block.move_to_operands(code.then_case());
    code.then_case().swap(code_block);
  }

  typecheck_code(to_code(code.then_case()));

  if(!code.else_case().is_nil())
  {
    if(to_code(code.else_case()).get_statement()==ID_decl_block)
    {
      code_blockt code_block;
      code_block.add_source_location()=code.else_case().source_location();

      code_block.move_to_operands(code.else_case());
      code.else_case().swap(code_block);
    }

    typecheck_code(to_code(code.else_case()));
  }
}
Exemple #7
0
void ansi_c_convertt::convert_declaration(ansi_c_declarationt &declaration)
{
  c_storage_spect c_storage_spec;

  convert_type(declaration.type(), c_storage_spec);

  declaration.set_is_inline(c_storage_spec.is_inline);
  declaration.set_is_static(c_storage_spec.is_static);
  declaration.set_is_extern(c_storage_spec.is_extern);
  declaration.set_is_thread_local(c_storage_spec.is_thread_local);
  declaration.set_is_register(c_storage_spec.is_register);

  // do not overwrite is_typedef -- it's done by the parser
  // typedefs are macros
  if(declaration.get_is_typedef())
    declaration.set_is_macro(true);

  if(declaration.value().is_not_nil())
  {
    if(declaration.value().type().id()==ID_code)
      convert_code(to_code(declaration.value()));
    else
      convert_expr(declaration.value());
  }
}
void goto_convertt::cpp_new_initializer(
  const exprt &lhs,
  const side_effect_exprt &rhs,
  goto_programt &dest)
{
  exprt initializer=
    static_cast<const exprt &>(rhs.find(ID_initializer));

  if(initializer.is_not_nil())
  {
    if(rhs.get_statement()=="cpp_new[]")
    {
      // build loop
    }
    else if(rhs.get_statement()==ID_cpp_new)
    {
      // just one object
      exprt deref_lhs(ID_dereference, rhs.type().subtype());
      deref_lhs.copy_to_operands(lhs);
      
      replace_new_object(deref_lhs, initializer);
      convert(to_code(initializer), dest);
    }
    else
      assert(false);
  }
}
Exemple #9
0
void ansi_c_convertt::convert_expr(exprt &expr)
{
  if(expr.id()==ID_sideeffect)
  {
    const irep_idt &statement=expr.get(ID_statement);

    if(statement==ID_statement_expression)
    {
      assert(expr.operands().size()==1);
      convert_code(to_code(expr.op0()));
      return;
      // done
    }
  }

  Forall_operands(it, expr)
    convert_expr(*it);

  if(expr.id()==ID_symbol)
  {
    expr.remove(ID_C_id_class);
    expr.remove(ID_C_base_name);
  }
  else if(expr.id()==ID_sizeof)
  {
    if(expr.operands().size()==0)
    {
      typet &type=static_cast<typet &>(expr.add(ID_type_arg));
      convert_type(type);
    }
  }
  else if(expr.id()==ID_designated_initializer)
  {
    exprt &designator=static_cast<exprt &>(expr.add(ID_designator));
    convert_expr(designator);
  }
  else if(expr.id()==ID_alignof)
  {
    if(expr.operands().size()==0)
    {
      typet &type=static_cast<typet &>(expr.add(ID_type_arg));
      convert_type(type);
    }
  }
  else if(expr.id()==ID_gcc_builtin_va_arg)
  {
    convert_type(expr.type());
  }
  else if(expr.id()==ID_generic_selection)
  {
    assert(expr.operands().size()==1);

    irept::subt &generic_associations=
      expr.add(ID_generic_associations).get_sub();

    Forall_irep(it, generic_associations)
    {
      convert_expr(static_cast<exprt &>(it->add(ID_value)));
      convert_type(static_cast<typet &>(it->add(ID_type_arg)));
    }
Exemple #10
0
void jsil_typecheckt::typecheck_non_type_symbol(symbolt &symbol)
{
  assert(!symbol.is_type);

  // Using is_extern to check if symbol was already typechecked
  if(symbol.is_extern)
    return;
  if(symbol.value.id()!="no-body-just-yet")
    symbol.is_extern=true;

  proc_name=symbol.name;
  typecheck_type(symbol.type);

  if(symbol.value.id()==ID_code)
    typecheck_code(to_code(symbol.value));
  else if(symbol.name=="eval")
  {
    // No code for eval. Do nothing
  }
  else if(symbol.value.id()=="no-body-just-yet")
  {
    // Do nothing
  }
  else
    throw "Non type symbol value expected code, but got "+
      symbol.value.pretty();
}
void goto_convertt::do_printf(
  const exprt &lhs,
  const exprt &function,
  const exprt::operandst &arguments,
  goto_programt &dest)
{
  const irep_idt &f_id=function.get(ID_identifier);

  if(f_id==CPROVER_PREFIX "printf" ||
     f_id=="printf")
  {
    typet return_type=static_cast<const typet &>(function.type().find(ID_return_type));
    side_effect_exprt printf_code(ID_printf, return_type);

    printf_code.operands()=arguments;
    printf_code.add_source_location()=function.source_location();

    if(lhs.is_not_nil())
    {
      code_assignt assignment(lhs, printf_code);
      assignment.add_source_location()=function.source_location();
      copy(assignment, ASSIGN, dest);
    }
    else
    {
      printf_code.id(ID_code);
      printf_code.type()=typet(ID_code);
      copy(to_code(printf_code), OTHER, dest);
    }
  }
  else
    assert(false);
}
void java_bytecode_typecheckt::typecheck_code(codet &code)
{
  const irep_idt &statement=code.get_statement();

  if(statement==ID_assign)
  {
    code_assignt &code_assign=to_code_assign(code);
    typecheck_expr(code_assign.lhs());
    typecheck_expr(code_assign.rhs());

    if(code_assign.lhs().type()!=code_assign.rhs().type())
      code_assign.rhs().make_typecast(code_assign.lhs().type());
  }
  else if(statement==ID_block)
  {
    Forall_operands(it, code)
      typecheck_code(to_code(*it));
  }
  else if(statement==ID_label)
  {
    code_labelt &code_label=to_code_label(code);
    typecheck_code(code_label.code());
  }
  else if(statement==ID_goto)
  {
  }
  else if(statement==ID_ifthenelse)
  {
    code_ifthenelset &code_ifthenelse=to_code_ifthenelse(code);
    typecheck_expr(code_ifthenelse.cond());
    typecheck_code(code_ifthenelse.then_case());
    if(code_ifthenelse.else_case().is_not_nil())
      typecheck_code(code_ifthenelse.else_case());
  }
  else if(statement==ID_switch)
  {
    code_switcht &code_switch = to_code_switch(code);
    typecheck_expr(code_switch.value());
  }
  else if(statement==ID_return)
  {
    if(code.operands().size()==1)
      typecheck_expr(code.op0());
  }
  else if(statement==ID_function_call)
  {
    code_function_callt &code_function_call=to_code_function_call(code);
    typecheck_expr(code_function_call.lhs());
    typecheck_expr(code_function_call.function());

    for(code_function_callt::argumentst::iterator
        a_it=code_function_call.arguments().begin();
        a_it!=code_function_call.arguments().end();
        a_it++)
      typecheck_expr(*a_it);
  }
}
Exemple #13
0
void c_typecheck_baset::typecheck_start_thread(codet &code)
{
  if(code.operands().size()!=1)
  {
    err_location(code);
    error() << "start_thread expected to have one operand" << eom;
    throw 0;
  }

  typecheck_code(to_code(code.op0()));
}
Exemple #14
0
static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct m5mols_info *info = to_m5mols(sd);

	if (enable) {
		if (info->code == to_code(M5MOLS_RES_MON)) {
			v4l2_info(sd, "%s : monitor mode\n", __func__);
			return m5mols_start_monitor(sd);
		}
		if (info->code == to_code(M5MOLS_RES_CAPTURE)) {
			v4l2_info(sd, "%s : capture mode\n", __func__);
			return  m5mols_start_capture(sd);
		}
		return -EINVAL;
	} else {
		if (is_streaming(sd))
			return m5mols_set_mode(sd, MODE_PARMSET);
		return -EINVAL;
	}
}
Exemple #15
0
void goto_program_dereferencet::dereference_instruction(
  goto_programt::targett target,
  bool checks_only)
{
  current_target=target;
  #if 0
  valid_local_variables=&target->local_variables;
  #endif
  goto_programt::instructiont &i=*target;

  dereference_expr(i.guard, checks_only, value_set_dereferencet::READ);

  if(i.is_assign())
  {
    if(i.code.operands().size()!=2)
      throw "assignment expects two operands";

    dereference_expr(i.code.op0(), checks_only, value_set_dereferencet::WRITE);
    dereference_expr(i.code.op1(), checks_only, value_set_dereferencet::READ);
  }
  else if(i.is_function_call())
  {
    code_function_callt &function_call=to_code_function_call(to_code(i.code));
    
    if(function_call.lhs().is_not_nil())
      dereference_expr(function_call.lhs(), checks_only, value_set_dereferencet::WRITE);
    
    dereference_expr(function_call.function(), checks_only, value_set_dereferencet::READ);
    dereference_expr(function_call.op2(), checks_only, value_set_dereferencet::READ);
  }
  else if(i.is_return())
  {
    Forall_operands(it, i.code)
      dereference_expr(*it, checks_only, value_set_dereferencet::READ);
  }
  else if(i.is_other())
  {
    const irep_idt &statement=i.code.get(ID_statement);

    if(statement==ID_expression)
    {
      if(i.code.operands().size()!=1)
        throw "expression expects one operand";

      dereference_expr(i.code.op0(), checks_only, value_set_dereferencet::READ);
    }
    else if(statement==ID_printf)
    {
      Forall_operands(it, i.code)
        dereference_expr(*it, checks_only, value_set_dereferencet::READ);
    }
  }
}
void goto_convertt::convert_CPROVER_try_finally(
  const codet &code,
  goto_programt &dest)
{
  if(code.operands().size()!=2)
  {
    err_location(code);
    throw "CPROVER_try_finally expects two arguments";
  }
  
  // first put 'finally' code onto destructor stack
  targets.destructor_stack.push_back(to_code(code.op1()));
  
  // do 'try' code
  convert(to_code(code.op0()), dest);

  // pop 'finally' from destructor stack
  targets.destructor_stack.pop_back();

  // now add 'finally' code
  convert(to_code(code.op1()), dest);
}
Exemple #17
0
void goto_symext::symex_dead(statet &state)
{
    const goto_programt::instructiont &instruction=*state.source.pc;

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

    if(code.operands().size()!=1)
        throw "dead expects one operand";

    if(code.op0().id()!=ID_symbol)
        throw "dead expects symbol as first operand";

    // We increase the L2 renaming to make these non-deterministic.
    // We also prevent propagation of old values.

    ssa_exprt ssa(to_symbol_expr(code.op0()));
    state.rename(ssa, ns, goto_symex_statet::L1);

    // in case of pointers, put something into the value set
    if(ns.follow(code.op0().type()).id()==ID_pointer)
    {
        exprt failed=
            get_failed_symbol(to_symbol_expr(code.op0()), ns);

        exprt rhs;

        if(failed.is_not_nil())
        {
            address_of_exprt address_of_expr;
            address_of_expr.object()=failed;
            address_of_expr.type()=code.op0().type();
            rhs=address_of_expr;
        }
        else
            rhs=exprt(ID_invalid);

        state.rename(rhs, ns, goto_symex_statet::L1);
        state.value_set.assign(ssa, rhs, ns, true, false);
    }

    ssa_exprt ssa_lhs=to_ssa_expr(ssa);
    const irep_idt &l1_identifier=ssa_lhs.get_identifier();

    // prevent propagation
    state.propagation.remove(l1_identifier);

    // L2 renaming
    if(state.level2.current_names.find(l1_identifier)!=
            state.level2.current_names.end())
        state.level2.increase_counter(l1_identifier);
}
void goto_convertt::convert_msc_try_except(
  const codet &code,
  goto_programt &dest)
{
  if(code.operands().size()!=3)
  {
    err_location(code);
    throw "msc_try_except expects three arguments";
  }

  convert(to_code(code.op0()), dest);
  
  // todo: generate exception tracking
}
Exemple #19
0
void goto_convertt::convert_msc_try_finally(
  const codet &code,
  goto_programt &dest)
{
  if(code.operands().size()!=2)
  {
    error().source_location=code.find_source_location();
    error() << "msc_try_finally expects two arguments" << eom;
    throw 0;
  }
  
  goto_programt tmp;
  tmp.add_instruction(SKIP)->source_location=code.source_location();

  {  
    // save 'leave' target
    leave_targett leave_target(targets);
    targets.set_leave(tmp.instructions.begin());
    
    // first put 'finally' code onto destructor stack
    targets.destructor_stack.push_back(to_code(code.op1()));
  
    // do 'try' code
    convert(to_code(code.op0()), dest);

    // pop 'finally' from destructor stack
    targets.destructor_stack.pop_back();
    
    // 'leave' target gets restored here
  }

  // now add 'finally' code
  convert(to_code(code.op1()), dest);
  
  // this is the target for 'leave'
  dest.destructive_append(tmp);
}
Exemple #20
0
void c_typecheck_baset::typecheck_block(codet &code)
{
  Forall_operands(it, code)
    typecheck_code(to_code(*it));

  // do decl-blocks

  exprt new_ops;
  new_ops.operands().reserve(code.operands().size());

  Forall_operands(it1, code)
  {
    if(it1->is_nil()) continue;

    codet &code_op=to_code(*it1);

    if(code_op.get_statement()==ID_label)
    {
      // these may be nested
      codet *code_ptr=&code_op;

      while(code_ptr->get_statement()==ID_label)
      {
        assert(code_ptr->operands().size()==1);
        code_ptr=&to_code(code_ptr->op0());
      }

      //codet &label_op=*code_ptr;

      new_ops.move_to_operands(code_op);
    }
    else
      new_ops.move_to_operands(code_op);
  }

  code.operands().swap(new_ops.operands());
}
Exemple #21
0
void goto_convertt::convert_msc_try_except(
  const codet &code,
  goto_programt &dest)
{
  if(code.operands().size()!=3)
  {
    error().source_location=code.find_source_location();
    error() << "msc_try_except expects three arguments" << eom;
    throw 0;
  }

  convert(to_code(code.op0()), dest);
  
  // todo: generate exception tracking
}
bool java_static_lifetime_init(
  symbol_tablet &symbol_table,
  const source_locationt &source_location,
  message_handlert &message_handler)
{
  symbolt &initialize_symbol=symbol_table.lookup(INITIALIZE);
  code_blockt &code_block=to_code_block(to_code(initialize_symbol.value));
  
  // we need to zero out all static variables
  
  for(symbol_tablet::symbolst::const_iterator
      it=symbol_table.symbols.begin();
      it!=symbol_table.symbols.end();
      it++)
  {
    if(it->second.type.id()!=ID_code &&
       it->second.is_lvalue &&
       it->second.is_state_var &&
       it->second.is_static_lifetime &&
       it->second.value.is_not_nil() &&
       it->second.mode==ID_java)
    {
      code_assignt assignment(it->second.symbol_expr(), it->second.value);
      code_block.add(assignment);
    }
  }
  
  // we now need to run all the <clinit> methods

  for(symbol_tablet::symbolst::const_iterator
      it=symbol_table.symbols.begin();
      it!=symbol_table.symbols.end();
      it++)
  {
    if(it->second.base_name=="<clinit>" &&
       it->second.type.id()==ID_code &&
       it->second.mode==ID_java)
    {
      code_function_callt function_call;
      function_call.lhs()=nil_exprt();
      function_call.function()=it->second.symbol_expr();
      code_block.add(function_call);
    }
  }
  
  return false;
}
exprt flow_insensitive_abstract_domain_baset::get_return_lhs(locationt to) const
{
  // get predecessor of "to"

  to--;

  if(to->is_end_function())
    return static_cast<const exprt &>(get_nil_irep());

  // must be the function call
  assert(to->is_function_call());

  const code_function_callt &code=
    to_code_function_call(to_code(to->code));

  return code.lhs();
}
Exemple #24
0
void goto_symext::symex_decl(statet &state)
{
  const goto_programt::instructiont &instruction=*state.source.pc;

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

  if(code.operands().size()==2)
    throw "two-operand decl not supported here";

  if(code.operands().size()!=1)
    throw "decl expects one operand";

  if(code.op0().id()!=ID_symbol)
    throw "decl expects symbol as first operand";

  symex_decl(state, to_symbol_expr(code.op0()));
}
Exemple #25
0
void goto_convert(
  contextt &context,
  optionst &options,
  goto_programt &dest,
  message_handlert &message_handler)
{
  // find main symbol
  const symbolst::const_iterator s_it=
    context.symbols.find("main");

  if(s_it==context.symbols.end())
    throw "failed to find main symbol";

  const symbolt &symbol=s_it->second;

  std::cout << "goto_convert : start converting symbol table to goto functions " << std::endl;
  ::goto_convert(to_code(symbol.value), context, options, dest, message_handler);
}
Exemple #26
0
void c_typecheck_baset::typecheck_gcc_switch_case_range(codet &code)
{
  if(code.operands().size()!=3)
  {
    err_location(code);
    error() << "gcc_switch_case_range expected to have three operands"
            << eom;
    throw 0;
  }

  typecheck_code(to_code(code.op2()));

  if(!case_is_allowed)
  {
    err_location(code);
    error() << "did not expect `case' here" << eom;
    throw 0;
  }

  typecheck_expr(code.op0());
  typecheck_expr(code.op1());
  implicit_typecast(code.op0(), switch_op_type);
  implicit_typecast(code.op1(), switch_op_type);
}
Exemple #27
0
void termination_baset::find_required_steps(
  const goto_tracet &goto_trace,
  goto_tracet::stepst::const_iterator &loop_begin,
  required_stepst &required_steps,
  const std::string &prefix) const
{
  find_symbols_sett required_symbols;
  unsigned before=0, after=1;

  // initialize: find all (potential) loop exits and
  // remember the symbols in them
  for(goto_tracet::stepst::const_iterator it1=loop_begin;
      it1!=goto_trace.steps.end();
      it1++)
  {
    if(it1->pc->is_goto() &&
       it1->pc->function==loop_begin->pc->function)
    {
      bool found_next=false, found_target=false;
      goto_programt::const_targett next=it1->pc; next++;
      goto_programt::const_targett target=it1->pc->targets.front();

      for(goto_tracet::stepst::const_iterator it2=loop_begin;
          it2!=goto_trace.steps.end();
          it2++)
      {
        if(it1!=it2)
        {
          if(it2->pc==next)
            found_next=true;
          else if(it2->pc==target)
            found_target=true;
        }
      }

      if(!found_target || !found_next)
      {
        exprt temp=it1->cond_expr;
        remove_ssa_ids(temp);
        find_symbols(temp, required_symbols);
      }
    }
  }

  #if 0
  std::cout << "INITIAL SYMBOLS: ";
  for(find_symbols_sett::const_iterator it=required_symbols.begin();
      it!=required_symbols.end();
      it++)
    std::cout << *it << ", ";
  std::cout << std::endl;
  #endif

  // get the fixpoint
  while(before!=after)
  {
    before=required_symbols.size();

    for(goto_tracet::stepst::const_iterator step=loop_begin;
        step!=goto_trace.steps.end();
        step++)
    {
      find_symbols_sett intersection;

      if(step->is_assignment())
      {
        exprt lhs, rhs;

        const codet &code=to_code(step->pc->code);

        if(code.get_statement()==ID_assign)
        {
          const code_assignt &acode=to_code_assign(step->pc->code);
          lhs=acode.lhs();
          rhs=acode.rhs();
        }
        else if(code.get_statement()==ID_function_call)
        {
          const code_function_callt fcode=to_code_function_call(step->pc->code);
          lhs=fcode.lhs();
          rhs=fcode.op2();
        }
        else
          throw "Unexpected assign statement";

        if(lhs.id()==ID_symbol &&
           has_prefix(lhs.get_string(ID_identifier), prefix))
        {
          // if we depend on the RHS syms, we also need the pre-symbol
          find_symbols_sett rhs_sym;
          find_symbols(rhs, rhs_sym);

          if(intersects(rhs_sym, required_symbols))
          {
            find_symbols(lhs, required_symbols);
            required_steps.insert(&(*step));
          }
        }
        else
        {
          find_symbols_sett lhs_sym;

          if(lhs.id()==ID_index)
            find_symbols(lhs.op0(), lhs_sym); // we're not modifying the index
          else
            find_symbols(lhs, lhs_sym);

           if(intersects(lhs_sym, required_symbols))
           {
             find_symbols(rhs, required_symbols);
             required_steps.insert(&(*step));
           }
        }
      }
      else if(step->is_assume())
      {
        find_symbols_sett syms;
        find_symbols(step->pc->guard, syms);

        if(intersects(syms, required_symbols))
        {
          required_symbols.insert(syms.begin(), syms.end());
          required_steps.insert(&(*step));
        }
      }
    }

    after=required_symbols.size();

  #if 0
  std::cout << "REQUIRED SYMBOLS: ";
  for(find_symbols_sett::const_iterator it=required_symbols.begin();
      it!=required_symbols.end();
      it++)
    std::cout << *it << ", ";
  std::cout << std::endl;
  #endif
  }
}
Exemple #28
0
bool static_lifetime_init(
  symbol_tablet &symbol_table,
  const source_locationt &source_location,
  message_handlert &message_handler)
{
  namespacet ns(symbol_table);

  symbol_tablet::symbolst::iterator s_it=
    symbol_table.symbols.find(INITIALIZE_FUNCTION);

  if(s_it==symbol_table.symbols.end())
    return false;

  symbolt &init_symbol=s_it->second;

  init_symbol.value=code_blockt();
  init_symbol.value.add_source_location()=source_location;

  code_blockt &dest=to_code_block(to_code(init_symbol.value));

  // add the magic label to hide
  dest.add(code_labelt("__CPROVER_HIDE", code_skipt()));

  // do assignments based on "value"

  // sort alphabetically for reproducible results
  std::set<std::string> symbols;

  forall_symbols(it, symbol_table.symbols)
    symbols.insert(id2string(it->first));

  for(const std::string &id : symbols)
  {
    const symbolt &symbol=ns.lookup(id);

    const irep_idt &identifier=symbol.name;

    if(!symbol.is_static_lifetime)
      continue;

    if(symbol.is_type || symbol.is_macro)
      continue;

    // special values
    if(identifier==CPROVER_PREFIX "constant_infinity_uint" ||
       identifier==CPROVER_PREFIX "memory" ||
       identifier=="__func__" ||
       identifier=="__FUNCTION__" ||
       identifier=="__PRETTY_FUNCTION__" ||
       identifier=="argc'" ||
       identifier=="argv'" ||
       identifier=="envp'" ||
       identifier=="envp_size'")
      continue;

    // just for linking
    if(has_prefix(id, CPROVER_PREFIX "architecture_"))
      continue;

    const typet &type=ns.follow(symbol.type);

    // check type
    if(type.id()==ID_code ||
       type.id()==ID_empty)
      continue;

    // We won't try to initialize any symbols that have
    // remained incomplete.

    if(symbol.value.is_nil() &&
       symbol.is_extern)
      // Compilers would usually complain about these
      // symbols being undefined.
      continue;

    if(type.id()==ID_array &&
       to_array_type(type).size().is_nil())
    {
      // C standard 6.9.2, paragraph 5
      // adjust the type to an array of size 1
      symbol_tablet::symbolst::iterator it=
        symbol_table.symbols.find(identifier);
      assert(it!=symbol_table.symbols.end());

      it->second.type=type;
      it->second.type.set(ID_size, from_integer(1, size_type()));
    }

    if(type.id()==ID_incomplete_struct ||
       type.id()==ID_incomplete_union)
      continue; // do not initialize

    if(symbol.value.id()==ID_nondet)
      continue; // do not initialize

    exprt rhs;

    if(symbol.value.is_nil())
    {
      try
      {
        namespacet ns(symbol_table);
        rhs=zero_initializer(symbol.type, symbol.location, ns, message_handler);
        assert(rhs.is_not_nil());
      }
      catch(...)
      {
        return true;
      }
    }
    else
      rhs=symbol.value;

    code_assignt code(symbol.symbol_expr(), rhs);
    code.add_source_location()=symbol.location;

    dest.move_to_operands(code);
  }

  // call designated "initialization" functions

  for(const std::string &id : symbols)
  {
    const symbolt &symbol=ns.lookup(id);

    if(symbol.type.id()==ID_code &&
       to_code_type(symbol.type).return_type().id()==ID_constructor)
    {
      code_function_callt function_call;
      function_call.function()=symbol.symbol_expr();
      function_call.add_source_location()=source_location;
      dest.move_to_operands(function_call);
    }
  }

  return false;
}
Exemple #29
0
void c_typecheck_baset::typecheck_function_body(symbolt &symbol)
{
  code_typet &code_type=to_code_type(symbol.type);
  
  assert(symbol.value.is_not_nil());
  
  // reset labels
  labels_used.clear();
  labels_defined.clear();

  // fix type
  symbol.value.type()=code_type;
    
  // set return type
  return_type=code_type.return_type();
  
  unsigned anon_counter=0;
  
  // Add the parameter declarations into the symbol table.
  code_typet::parameterst &parameters=code_type.parameters();
  for(code_typet::parameterst::iterator
      p_it=parameters.begin();
      p_it!=parameters.end();
      p_it++)
  {
    // may be anonymous
    if(p_it->get_base_name()==irep_idt())
    {
      irep_idt base_name="#anon"+i2string(anon_counter++);
      p_it->set_base_name(base_name);
    }
    
    // produce identifier
    irep_idt base_name=p_it->get_base_name();
    irep_idt identifier=id2string(symbol.name)+"::"+id2string(base_name);

    p_it->set_identifier(identifier);

    parameter_symbolt p_symbol;
    
    p_symbol.type=p_it->type();
    p_symbol.name=identifier;
    p_symbol.base_name=base_name;
    p_symbol.location=p_it->source_location();

    symbolt *new_p_symbol;
    move_symbol(p_symbol, new_p_symbol);
  }

  // typecheck the body code  
  typecheck_code(to_code(symbol.value));

  // special case for main()  
  if(symbol.name==ID_main)
    add_argc_argv(symbol);

  // check the labels
  for(std::map<irep_idt, source_locationt>::const_iterator
      it=labels_used.begin(); it!=labels_used.end(); it++)
  {
    if(labels_defined.find(it->first)==labels_defined.end())
    {
      err_location(it->second);
      str << "branching label `" << it->first
          << "' is not defined in function";
      throw 0;
    }
  }
}
Exemple #30
0
void jsil_typecheckt::typecheck_block(codet &code)
{
  Forall_operands(it, code)
    typecheck_code(to_code(*it));
}