Beispiel #1
0
int join(){
	int t,t1,t2;
	t1 = equality();
	t = t1;
	while(look->tag == AND){
		t = temp++;
		move();
		t2 = equality();
		gen("t%d = t%d && t%d\n",t,t1,t2);
		t1 = t;
	}
	return t;
}
NodeInt join(){
	int nodeL = equality();
	switch (CurrToken) {
		case AND_OP:{
			Token tok = mutch(AND_OP);
			NodeInt nodeR = equality();
			return AddNode(tok, nodeL, 0,nodeR);
			break;
		}
		default:
			break;
	}
	return nodeL;
}
Beispiel #3
0
int check(int nGood[], int nNum ) {
    int nFlag;
	int nCntr1;
	int nCntr2;
	int nCnt;
	int nLen;
	int nLoop;
	long nVar1;
	long nVar2;
	for(nLen=0;nLen<=nNum;nLen++);
	nLen--;
	nFlag=0;
    for(nCntr1=nLen,nCntr2=nLen-1; nCntr1>=0 && nCntr2 >=0; nCntr1-=1, nCntr2-=2) {
	    nCnt=0;
		nVar1=0;
		nVar2=0;
		for(nLoop=nLen; nLoop >= nCntr1; nLoop--,nCnt++)
		    nVar1=nVar1*10+(long)nGood[nLoop];
		for(nLoop=nCntr1-1; nLoop >= nCntr2; nLoop--)
		    nVar2=nVar2*10+(long)nGood[nLoop];
		nFlag=equality(nVar1,nVar2,nCnt);
		if(nFlag>0)
		    return nFlag;
    }
	return nFlag;
}
Beispiel #4
0
			rectangle_packer (int _nb_screen, const pair & vscreen_min_size, const pair & vscreen_max_size, const pair_list & screen_sizes, const sequence_pair & layout) : nb_screen (_nb_screen) {
				init_solver ();

				// Virtual screen boundaries
				more_than_const (v_vscreen_size (X), vscreen_min_size.x); less_than_const (v_vscreen_size (X), vscreen_max_size.x);
				more_than_const (v_vscreen_size (Y), vscreen_min_size.y); less_than_const (v_vscreen_size (Y), vscreen_max_size.y);

				// Screens inside virtual screen
				for (int sc = 0; sc < nb_screen; ++sc) {
					positive_or_zero (v_screen_pos (sc, X)); offseted_less_than_var (v_screen_pos (sc, X), screen_sizes[sc].x, v_vscreen_size (X));
					positive_or_zero (v_screen_pos (sc, Y)); offseted_less_than_var (v_screen_pos (sc, Y), screen_sizes[sc].y, v_vscreen_size (Y));
				}

				// Screen ordering constraints
				for (int sa = 0;  sa < nb_screen; ++sa)
					for (int sb = 0; sb < sa; ++sb)
						switch (layout.ordering (sa, sb)) {
							case left: offseted_less_than_var (v_screen_pos (sa, X), screen_sizes[sa].x, v_screen_pos (sb, X)); break;
							case right: offseted_less_than_var (v_screen_pos (sb, X), screen_sizes[sb].x, v_screen_pos (sa, X)); break;
							case above: offseted_less_than_var (v_screen_pos (sa, Y), screen_sizes[sa].y, v_screen_pos (sb, Y)); break;
							case under: offseted_less_than_var (v_screen_pos (sb, Y), screen_sizes[sb].y, v_screen_pos (sa, Y)); break;
							default: throw std::runtime_error ("rectangle_packer: unordered screens despite sequence pair"); 
						}

				/* Objective function. sum of :
				 * - constraint gap length
				 * - distance between centers on second axis
				 */	
				const int constraint_gap_coeff = 1;
				const int center_distance_coeff = 1;
				
				std::vector< int > coeffs (v_nb (), 0); // More practical to gather coeffs
				coeffs[v_objective ()] = -1; // 0 = -o + sum(...)

				for (int sa = 0;  sa < nb_screen; ++sa)
					for (int sb = 0; sb < sa; ++sb)
						switch (layout.ordering (sa, sb)) {
							case left:
								coeffs[v_screen_pos (sa, X)] -= constraint_gap_coeff; coeffs[v_screen_pos (sb, X)] += constraint_gap_coeff; // o += sb.x - sa.x
								coeffs[distance_var (v_screen_pos (sa, Y), screen_sizes[sa].y, v_screen_pos (sb, Y), screen_sizes[sb].y)] += center_distance_coeff; // o += dist (sa.cy, sb.cy)
								break;
							case right:
								coeffs[v_screen_pos (sb, X)] -= constraint_gap_coeff; coeffs[v_screen_pos (sa, X)] += constraint_gap_coeff; // o += sa.x - sb.x
								coeffs[distance_var (v_screen_pos (sb, Y), screen_sizes[sb].y, v_screen_pos (sa, Y), screen_sizes[sa].y)] += center_distance_coeff; // o += dist (sb.cy, sa.cy)
								break;
							case above:
								coeffs[v_screen_pos (sa, Y)] -= constraint_gap_coeff; coeffs[v_screen_pos (sb, Y)] += constraint_gap_coeff; // o += sb.y - sa.y
								coeffs[distance_var (v_screen_pos (sa, X), screen_sizes[sa].x, v_screen_pos (sb, X), screen_sizes[sb].x)] += center_distance_coeff; // o += dist (sa.cx, sb.cx)
								break;
							case under:
								coeffs[v_screen_pos (sb, Y)] -= constraint_gap_coeff; coeffs[v_screen_pos (sa, Y)] += constraint_gap_coeff; // o += sa.y - sb.y
								coeffs[distance_var (v_screen_pos (sb, X), screen_sizes[sb].x, v_screen_pos (sa, X), screen_sizes[sa].x)] += center_distance_coeff; // o += dist (sb.cx, sa.cx)
								break;
							default:
								break; // Error handled before
						}
				equality (coeffs);
			}
Beispiel #5
0
void path_searcht::do_show_vcc(
  statet &state,
  const namespacet &ns)
{
  // keep statistics
  number_of_VCCs++;
  
  const goto_programt::instructiont &instruction=
    *state.get_instruction();
    
  mstreamt &out=result();

  if(instruction.location.is_not_nil())
    out << instruction.location << "\n";
  
  if(instruction.location.get_comment()!="")
    out << instruction.location.get_comment() << "\n";
    
  unsigned count=1;
  
  std::vector<path_symex_step_reft> steps;
  state.history.build_history(steps);

  for(std::vector<path_symex_step_reft>::const_iterator
      s_it=steps.begin();
      s_it!=steps.end();
      s_it++)
  {      
    if((*s_it)->guard.is_not_nil())
    {
      std::string string_value=from_expr(ns, "", (*s_it)->guard);
      out << "{-" << count << "} " << string_value << "\n";
      count++;
    }

    if((*s_it)->ssa_rhs.is_not_nil())
    {
      equal_exprt equality((*s_it)->ssa_lhs, (*s_it)->ssa_rhs);
      std::string string_value=from_expr(ns, "", equality);
      out << "{-" << count << "} " << string_value << "\n";
      count++;
    }
  }

  out << "|--------------------------" << "\n";
  
  exprt assertion=state.read(instruction.guard);

  out << "{" << 1 << "} "
      << from_expr(ns, "", assertion) << "\n";

  if(!assertion.is_true())
    number_of_VCCs_after_simplification++;
  
  out << eom;
}
Beispiel #6
0
void local_SSAt::build_cond(locationt loc)
{
  // anything to be built?
  if(!loc->is_goto() &&
     !loc->is_assume()) return;
  
  // produce a symbol for the renamed branching condition
  equal_exprt equality(cond_symbol(loc), read_rhs(loc->guard, loc));
  nodes[loc].equalities.push_back(equality);
}
Beispiel #7
0
void path_searcht::do_show_vcc(statet &state)
{
  // keep statistics
  number_of_VCCs++;

  const goto_programt::instructiont &instruction=
    *state.get_instruction();

  mstreamt &out=result();

  if(instruction.source_location.is_not_nil())
    out << instruction.source_location << '\n';

  if(instruction.source_location.get_comment()!="")
    out << instruction.source_location.get_comment() << '\n';

  unsigned count=1;

  std::vector<path_symex_step_reft> steps;
  state.history.build_history(steps);

  for(const auto &step_ref : steps)
  {
    if(step_ref->guard.is_not_nil())
    {
      std::string string_value=from_expr(ns, "", step_ref->guard);
      out << "{-" << count << "} " << string_value << '\n';
      count++;
    }

    if(step_ref->ssa_rhs.is_not_nil())
    {
      equal_exprt equality(step_ref->ssa_lhs, step_ref->ssa_rhs);
      std::string string_value=from_expr(ns, "", equality);
      out << "{-" << count << "} " << string_value << '\n';
      count++;
    }
  }

  out << "|--------------------------" << '\n';

  exprt assertion=state.read(instruction.guard);

  out << "{" << 1 << "} "
      << from_expr(ns, "", assertion) << '\n';

  if(!assertion.is_true())
    number_of_VCCs_after_simplification++;

  out << eom;
}
Beispiel #8
0
int
list_iassoc(Var vtarget, Var vlist, int vindex)
{
    int i;

    for (i = 1; i <= vlist.v.list[0].v.num; i++) {
        if (vlist.v.list[i].type == TYPE_LIST &&
                vlist.v.list[i].v.list[0].v.num >= vindex &&
                equality(vlist.v.list[i].v.list[vindex], vtarget, 0)) {

            return i;
        }
    }
    return 0;
}
Beispiel #9
0
Var
list_assoc(Var vtarget, Var vlist, int vindex)
{
    int i;

    for (i = 1; i <= vlist.v.list[0].v.num; i++) {
        if (vlist.v.list[i].type == TYPE_LIST &&
                vlist.v.list[i].v.list[0].v.num >= vindex &&
                equality(vlist.v.list[i].v.list[vindex], vtarget, 0)) {

            return var_dup(vlist.v.list[i]);
        }
    }
    return new_list(0);
}
Beispiel #10
0
bodyt termination_baset::get_body(
  goto_tracet::stepst::const_iterator &loop_begin,
  const goto_tracet &trace)
{
  bodyt result_body;
  exprt::operandst op;
  const goto_trace_stept &assertion=trace.steps.back();

  // let's get a loop number as well:
  assert(assertion.pc->guard.id()=="=>");
  std::string c_str = assertion.pc->guard.op0().get_string("identifier");
  std::string prefix = termination_prefix+
                       c_str.substr(c_str.rfind("_")+1) + "::";

  // find out what we actually need
  required_stepst required_steps;
  find_required_steps(trace, loop_begin, required_steps, prefix);

  /* We perform a new SSA-conversion. However, since we can only
     get a single path through the program, there are no joins and
     thus no phi-functions. We just increment counters. */

  std::map<irep_idt, unsigned> ssa_counters;
  replace_idt replace_id;

  // get the required body constraints
  for(goto_tracet::stepst::const_iterator step=loop_begin;
      step!=--trace.steps.end();
      step++)
  {
    last_path.push_back(step->pc);

    // required_stepst::const_iterator fit=required_steps.find(&(*step));
    // if(fit==required_steps.end()) continue;

    switch(step->pc->type)
    {
      case ASSIGN:
      {
        const code_assignt &code=to_code_assign(step->pc->code);
        find_symbols_sett w;
        find_symbols_w(code.lhs(), w);

        equal_exprt equality(code.lhs(), code.rhs());
        replace_id.replace(equality.rhs());

        // All the written ones get their SSA-ID updated
        for(find_symbols_sett::const_iterator it=w.begin();
            it!=w.end();
            it++)
        {
          // Are we writing a pre-variable?
          if(has_prefix(id2string(*it), prefix))
          {
            assert(code.rhs().id()==ID_symbol);
            const irep_idt &post_id=code.rhs().get(ID_identifier);
            const irep_idt &pre_id=code.lhs().get(ID_identifier);
            result_body.variable_map[post_id]=pre_id;

            // the RHS gets a #0 id
            irep_idt new_id=id2string(post_id)+"!0";
            replace_id.insert(post_id, new_id);
            equality.rhs().set(ID_identifier, new_id);
          }
          else
          {
            const irep_idt &old_id=*it;
            unsigned cur=++ssa_counters[old_id]; // 0 is never used

            // gets a new ID
            irep_idt new_id=id2string(old_id)+"!"+i2string(cur);
            replace_id.insert(old_id, new_id);
          }
        }

        replace_id.replace(equality.lhs());
        op.push_back(equality);
        break;
      }
      case ASSUME:
      case ASSERT:
      {
        if(!step->cond_expr.is_true() && !step->cond_expr.is_nil())
        {
          exprt guard=step->cond_expr; // That's SSA!
          remove_ssa_ids(guard);
//          exprt guard=step->pc->guard;

          find_symbols_sett syms;
          find_symbols(guard, syms);

          for(find_symbols_sett::const_iterator it=syms.begin();
              it!=syms.end();
              it++)
          {
            if(ssa_counters.find(*it)==ssa_counters.end())
            {
              irep_idt new_id=id2string(*it)+"!"+i2string(++ssa_counters[*it]);
              replace_id.insert(*it, new_id);
            }
          }

          replace_id.replace(guard);
          if(!step->cond_value) guard.negate();
          op.push_back(guard);
        }
        break;
      }
      case GOTO:
      {
        if(!step->cond_expr.is_nil())
        {
//          exprt guard=step->pc->guard;
          exprt guard=step->cond_expr;
          remove_ssa_ids(guard);

          find_symbols_sett syms;
          find_symbols(guard, syms);

          for(find_symbols_sett::const_iterator it=syms.begin();
              it!=syms.end();
              it++)
          {
            if(ssa_counters.find(*it)==ssa_counters.end())
            {
              ssa_counters[*it]=0;
              irep_idt new_id=id2string(*it)+"!"+i2string(0);
              replace_id.insert(*it, new_id);
            }
          }

          replace_id.replace(guard);
          if(!step->cond_value)
            guard.negate();
          op.push_back(guard);
        }
        break;
      }
      case DECL: /* nothing */ break;
	    case LOCATION: /* These can show up here? */ break;
      default:
        throw std::string("unexpected instruction type.");
    }
  }

  // the final result, which (again) contains SSA variables
  exprt &body_expr = result_body.body_relation;
  body_expr = and_exprt(op);

  if(result_body.variable_map.empty())
  {
    // used to be:
    // throw "BUG: No variables found; path missing.";
    // Though: No variable is ever saved, i.e., this loop
    // must be completely nondeterministic.
    warning("No pre-variables found; this "
            "loop is completely non-deterministic.");
    body_expr=false_exprt();
  }

  // The last SSA-occurrence of a variable is the
  // output variable and it gets its non-SSA name.
  replace_idt last_map;
  for(std::map<irep_idt, unsigned>::const_iterator it=ssa_counters.begin();
      it!=ssa_counters.end();
      it++)
  {
    const irep_idt &id=it->first;
    unsigned last=it->second;

    irep_idt last_name=id2string(id)+"!"+i2string(last);
    last_map.insert(last_name, id);
  }

  last_map.replace(body_expr);

  replace_nondet_sideeffects(body_expr);

  return result_body;
}
Beispiel #11
0
void local_SSAt::assign_rec(
  const exprt &lhs,
  const exprt &rhs,
  const exprt &guard,
  locationt loc)
{
  const typet &type=ns.follow(lhs.type());

  if(is_symbol_struct_member(lhs, ns))
  {
    if(type.id()==ID_struct)
    {
      // need to split up

      const struct_typet &struct_type=to_struct_type(type);
      const struct_typet::componentst &components=struct_type.components();
      
      for(struct_typet::componentst::const_iterator
          it=components.begin();
          it!=components.end();
          it++)
      {
        member_exprt new_lhs(lhs, it->get_name(), it->type());
        member_exprt new_rhs(rhs, it->get_name(), it->type());
        assign_rec(new_lhs, new_rhs, guard, loc);
      }

      return;
    }

    ssa_objectt lhs_object(lhs, ns);
    
    const std::set<ssa_objectt> &assigned=
      assignments.get(loc);

    if(assigned.find(lhs_object)!=assigned.end())
    {
      exprt ssa_rhs=read_rhs(rhs, loc);

      const symbol_exprt ssa_symbol=name(lhs_object, OUT, loc);
      
      equal_exprt equality(ssa_symbol, ssa_rhs);
      nodes[loc].equalities.push_back(equality);
    }
  }
  else if(lhs.id()==ID_index)
  {
    const index_exprt &index_expr=to_index_expr(lhs);
    exprt ssa_array=index_expr.array();
    exprt new_rhs=with_exprt(ssa_array, index_expr.index(), rhs);
    assign_rec(index_expr.array(), new_rhs, guard, loc);
  }
  else if(lhs.id()==ID_member)
  {
    // These are non-flattened struct or union members.
    const member_exprt &member_expr=to_member_expr(lhs);
    const exprt &compound=member_expr.struct_op();
    const typet &compound_type=ns.follow(compound.type());

    if(compound_type.id()==ID_union)
    {
      union_exprt new_rhs(member_expr.get_component_name(), rhs, compound.type());
      assign_rec(member_expr.struct_op(), new_rhs, guard, loc);
    }
    else if(compound_type.id()==ID_struct)
    {
      exprt member_name(ID_member_name);
      member_name.set(ID_component_name, member_expr.get_component_name());
      with_exprt new_rhs(compound, member_name, rhs);
      assign_rec(compound, new_rhs, guard, loc);
    }
  }
  else if(lhs.id()==ID_complex_real)
  {
    assert(lhs.operands().size()==1);
    const exprt &op=lhs.op0();
    const complex_typet &complex_type=to_complex_type(op.type());
    exprt imag_op=unary_exprt(ID_complex_imag, op, complex_type.subtype());
    complex_exprt new_rhs(rhs, imag_op, complex_type);
    assign_rec(op, new_rhs, guard, loc);
  }
  else if(lhs.id()==ID_complex_imag)
  {
    assert(lhs.operands().size()==1);
    const exprt &op=lhs.op0();
    const complex_typet &complex_type=to_complex_type(op.type());
    exprt real_op=unary_exprt(ID_complex_real, op, complex_type.subtype());
    complex_exprt new_rhs(real_op, rhs, complex_type);
    assign_rec(op, new_rhs, guard, loc);
  }
  else if(lhs.id()==ID_if)
  {
    const if_exprt &if_expr=to_if_expr(lhs);
    assign_rec(if_expr.true_case(), rhs, and_exprt(guard, if_expr.cond()), loc);
    assign_rec(if_expr.false_case(), rhs, and_exprt(guard, not_exprt(if_expr.cond())), loc);
  }
  else if(lhs.id()==ID_byte_extract_little_endian ||
          lhs.id()==ID_byte_extract_big_endian)
  {
    const byte_extract_exprt &byte_extract_expr=to_byte_extract_expr(lhs);

    exprt new_lhs=byte_extract_expr.op();

    exprt new_rhs=byte_extract_exprt(
      byte_extract_expr.id(), rhs, byte_extract_expr.offset(), new_lhs.type());

    assign_rec(new_lhs, new_rhs, guard, loc);
  }
  else
    throw "UNKNOWN LHS: "+lhs.id_string();
}
Beispiel #12
0
void local_SSAt::build_guard(locationt loc)
{
  const guard_mapt::entryt &entry=guard_map[loc];
  
  // anything to be built?
  if(!entry.has_guard) return;
  
  exprt::operandst sources;

  // the very first 'loc' trivially gets 'true' as source
  if(loc==goto_function.body.instructions.begin())
    sources.push_back(true_exprt());
    
  for(guard_mapt::incomingt::const_iterator
      i_it=entry.incoming.begin();
      i_it!=entry.incoming.end();
      i_it++)
  {
    const guard_mapt::edget &edge=*i_it;
    
    exprt source;
    
    // might be backwards branch taken edge
    if(edge.is_branch_taken() &&
       edge.from->is_backwards_goto())
    {
      // The loop selector indicates whether the path comes from
      // above (entering the loop) or below (iterating).
      // By convention, we use the loop select symbol for the location
      // of the backwards goto.
      symbol_exprt loop_select=
        name(guard_symbol(), LOOP_SELECT, edge.from);

      #if 0
      source=false_exprt();
      #else
      // need constraing for edge.cond
      source=loop_select;
      #endif
    }
    else
    {
      // the other cases are basically similar
      
      symbol_exprt gs=name(guard_symbol(), OUT, edge.guard_source);
      exprt cond;
      
      if(edge.is_branch_taken() ||
         edge.is_assume() ||
         edge.is_function_call())
        cond=cond_symbol(edge.from);
      else if(edge.is_branch_not_taken())
        cond=boolean_negate(cond_symbol(edge.from));
      else if(edge.is_successor())
        cond=true_exprt();
      else
        assert(false);

      source=and_exprt(gs, cond);
    }
    
    sources.push_back(source);
  }

  // the below produces 'false' if there is no source
  exprt rhs=disjunction(sources);
  
  equal_exprt equality(guard_symbol(loc), rhs);
  nodes[loc].equalities.push_back(equality);
}
Beispiel #13
0
void local_SSAt::build_phi_nodes(locationt loc)
{
  const ssa_domaint::phi_nodest &phi_nodes=ssa_analysis[loc].phi_nodes;
  nodet &node=nodes[loc];

  for(objectst::const_iterator
      o_it=ssa_objects.objects.begin();
      o_it!=ssa_objects.objects.end(); o_it++)
  {
    // phi-node for this object here?
    ssa_domaint::phi_nodest::const_iterator p_it=
      phi_nodes.find(o_it->get_identifier());
          
    if(p_it==phi_nodes.end()) continue; // none
    
    // Yes. Get the source -> def map.
    const std::map<locationt, ssa_domaint::deft> &incoming=p_it->second;

    exprt rhs=nil_exprt();

    // We distinguish forwards- from backwards-edges,
    // and do forwards-edges first, which gives them
    // _lower_ priority in the ITE. Inputs are always
    // forward edges.
    
    for(std::map<locationt, ssa_domaint::deft>::const_iterator
        incoming_it=incoming.begin();
        incoming_it!=incoming.end();
        incoming_it++)
      if(incoming_it->second.is_input() ||
         incoming_it->first->location_number < loc->location_number)
      {
        // it's a forward edge
        exprt incoming_value=name(*o_it, incoming_it->second);
        exprt incoming_guard=edge_guard(incoming_it->first, loc);

        if(rhs.is_nil()) // first
          rhs=incoming_value;
        else
          rhs=if_exprt(incoming_guard, incoming_value, rhs);
      }
     
    // now do backwards

    for(std::map<locationt, ssa_domaint::deft>::const_iterator
        incoming_it=incoming.begin();
        incoming_it!=incoming.end();
        incoming_it++)
      if(!incoming_it->second.is_input() &&
         incoming_it->first->location_number >= loc->location_number)
      {
        // it's a backwards edge
        exprt incoming_value=name(*o_it, LOOP_BACK, incoming_it->first);
        exprt incoming_select=name(guard_symbol(), LOOP_SELECT, incoming_it->first);

        if(rhs.is_nil()) // first
          rhs=incoming_value;
        else
          rhs=if_exprt(incoming_select, incoming_value, rhs);
      }

    symbol_exprt lhs=name(*o_it, PHI, loc);
    
    equal_exprt equality(lhs, rhs);
    node.equalities.push_back(equality);
  }
}
Beispiel #14
0
value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
  const exprt &what,
  const modet mode,
  const exprt &pointer_expr,
  const guardt &guard)
{
  const typet &dereference_type=
    ns.follow(pointer_expr.type()).subtype();

  if(what.id()==ID_unknown ||
     what.id()==ID_invalid)
  {
    invalid_pointer(pointer_expr, guard);
    return valuet();
  }

  if(what.id()!=ID_object_descriptor)
    throw "unknown points-to: "+what.id_string();

  const object_descriptor_exprt &o=to_object_descriptor_expr(what);

  const exprt &root_object=o.root_object();
  const exprt &object=o.object();

  #if 0
  std::cout << "O: " << from_expr(ns, "", root_object) << '\n';
  #endif

  valuet result;

  if(root_object.id()=="NULL-object")
  {
    if(options.get_bool_option("pointer-check"))
    {
      guardt tmp_guard(guard);

      if(o.offset().is_zero())
      {
        tmp_guard.add(null_pointer(pointer_expr));

        dereference_callback.dereference_failure(
          "pointer dereference",
          "NULL pointer", tmp_guard);
      }
      else
      {
        tmp_guard.add(null_object(pointer_expr));

        dereference_callback.dereference_failure(
          "pointer dereference",
          "NULL plus offset pointer", tmp_guard);
      }
    }
  }
  else if(root_object.id()==ID_dynamic_object)
  {
    // const dynamic_object_exprt &dynamic_object=
    //  to_dynamic_object_expr(root_object);

    // the object produced by malloc
    exprt malloc_object=
      ns.lookup(CPROVER_PREFIX "malloc_object").symbol_expr();

    exprt is_malloc_object=same_object(pointer_expr, malloc_object);

    // constraint that it actually is a dynamic object
    exprt dynamic_object_expr(ID_dynamic_object, bool_typet());
    dynamic_object_expr.copy_to_operands(pointer_expr);

    // this is also our guard
    result.pointer_guard=dynamic_object_expr;

    // can't remove here, turn into *p
    result.value=dereference_exprt(pointer_expr, dereference_type);

    if(options.get_bool_option("pointer-check"))
    {
      // if(!dynamic_object.valid().is_true())
      {
        // check if it is still alive
        guardt tmp_guard(guard);
        tmp_guard.add(deallocated(pointer_expr, ns));
        dereference_callback.dereference_failure(
          "pointer dereference",
          "dynamic object deallocated",
          tmp_guard);
      }

      if(options.get_bool_option("bounds-check"))
      {
        if(!o.offset().is_zero())
        {
          // check lower bound
          guardt tmp_guard(guard);
          tmp_guard.add(is_malloc_object);
          tmp_guard.add(
            dynamic_object_lower_bound(
              pointer_expr,
              ns,
              nil_exprt()));
          dereference_callback.dereference_failure(
            "pointer dereference",
            "dynamic object lower bound", tmp_guard);
        }

        {
          // check upper bound

          // we check SAME_OBJECT(__CPROVER_malloc_object, p) &&
          //          POINTER_OFFSET(p)+size>__CPROVER_malloc_size

          guardt tmp_guard(guard);
          tmp_guard.add(is_malloc_object);
          tmp_guard.add(
            dynamic_object_upper_bound(
              pointer_expr,
              dereference_type,
              ns,
              size_of_expr(dereference_type, ns)));
          dereference_callback.dereference_failure(
            "pointer dereference",
            "dynamic object upper bound", tmp_guard);
        }
      }
    }
  }
  else if(root_object.id()==ID_integer_address)
  {
    // This is stuff like *((char *)5).
    // This is turned into an access to __CPROVER_memory[...].

    if(language_mode==ID_java)
    {
      result.value=nil_exprt();
      return result;
    }

    const symbolt &memory_symbol=ns.lookup(CPROVER_PREFIX "memory");
    exprt symbol_expr=symbol_exprt(memory_symbol.name, memory_symbol.type);

    if(base_type_eq(
         ns.follow(memory_symbol.type).subtype(),
         dereference_type, ns))
    {
      // Types match already, what a coincidence!
      // We can use an index expression.

      exprt index_expr=index_exprt(symbol_expr, pointer_offset(pointer_expr));
      index_expr.type()=ns.follow(memory_symbol.type).subtype();
      result.value=index_expr;
    }
    else if(dereference_type_compare(
              ns.follow(memory_symbol.type).subtype(),
              dereference_type))
    {
      exprt index_expr=index_exprt(symbol_expr, pointer_offset(pointer_expr));
      index_expr.type()=ns.follow(memory_symbol.type).subtype();
      result.value=typecast_exprt(index_expr, dereference_type);
    }
    else
    {
      // We need to use byte_extract.
      // Won't do this without a commitment to an endianness.

      if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::NO_ENDIANNESS)
      {
      }
      else
      {
        exprt byte_extract(byte_extract_id(), dereference_type);
        byte_extract.copy_to_operands(
          symbol_expr, pointer_offset(pointer_expr));
        result.value=byte_extract;
      }
    }
  }
  else
  {
    // something generic -- really has to be a symbol
    address_of_exprt object_pointer(object);

    if(o.offset().is_zero())
    {
      equal_exprt equality(pointer_expr, object_pointer);

      if(ns.follow(equality.lhs().type())!=ns.follow(equality.rhs().type()))
        equality.lhs().make_typecast(equality.rhs().type());

      result.pointer_guard=equality;
    }
    else
    {
      result.pointer_guard=same_object(pointer_expr, object_pointer);
    }

    guardt tmp_guard(guard);
    tmp_guard.add(result.pointer_guard);

    valid_check(object, tmp_guard, mode);

    const typet &object_type=ns.follow(object.type());
    const exprt &root_object=o.root_object();
    const typet &root_object_type=ns.follow(root_object.type());

    exprt root_object_subexpression=root_object;

    if(dereference_type_compare(object_type, dereference_type) &&
       o.offset().is_zero())
    {
      // The simplest case: types match, and offset is zero!
      // This is great, we are almost done.

      result.value=object;

      if(object_type!=ns.follow(dereference_type))
        result.value.make_typecast(dereference_type);
    }
    else if(root_object_type.id()==ID_array &&
            dereference_type_compare(
              root_object_type.subtype(),
              dereference_type))
    {
      // We have an array with a subtype that matches
      // the dereferencing type.
      // We will require well-alignedness!

      exprt offset;

      // this should work as the object is essentially the root object
      if(o.offset().is_constant())
        offset=o.offset();
      else
        offset=pointer_offset(pointer_expr);

      exprt adjusted_offset;

      // are we doing a byte?
      mp_integer element_size=
        dereference_type.id()==ID_empty?
        pointer_offset_size(char_type(), ns):
        pointer_offset_size(dereference_type, ns);

      if(element_size==1)
      {
        // no need to adjust offset
        adjusted_offset=offset;
      }
      else if(element_size<=0)
      {
        throw "unknown or invalid type size of:\n"+dereference_type.pretty();
      }
      else
      {
        exprt element_size_expr=
          from_integer(element_size, offset.type());

        adjusted_offset=binary_exprt(
          offset, ID_div, element_size_expr, offset.type());

        // TODO: need to assert well-alignedness
      }

      index_exprt index_expr=
        index_exprt(root_object, adjusted_offset, root_object_type.subtype());

      bounds_check(index_expr, tmp_guard);

      result.value=index_expr;

      if(ns.follow(result.value.type())!=ns.follow(dereference_type))
        result.value.make_typecast(dereference_type);
    }
    else if(get_subexpression_at_offset(
        root_object_subexpression,
        o.offset(),
        dereference_type,
        ns))
    {
      // Successfully found a member, array index, or combination thereof
      // that matches the desired type and offset:
      result.value=root_object_subexpression;
    }
    else
    {
      // we extract something from the root object
      result.value=o.root_object();

      // this is relative to the root object
      const exprt offset=pointer_offset(pointer_expr);

      if(memory_model(result.value, dereference_type, tmp_guard, offset))
      {
        // ok, done
      }
      else
      {
        if(options.get_bool_option("pointer-check"))
        {
          std::string msg="memory model not applicable (got `";
          msg+=from_type(ns, "", result.value.type());
          msg+="', expected `";
          msg+=from_type(ns, "", dereference_type);
          msg+="')";

          dereference_callback.dereference_failure(
            "pointer dereference",
            msg, tmp_guard);
        }

        return valuet(); // give up, no way that this is ok
      }
    }
  }

  return result;
}
Beispiel #15
0
GLboolean _slang_assemble_operation (slang_assemble_ctx *A, slang_operation *op, slang_ref_type ref)
{
	/* set default results */
	A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ref;
	A->swz.num_components = 0;

	switch (op->type)
	{
	case slang_oper_block_no_new_scope:
	case slang_oper_block_new_scope:
		{
			GLuint i;

			for (i = 0; i < op->num_children; i++)
			{
				if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid/*slang_ref_freelance*/))
					return GL_FALSE;
				if (!_slang_cleanup_stack (A, &op->children[i]))
					return GL_FALSE;
			}
		}
		break;
	case slang_oper_variable_decl:
		{
			GLuint i;
			slang_operation assign;
			GLboolean result;

			/* Construct assignment expression placeholder. */
			if (!slang_operation_construct (&assign))
				return GL_FALSE;
			assign.type = slang_oper_assign;
			assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
			if (assign.children == NULL)
			{
				slang_operation_destruct (&assign);
				return GL_FALSE;
			}
			for (assign.num_children = 0; assign.num_children < 2; assign.num_children++)
				if (!slang_operation_construct (&assign.children[assign.num_children]))
				{
					slang_operation_destruct (&assign);
					return GL_FALSE;
				}

			result = GL_TRUE;
			for (i = 0; i < op->num_children; i++)
			{
				slang_variable *var;

				var = _slang_locate_variable (op->children[i].locals, op->children[i].a_id, GL_TRUE);
				if (var == NULL)
				{
					result = GL_FALSE;
					break;
				}
				if (var->initializer == NULL)
					continue;

				if (!slang_operation_copy (&assign.children[0], &op->children[i]) ||
					!slang_operation_copy (&assign.children[1], var->initializer) ||
					!_slang_assemble_assign (A, &assign, "=", slang_ref_forbid) ||
					!_slang_cleanup_stack (A, &assign))
				{
					result = GL_FALSE;
					break;
				}
			}
			slang_operation_destruct (&assign);
			if (!result)
				return GL_FALSE;
		}
		break;
	case slang_oper_asm:
		{
			GLuint i;

			if (!_slang_assemble_operation (A, &op->children[0], slang_ref_force))
				return GL_FALSE;
			for (i = 1; i < op->num_children; i++)
				if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid))
					return GL_FALSE;
			if (!call_asm_instruction (A, op->a_id))
				return GL_FALSE;
		}
		break;
	case slang_oper_break:
		if (!PLAB (A->file, slang_asm_jump, A->flow.loop_end))
			return GL_FALSE;
		break;
	case slang_oper_continue:
		if (!PLAB (A->file, slang_asm_jump, A->flow.loop_start))
			return GL_FALSE;
		break;
	case slang_oper_discard:
		if (!PUSH (A->file, slang_asm_discard))
			return GL_FALSE;
		if (!PUSH (A->file, slang_asm_exit))
			return GL_FALSE;
		break;
	case slang_oper_return:
		if (A->local.ret_size != 0)
		{
			/* push the result's address */
			if (!PLAB2 (A->file, slang_asm_local_addr, 0, A->local.ret_size))
				return GL_FALSE;
			if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
				return GL_FALSE;

			A->swz.num_components = 0;
			/* assign the operation to the function result (it was reserved on the stack) */
			if (!_slang_assemble_assignment (A, op->children))
				return GL_FALSE;

			if (!PLAB (A->file, slang_asm_local_free, 4))
				return GL_FALSE;
		}
		if (!PLAB (A->file, slang_asm_jump, A->flow.function_end))
			return GL_FALSE;
		break;
	case slang_oper_expression:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[0], ref))
			return GL_FALSE;
		break;
	case slang_oper_if:
		if (!_slang_assemble_if (A, op))
			return GL_FALSE;
		break;
	case slang_oper_while:
		if (!_slang_assemble_while (A, op))
			return GL_FALSE;
		break;
	case slang_oper_do:
		if (!_slang_assemble_do (A, op))
			return GL_FALSE;
		break;
	case slang_oper_for:
		if (!_slang_assemble_for (A, op))
			return GL_FALSE;
		break;
	case slang_oper_void:
		break;
	case slang_oper_literal_bool:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!PLIT (A->file, slang_asm_bool_push, op->literal))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_literal_int:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!PLIT (A->file, slang_asm_int_push, op->literal))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_literal_float:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!PLIT (A->file, slang_asm_float_push, op->literal))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_identifier:
		{
			slang_variable *var;
			GLuint size;

			/* find the variable and calculate its size */
			var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE);
			if (var == NULL)
				return GL_FALSE;
			size = 0;
			if (!sizeof_variable (A, &var->type.specifier, slang_qual_none, var->array_len, &size))
				return GL_FALSE;

			/* prepare stack for dereferencing */
			if (ref == slang_ref_forbid)
				if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
					return GL_FALSE;

			/* push the variable's address */
			if (var->global)
			{
				if (!PLAB (A->file, slang_asm_global_addr, var->address))
					return GL_FALSE;
			}
			else
			{
				if (!PLAB2 (A->file, slang_asm_local_addr, var->address, size))
					return GL_FALSE;
			}

			/* perform the dereference */
			if (ref == slang_ref_forbid)
			{
				if (!PUSH (A->file, slang_asm_addr_copy))
					return GL_FALSE;
				if (!PLAB (A->file, slang_asm_local_free, 4))
					return GL_FALSE;
				if (!_slang_dereference (A, op))
					return GL_FALSE;
			}
		}
		break;
	case slang_oper_sequence:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/))
			return GL_FALSE;
		if (!_slang_cleanup_stack (A, &op->children[0]))
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_assign:
		if (!_slang_assemble_assign (A, op, "=", ref))
			return GL_FALSE;
		break;
	case slang_oper_addassign:
		if (!_slang_assemble_assign (A, op, "+=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_subassign:
		if (!_slang_assemble_assign (A, op, "-=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_mulassign:
		if (!_slang_assemble_assign (A, op, "*=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	/*case slang_oper_modassign:*/
	/*case slang_oper_lshassign:*/
	/*case slang_oper_rshassign:*/
	/*case slang_oper_orassign:*/
	/*case slang_oper_xorassign:*/
	/*case slang_oper_andassign:*/
	case slang_oper_divassign:
		if (!_slang_assemble_assign (A, op, "/=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_select:
		if (!_slang_assemble_select (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_logicalor:
		if (!_slang_assemble_logicalor (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_logicaland:
		if (!_slang_assemble_logicaland (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_logicalxor:
		if (!_slang_assemble_function_call_name (A, "^^", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_bitor:*/
	/*case slang_oper_bitxor:*/
	/*case slang_oper_bitand:*/
	case slang_oper_less:
		if (!_slang_assemble_function_call_name (A, "<", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_greater:
		if (!_slang_assemble_function_call_name (A, ">", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_lessequal:
		if (!_slang_assemble_function_call_name (A, "<=", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_greaterequal:
		if (!_slang_assemble_function_call_name (A, ">=", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_lshift:*/
	/*case slang_oper_rshift:*/
	case slang_oper_add:
		if (!_slang_assemble_function_call_name (A, "+", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_subtract:
		if (!_slang_assemble_function_call_name (A, "-", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_multiply:
		if (!_slang_assemble_function_call_name (A, "*", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_modulus:*/
	case slang_oper_divide:
		if (!_slang_assemble_function_call_name (A, "/", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_equal:
		if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
			return GL_FALSE;
		if (!equality (A, op->children, GL_TRUE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_notequal:
		if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
			return GL_FALSE;
		if (!equality (A, op->children, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_preincrement:
		if (!_slang_assemble_assign (A, op, "++", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_predecrement:
		if (!_slang_assemble_assign (A, op, "--", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_plus:
		if (!_slang_dereference (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_minus:
		if (!_slang_assemble_function_call_name (A, "-", op->children, 1, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_complement:*/
	case slang_oper_not:
		if (!_slang_assemble_function_call_name (A, "!", op->children, 1, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_subscript:
		{
			slang_assembly_typeinfo ti_arr, ti_elem;

			if (!slang_assembly_typeinfo_construct (&ti_arr))
				return GL_FALSE;
			if (!slang_assembly_typeinfo_construct (&ti_elem))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				return GL_FALSE;
			}
			if (!handle_subscript (A, &ti_elem, &ti_arr, op, ref))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				slang_assembly_typeinfo_destruct (&ti_elem);
				return GL_FALSE;
			}
			slang_assembly_typeinfo_destruct (&ti_arr);
			slang_assembly_typeinfo_destruct (&ti_elem);
		}
		break;
	case slang_oper_call:
		{
			slang_function *fun;

			fun = _slang_locate_function (A->space.funcs, op->a_id, op->children, op->num_children,
				&A->space, A->atoms);
			if (fun == NULL)
			{
				if (!_slang_assemble_constructor (A, op))
					return GL_FALSE;
			}
			else
			{
				if (!_slang_assemble_function_call (A, fun, op->children, op->num_children, GL_FALSE))
					return GL_FALSE;
			}
			A->ref = slang_ref_forbid;
		}
		break;
	case slang_oper_field:
		{
			slang_assembly_typeinfo ti_after, ti_before;

			if (!slang_assembly_typeinfo_construct (&ti_after))
				return GL_FALSE;
			if (!slang_assembly_typeinfo_construct (&ti_before))
			{
				slang_assembly_typeinfo_destruct (&ti_after);
				return GL_FALSE;
			}
			if (!handle_field (A, &ti_after, &ti_before, op, ref))
			{
				slang_assembly_typeinfo_destruct (&ti_after);
				slang_assembly_typeinfo_destruct (&ti_before);
				return GL_FALSE;
			}
			slang_assembly_typeinfo_destruct (&ti_after);
			slang_assembly_typeinfo_destruct (&ti_before);
		}
		break;
	case slang_oper_postincrement:
		if (!assemble_function_call_name_dummyint (A, "++", op->children))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_postdecrement:
		if (!assemble_function_call_name_dummyint (A, "--", op->children))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	default:
		return GL_FALSE;
	}

	return GL_TRUE;
}