Пример #1
0
void stack_depth(
  symbol_tablet &symbol_table,
  goto_functionst &goto_functions,
  const int depth)
{
  const symbol_exprt sym=add_stack_depth_symbol(symbol_table);
  const exprt depth_expr(from_integer(depth, sym.type()));

  Forall_goto_functions(f_it, goto_functions)
    if(f_it->second.body_available &&
        f_it->first!=CPROVER_PREFIX "initialize" &&
        f_it->first!=ID_main)
      stack_depth(f_it->second.body, sym, depth, depth_expr);

  // initialize depth to 0
  goto_functionst::function_mapt::iterator
    i_it=goto_functions.function_map.find(CPROVER_PREFIX "initialize");
  assert(i_it!=goto_functions.function_map.end());

  goto_programt &init=i_it->second.body;
  goto_programt::targett first=init.instructions.begin();
  goto_programt::targett it=init.insert_before(first);
  it->make_assignment();
  it->code=code_assignt(sym, from_integer(0, sym.type()));
  it->location=first->location;
  it->function=first->function;

  // update counters etc.
  goto_functions.update();
}
Пример #2
0
exprt interval_domaint::make_expression(const symbol_exprt &src) const
{
  if(is_int(src.type()))
  {
    int_mapt::const_iterator i_it=int_map.find(src.get_identifier());
    if(i_it==int_map.end()) return true_exprt();
    const integer_intervalt &interval=i_it->second;
    if(interval.is_top()) return true_exprt();
    if(interval.is_bottom()) return false_exprt();

    exprt::operandst conjuncts;

    if(interval.upper_set) 
    {
      exprt tmp=from_integer(interval.upper, src.type());
      conjuncts.push_back(binary_relation_exprt(src, ID_le, tmp));
    }

    if(interval.lower_set) 
    {
      exprt tmp=from_integer(interval.lower, src.type());
      conjuncts.push_back(binary_relation_exprt(tmp, ID_le, src));
    }
  
    return conjunction(conjuncts);
  }
  else if(is_float(src.type()))
  {
    float_mapt::const_iterator i_it=float_map.find(src.get_identifier());
    if(i_it==float_map.end()) return true_exprt();
    const ieee_float_intervalt &interval=i_it->second;
    if(interval.is_top()) return true_exprt();
    if(interval.is_bottom()) return false_exprt();

    exprt::operandst conjuncts;

    if(interval.upper_set) 
    {
      exprt tmp=interval.upper.to_expr();
      conjuncts.push_back(binary_relation_exprt(src, ID_le, tmp));
    }

    if(interval.lower_set) 
    {
      exprt tmp=interval.lower.to_expr();
      conjuncts.push_back(binary_relation_exprt(tmp, ID_le, src));
    }
  
    return conjunction(conjuncts);
  }
  else
    return true_exprt();
}
Пример #3
0
void stack_depth(
  goto_programt &goto_program,
  const symbol_exprt &symbol,
  const int i_depth,
  const exprt &max_depth)
{
  assert(!goto_program.instructions.empty());

  goto_programt::targett first=goto_program.instructions.begin();

  binary_relation_exprt guard(symbol, ID_le, max_depth);
  goto_programt::targett assert_ins=goto_program.insert_before(first);
  assert_ins->make_assertion(guard);
  assert_ins->location=first->location;
  assert_ins->function=first->function;

  assert_ins->location.set_comment("Stack depth exceeds "+i2string(i_depth));
  assert_ins->location.set_property("stack-depth");

  goto_programt::targett plus_ins=goto_program.insert_before(first);
  plus_ins->make_assignment();
  plus_ins->code=code_assignt(symbol,
      plus_exprt(symbol, from_integer(1, symbol.type())));
  plus_ins->location=first->location;
  plus_ins->function=first->function;

  goto_programt::targett last=--goto_program.instructions.end();
  assert(last->is_end_function());

  goto_programt::instructiont minus_ins;
  minus_ins.make_assignment();
  minus_ins.code=code_assignt(symbol,
      minus_exprt(symbol, from_integer(1, symbol.type())));
  minus_ins.location=last->location;
  minus_ins.function=last->function;

  goto_program.insert_before_swap(last, minus_ins);
}
Пример #4
0
void assume_renondet_inputs_valid(jsa_programt &prog)
{
  if (prog.counterexample_locations.empty()) return;
  const symbol_tablet &st=prog.st;
  goto_programt &body=get_entry_body(prog.gf);

  for (const goto_programt::targett &pos : prog.inductive_step_renondets)
  {
    const irep_idt &id=get_affected_variable(*pos);
    const symbol_exprt lhs(st.lookup(id).symbol_expr());
    const typet &type=lhs.type();
    if (is_jsa_heap(type))
      assume_valid_heap(st, body, pos, address_of_exprt(lhs));
  }
}
Пример #5
0
void acceleratet::build_state_machine(
  trace_automatont::sym_mapt::iterator begin,
  trace_automatont::sym_mapt::iterator end,
  state_sett &accept_states,
  symbol_exprt state,
  symbol_exprt next_state,
  scratch_programt &state_machine)
{
  std::map<unsigned int, unsigned int> successor_counts;
  unsigned int max_count=0;
  unsigned int likely_next=0;

  // Optimisation: find the most common successor state and initialise
  // next_state to that value.  This reduces the size of the state machine
  // driver substantially.
  for(trace_automatont::sym_mapt::iterator p=begin; p!=end; ++p)
  {
    trace_automatont::state_pairt state_pair=p->second;
    unsigned int to=state_pair.second;
    unsigned int count=0;

    if(successor_counts.find(to)==successor_counts.end())
    {
      count=1;
    }
    else
    {
      count=successor_counts[to] + 1;
    }

    successor_counts[to]=count;

    if(count > max_count)
    {
      max_count=count;
      likely_next=to;
    }
  }

  // Optimisation: if there is only one possible successor state, just
  // jump straight to it instead of driving the whole machine.
  if(successor_counts.size()==1)
  {
    if(accept_states.find(likely_next)!=accept_states.end())
    {
      // It's an accept state.  Just assume(false).
      state_machine.assume(false_exprt());
    }
    else
    {
      state_machine.assign(state,
          from_integer(likely_next, next_state.type()));
    }

    return;
  }

  state_machine.assign(next_state,
      from_integer(likely_next, next_state.type()));

  for(trace_automatont::sym_mapt::iterator p=begin; p!=end; ++p)
  {
    trace_automatont::state_pairt state_pair=p->second;
    unsigned int from=state_pair.first;
    unsigned int to=state_pair.second;

    if(to==likely_next)
    {
      continue;
    }

    // We're encoding the transition
    //
    //   from -loc-> to
    //
    // which we encode by inserting:
    //
    //   next_state=(state==from) ? to : next_state;
    //
    // just before loc.
    equal_exprt guard(state, from_integer(from, state.type()));
    if_exprt rhs(guard, from_integer(to, next_state.type()), next_state);
    state_machine.assign(next_state, rhs);
  }

  // Update the state and assume(false) if we've hit an accept state.
  state_machine.assign(state, next_state);

  for(state_sett::iterator it=accept_states.begin();
      it!=accept_states.end();
      ++it)
  {
    state_machine.assume(
      not_exprt(equal_exprt(state, from_integer(*it, state.type()))));
  }
}
Пример #6
0
void jsil_typecheckt::typecheck_symbol_expr(symbol_exprt &symbol_expr)
{
  irep_idt identifier=symbol_expr.get_identifier();

  // if this is a built-in identifier, check if it exists in the
  // symbol table and retrieve it's type
  // TODO: add a flag for not needing to prefix internal symbols
  // that do not start with hash
  if(has_prefix(id2string(identifier), "#") ||
     identifier=="eval" ||
     identifier=="nan")
  {
    symbol_tablet::symbolst::const_iterator s_it=
      symbol_table.symbols.find(identifier);

    if(s_it==symbol_table.symbols.end())
      throw "unexpected internal symbol: "+id2string(identifier);
    else
    {
      // symbol already exists
      const symbolt &symbol=s_it->second;

      // type the expression
      symbol_expr.type()=symbol.type;
    }
  }
  else
  {
    // if this is a variable, we need to check if we already
    // prefixed it and add to the symbol table if it is not there already
    irep_idt identifier_base = identifier;
    if(!has_prefix(id2string(identifier), id2string(proc_name)))
    {
      identifier = add_prefix(identifier);
      symbol_expr.set_identifier(identifier);
    }

    symbol_tablet::symbolst::const_iterator s_it=
    symbol_table.symbols.find(identifier);

    if(s_it==symbol_table.symbols.end())
    {
      // create new symbol
      symbolt new_symbol;
      new_symbol.name=identifier;
      new_symbol.type=symbol_expr.type();
      new_symbol.base_name=identifier_base;
      new_symbol.mode="jsil";
      new_symbol.is_type=false;
      new_symbol.is_lvalue=new_symbol.type.id()!=ID_code;

      // mark as already typechecked
      new_symbol.is_extern=true;

      if(symbol_table.add(new_symbol))
      {
        error() << "failed to add symbol `"
                << new_symbol.name << "' in the symbol table"
                << eom;
        throw 0;
      }
    }
    else
    {
      // symbol already exists
      assert(!s_it->second.is_type);

      const symbolt &symbol=s_it->second;

      // type the expression
      symbol_expr.type()=symbol.type;
    }
  }
}
Пример #7
0
bool is_jsa_const(const symbol_exprt &symbol)
{
  const std::string &id=id2string(symbol.get_identifier());
  if (std::string::npos != id.find(JSA_CONSTANT_PREFIX)) return true;
  return symbol.type().get_bool(ID_C_constant);
}
Пример #8
0
void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
{
  // We increase the L2 renaming to make these non-deterministic.
  // We also prevent propagation of old values.

  ssa_exprt ssa(expr);
  state.rename(ssa, ns, goto_symex_statet::L1);
  const irep_idt &l1_identifier=ssa.get_identifier();

  // rename type to L2
  state.rename(ssa.type(), l1_identifier, ns);
  ssa.update_type();

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

    exprt rhs;

    if(failed.is_not_nil())
    {
      address_of_exprt address_of_expr;
      address_of_expr.object()=failed;
      address_of_expr.type()=expr.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);
  }

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

  // L2 renaming
  // inlining may yield multiple declarations of the same identifier
  // within the same L1 context
  if(state.level2.current_names.find(l1_identifier)==
     state.level2.current_names.end())
    state.level2.current_names[l1_identifier]=std::make_pair(ssa, 0);
  state.level2.increase_counter(l1_identifier);
  const bool record_events=state.record_events;
  state.record_events=false;
  state.rename(ssa, ns);
  state.record_events=record_events;

  // we hide the declaration of auxiliary variables
  // and if the statement itself is hidden
  bool hidden=
    ns.lookup(expr.get_identifier()).is_auxiliary ||
    state.top().hidden_function ||
    state.source.pc->source_location.get_hide();

  target.decl(
    state.guard.as_expr(),
    ssa,
    state.source,
    hidden?symex_targett::HIDDEN:symex_targett::STATE);

  assert(state.dirty);
  if((*state.dirty)(ssa.get_object_name()) &&
     state.atomic_section_id==0)
    target.shared_write(
      state.guard.as_expr(),
      ssa,
      state.atomic_section_id,
      state.source);
}