void constant_propagator_domaint::assign_rec(
  valuest &values,
  const exprt &lhs, const exprt &rhs,
  const namespacet &ns)
{
  const typet & lhs_type = ns.follow(lhs.type());
  const typet & rhs_type = ns.follow(rhs.type());

#ifdef DEBUG
  std::cout << "assign: " << from_expr(ns, "", lhs)
            << " := " << from_type(ns, "", rhs_type) << '\n';
#endif

  if(lhs.id()==ID_symbol && rhs.id()==ID_if)
  {
	exprt cond=rhs.op0();
	assert(cond.operands().size()==2);
	if(values.is_constant(cond.op0())
			&& values.is_constant(cond.op1()))
	{
      if(cond.op0().id()==ID_index)
      {
    	exprt index=cond.op0();
        exprt new_expr=concatenate_array_id(index.op0(), index.op1(), index.type());
        values.replace_const(new_expr);
        cond.op0()=new_expr;
        cond = simplify_expr(cond,ns);
      }
      else
        assert(0);

      assign(values, to_symbol_expr(lhs), cond, ns);
	}
  }
  else if(lhs.id()==ID_symbol && rhs_type.id()!=ID_array
                         && rhs_type.id()!=ID_struct
                         && rhs_type.id()!=ID_union)
  {
    if(values.is_constant(rhs))
      assign(values, to_symbol_expr(lhs), rhs, ns);
    else
      values.set_to_top(to_symbol_expr(lhs));
  }
  else if(lhs.id()==ID_symbol && lhs_type.id()==ID_array
		                       && rhs_type.id()==ID_array)
  {
	exprt new_expr;
	mp_integer idx=0;
    forall_operands(it, rhs)
	{
  	  new_expr=concatenate_array_id(lhs, idx, it->type());
  	  assign(values, to_symbol_expr(new_expr), *it, ns);
  	  idx = idx +1;
	}
Beispiel #2
0
std::string from_type(const typet &type)
{
  symbol_tablet symbol_table;
  return from_type(namespacet(symbol_table), "", type);
}
Beispiel #3
0
void convert(
  const namespacet &ns,
  const goto_tracet &goto_trace,
  jsont &dest)
{
  json_arrayt &dest_array=dest.make_array();

  source_locationt previous_source_location;

  for(const auto &step : goto_trace.steps)
  {
    const source_locationt &source_location=step.pc->source_location;

    jsont json_location;

    if(source_location.is_not_nil() && source_location.get_file()!="")
      json_location=json(source_location);
    else
      json_location=json_nullt();

    switch(step.type)
    {
    case goto_trace_stept::typet::ASSERT:
      if(!step.cond_value)
      {
        irep_idt property_id;

        if(step.pc->is_assert())
          property_id=source_location.get_property_id();
        else if(step.pc->is_goto()) // unwinding, we suspect
        {
          property_id=
            id2string(step.pc->source_location.get_function())+
            ".unwind."+std::to_string(step.pc->loop_number);
        }

        json_objectt &json_failure=dest_array.push_back().make_object();

        json_failure["stepType"]=json_stringt("failure");
        json_failure["hidden"]=jsont::json_boolean(step.hidden);
        json_failure["thread"]=json_numbert(std::to_string(step.thread_nr));
        json_failure["reason"]=json_stringt(id2string(step.comment));
        json_failure["property"]=json_stringt(id2string(property_id));

        if(!json_location.is_null())
          json_failure["sourceLocation"]=json_location;
      }
      break;

    case goto_trace_stept::typet::ASSIGNMENT:
    case goto_trace_stept::typet::DECL:
      {
        irep_idt identifier=step.lhs_object.get_identifier();
        json_objectt &json_assignment=dest_array.push_back().make_object();

        json_assignment["stepType"]=json_stringt("assignment");

        if(!json_location.is_null())
          json_assignment["sourceLocation"]=json_location;

        std::string value_string, binary_string, type_string, full_lhs_string;
        json_objectt full_lhs_value;

        if(step.full_lhs.is_not_nil())
          full_lhs_string=from_expr(ns, identifier, step.full_lhs);

#if 0
        if(it.full_lhs_value.is_not_nil())
          full_lhs_value_string=from_expr(ns, identifier, it.full_lhs_value);
#endif

        if(step.full_lhs_value.is_not_nil())
          full_lhs_value = json(step.full_lhs_value, ns);

        const symbolt *symbol;
        irep_idt base_name, display_name;

        if(!ns.lookup(identifier, symbol))
        {
          base_name=symbol->base_name;
          display_name=symbol->display_name();
          if(type_string=="")
            type_string=from_type(ns, identifier, symbol->type);

          json_assignment["mode"]=json_stringt(id2string(symbol->mode));
        }

        json_assignment["value"]=full_lhs_value;
        json_assignment["lhs"]=json_stringt(full_lhs_string);
        json_assignment["hidden"]=jsont::json_boolean(step.hidden);
        json_assignment["thread"]=json_numbert(std::to_string(step.thread_nr));

        json_assignment["assignmentType"]=
          json_stringt(
            step.assignment_type==
              goto_trace_stept::assignment_typet::ACTUAL_PARAMETER?
            "actual-parameter":
            "variable");
      }
      break;

    case goto_trace_stept::typet::OUTPUT:
      {
        json_objectt &json_output=dest_array.push_back().make_object();

        json_output["stepType"]=json_stringt("output");
        json_output["hidden"]=jsont::json_boolean(step.hidden);
        json_output["thread"]=json_numbert(std::to_string(step.thread_nr));
        json_output["outputID"]=json_stringt(id2string(step.io_id));

        json_arrayt &json_values=json_output["values"].make_array();

        for(const auto &arg : step.io_args)
        {
          if(arg.is_nil())
            json_values.push_back(json_stringt(""));
          else
            json_values.push_back(json(arg, ns));
        }

        if(!json_location.is_null())
          json_output["sourceLocation"]=json_location;
      }
      break;

    case goto_trace_stept::typet::INPUT:
      {
        json_objectt &json_input=dest_array.push_back().make_object();

        json_input["stepType"]=json_stringt("input");
        json_input["hidden"]=jsont::json_boolean(step.hidden);
        json_input["thread"]=json_numbert(std::to_string(step.thread_nr));
        json_input["inputID"]=json_stringt(id2string(step.io_id));

        json_arrayt &json_values=json_input["values"].make_array();

        for(const auto &arg : step.io_args)
        {
          if(arg.is_nil())
            json_values.push_back(json_stringt(""));
          else
            json_values.push_back(json(arg, ns));
        }

        if(!json_location.is_null())
          json_input["sourceLocation"]=json_location;
      }
      break;

    case goto_trace_stept::typet::FUNCTION_CALL:
    case goto_trace_stept::typet::FUNCTION_RETURN:
      {
        std::string tag=
          (step.type==goto_trace_stept::typet::FUNCTION_CALL)?
            "function-call":"function-return";
        json_objectt &json_call_return=dest_array.push_back().make_object();

        json_call_return["stepType"]=json_stringt(tag);
        json_call_return["hidden"]=jsont::json_boolean(step.hidden);
        json_call_return["thread"]=json_numbert(std::to_string(step.thread_nr));

        const symbolt &symbol=ns.lookup(step.identifier);
        json_objectt &json_function=json_call_return["function"].make_object();
        json_function["displayName"]=
          json_stringt(id2string(symbol.display_name()));
        json_function["identifier"]=json_stringt(id2string(step.identifier));
        json_function["sourceLocation"]=json(symbol.location);

        if(!json_location.is_null())
          json_call_return["sourceLocation"]=json_location;
      }
      break;

    default:
      if(source_location!=previous_source_location)
      {
        // just the source location
        if(!json_location.is_null())
        {
          json_objectt &json_location_only=dest_array.push_back().make_object();
          json_location_only["stepType"]=json_stringt("location-only");
          json_location_only["hidden"]=jsont::json_boolean(step.hidden);
          json_location_only["thread"]=
            json_numbert(std::to_string(step.thread_nr));
          json_location_only["sourceLocation"]=json_location;
        }
      }
    }

    if(source_location.is_not_nil() && source_location.get_file()!="")
      previous_source_location=source_location;
  }
}
Beispiel #4
0
/******************************************************************************
 * TranslateColors              [MSCMS.@]
 *
 * Perform color translation.
 *
 * PARAMS
 *  transform    [I] Handle to a color transform.
 *  input        [I] Array of input colors.
 *  number       [I] Number of colors to translate.
 *  input_type   [I] Input color format.
 *  output       [O] Array of output colors.
 *  output_type  [I] Output color format.
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 */
BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count,
                             COLORTYPE input_type, PCOLOR out, COLORTYPE output_type )
{
#ifdef HAVE_LCMS2
    BOOL ret = TRUE;
    struct transform *transform = grab_transform( handle );
    cmsHTRANSFORM xfrm;
    unsigned int i;

    TRACE( "( %p, %p, %d, %d, %p, %d )\n", handle, in, count, input_type, out, output_type );

    if (!transform) return FALSE;

    xfrm = transform->cmstransform;
    if (!cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) ))
        return FALSE;

    switch (input_type)
    {
    case COLOR_RGB:
    {
        switch (output_type)
        {
        case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].rgb, 1 ); goto done;
        case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].Lab, 1 ); goto done;
        case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].gray, 1 ); goto done;
        case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].cmyk, 1 ); goto done;
        case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].XYZ, 1 ); goto done;
        default:
            FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
            ret = FALSE;
            break;
        }
        break;
    }
    case COLOR_Lab:
    {
        switch (output_type)
        {
        case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].rgb, 1 ); goto done;
        case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].Lab, 1 ); goto done;
        case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].gray, 1 ); goto done;
        case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].cmyk, 1 ); goto done;
        case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].XYZ, 1 ); goto done;
        default:
            FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
            ret = FALSE;
            break;
        }
        break;
    }
    case COLOR_GRAY:
    {
        switch (output_type)
        {
        case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].rgb, 1 ); goto done;
        case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].Lab, 1 ); goto done;
        case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].gray, 1 ); goto done;
        case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].cmyk, 1 ); goto done;
        case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].XYZ, 1 ); goto done;
        default:
            FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
            ret = FALSE;
            break;
        }
        break;
    }
    case COLOR_CMYK:
    {
        switch (output_type)
        {
        case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].rgb, 1 ); goto done;
        case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].Lab, 1 ); goto done;
        case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].gray, 1 ); goto done;
        case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].cmyk, 1 ); goto done;
        case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].XYZ, 1 ); goto done;
        default:
            FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
            ret = FALSE;
            break;
        }
        break;
    }
    case COLOR_XYZ:
    {
        switch (output_type)
        {
        case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].rgb, 1 ); goto done;
        case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].Lab, 1 ); goto done;
        case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].gray, 1 ); goto done;
        case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].cmyk, 1 ); goto done;
        case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].XYZ, 1 ); goto done;
        default:
            FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
            ret = FALSE;
            break;
        }
        break;
    }
    default:
        FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
        ret = FALSE;
        break;
    }

done:
    release_transform( transform );
    return ret;

#else  /* HAVE_LCMS2 */
    return FALSE;
#endif /* HAVE_LCMS2 */
}
Beispiel #5
0
void value_sett::output(
  const namespacet &ns,
  std::ostream &out) const
{
  for(valuest::const_iterator
      v_it=values.begin();
      v_it!=values.end();
      v_it++)
  {
    irep_idt identifier, display_name;

    const entryt &e=v_it->second;

    if(has_prefix(id2string(e.identifier), "value_set::dynamic_object"))
    {
      display_name=id2string(e.identifier)+e.suffix;
      identifier="";
    }
    else if(e.identifier=="value_set::return_value")
    {
      display_name="RETURN_VALUE"+e.suffix;
      identifier="";
    }
    else
    {
      #if 0
      const symbolt &symbol=ns.lookup(e.identifier);
      display_name=symbol.display_name()+e.suffix;
      identifier=symbol.name;
      #else
      identifier=id2string(e.identifier);
      display_name=id2string(identifier)+e.suffix;
      #endif
    }

    out << display_name;

    out << " = { ";

    const object_map_dt &object_map=e.object_map.read();

    std::size_t width=0;

    for(object_map_dt::const_iterator
        o_it=object_map.begin();
        o_it!=object_map.end();
        o_it++)
    {
      const exprt &o=object_numbering[o_it->first];

      std::string result;

      if(o.id()==ID_invalid || o.id()==ID_unknown)
        result=from_expr(ns, identifier, o);
      else
      {
        result="<"+from_expr(ns, identifier, o)+", ";

        if(o_it->second.offset_is_set)
          result+=integer2string(o_it->second.offset)+"";
        else
          result+='*';

        if(o.type().is_nil())
          result+=", ?";
        else
          result+=", "+from_type(ns, identifier, o.type());

        result+='>';
      }

      out << result;

      width+=result.size();

      object_map_dt::const_iterator next(o_it);
      next++;

      if(next!=object_map.end())
      {
        out << ", ";
        if(width>=40) out << "\n      ";
      }
    }

    out << " } " << std::endl;
  }
}
Beispiel #6
0
void goto_inlinet::parameter_assignments(
  const locationt &location,
  const code_typet &code_type,
  const exprt::operandst &arguments,
  goto_programt &dest)
{
  // iterates over the operands
  exprt::operandst::const_iterator it1=arguments.begin();

  goto_programt::local_variablest local_variables;
  
  const code_typet::argumentst &argument_types=
    code_type.arguments();
  
  // iterates over the types of the arguments
  for(code_typet::argumentst::const_iterator
      it2=argument_types.begin();
      it2!=argument_types.end();
      it2++)
  {
    // if you run out of actual arguments there was a mismatch
    if(it1==arguments.end())
    {
      err_location(location);
      throw "function call: not enough arguments";
    }

    const exprt &argument=static_cast<const exprt &>(*it2);

    // this is the type the n-th argument should be
    const typet &arg_type=ns.follow(argument.type());

    const irep_idt &identifier=argument.cmt_identifier();

    if(identifier=="")
    {
      err_location(location);
      throw "no identifier for function argument";
    }

    {
      const symbolt &symbol=ns.lookup(identifier);

      goto_programt::targett decl=dest.add_instruction();
      decl->make_other();
      exprt tmp = code_declt(symbol_expr(symbol));
      migrate_expr(tmp, decl->code);
      decl->location=location;
      decl->function=location.get_function(); 
      decl->local_variables=local_variables;
    }

    local_variables.insert(identifier);
    
    // nil means "don't assign"
    if(it1->is_nil())
    {    
    }
    else
    {
      // this is the actual parameter
      exprt actual(*it1);

      // it should be the same exact type
      type2tc arg_type_2, actual_type_2;
      migrate_type(arg_type, arg_type_2);
      migrate_type(actual.type(), actual_type_2);
      if (!base_type_eq(arg_type_2, actual_type_2, ns))
      {
        const typet &f_argtype = ns.follow(arg_type);
        const typet &f_acttype = ns.follow(actual.type());
        
        // we are willing to do some conversion
        if((f_argtype.id()=="pointer" &&
            f_acttype.id()=="pointer") ||
           (f_argtype.is_array() &&
            f_acttype.id()=="pointer" &&
            f_argtype.subtype()==f_acttype.subtype()))
        {
          actual.make_typecast(arg_type);
        }
        else if((f_argtype.id()=="signedbv" ||
            f_argtype.id()=="unsignedbv" ||
            f_argtype.is_bool()) &&
           (f_acttype.id()=="signedbv" ||
            f_acttype.id()=="unsignedbv" ||
            f_acttype.is_bool()))  
        {
          actual.make_typecast(arg_type);
        }
        else
        {
          err_location(location);

          str << "function call: argument `" << identifier
              << "' type mismatch: got "
              << from_type(ns, identifier, it1->type())
              << ", expected "
              << from_type(ns, identifier, arg_type);
          throw 0;
        }
      }

      // adds an assignment of the actual parameter to the formal parameter
      code_assignt assignment(symbol_exprt(identifier, arg_type), actual);
      assignment.location()=location;

      dest.add_instruction(ASSIGN);
      dest.instructions.back().location=location;
      migrate_expr(assignment, dest.instructions.back().code);
      dest.instructions.back().local_variables=local_variables;
      dest.instructions.back().function=location.get_function();      
    }

    it1++;
  }

  if(it1!=arguments.end())
  {
    // too many arguments -- we just ignore that, no harm done
  }
}
Beispiel #7
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 #8
0
goto_program_coverage_recordt::goto_program_coverage_recordt(
  const namespacet &ns,
  goto_functionst::function_mapt::const_iterator gf_it,
  const symex_coveraget::coveraget &coverage):
  coverage_recordt("method")
{
  assert(gf_it->second.body_available());

  // identify the file name, inlined functions aren't properly
  // accounted for
  goto_programt::const_targett end_function=
    --gf_it->second.body.instructions.end();
  assert(end_function->is_end_function());
  file_name=end_function->source_location.get_file();
  assert(!file_name.empty());

  // compute the maximum coverage of individual source-code lines
  coverage_lines_mapt coverage_lines_map;
  compute_coverage_lines(
    gf_it->second.body,
    file_name,
    coverage,
    coverage_lines_map);

  // <method name="foo" signature="int(int)" line-rate="1.0" branch-rate="1.0">
  //   <lines>
  //     <line number="23" hits="1" branch="false"/>
  //     <line number="24" hits="1" branch="false"/>
  //     <line number="25" hits="1" branch="false"/>
  //     <line number="26" hits="1" branch="false"/>
  //     <line number="27" hits="1" branch="false"/>
  //     <line number="28" hits="1" branch="false"/>
  //     <line number="29" hits="1" branch="false"/>
  //     <line number="30" hits="1" branch="false"/>
  //   </lines>
  // </method>
  xml.set_attribute("name", id2string(gf_it->first));

  code_typet sig_type=
    original_return_type(ns.get_symbol_table(), gf_it->first);
  if(sig_type.is_nil())
    sig_type=gf_it->second.type;
  xml.set_attribute("signature",
                    from_type(ns, gf_it->first, sig_type));

  xml.set_attribute("line-rate",
                    rate_detailed(lines_covered, lines_total));
  xml.set_attribute("branch-rate",
                    rate(branches_covered, branches_total));

  xmlt &lines=xml.new_element("lines");

  for(const auto &cov_line : coverage_lines_map)
  {
    xmlt &line=lines.new_element("line");

    line.set_attribute("number", std::to_string(cov_line.first));
    line.set_attribute("hits", std::to_string(cov_line.second.hits));
    if(cov_line.second.conditions.empty())
      line.set_attribute("branch", "false");
    else
    {
      line.set_attribute("branch", "true");

      xmlt &conditions=line.new_element("conditions");

      std::size_t number=0, total_taken=0;
      for(const auto &c : cov_line.second.conditions)
      {
        // <condition number="0" type="jump" coverage="50%"/>
        xmlt &condition=conditions.new_element("condition");
        condition.set_attribute("number", std::to_string(number++));
        condition.set_attribute("type", "jump");
        unsigned taken=c.second.false_taken+c.second.true_taken;
        total_taken+=taken;
        condition.set_attribute("coverage", rate(taken, 2, true));
      }

      line.set_attribute(
        "condition-coverage",
        rate_detailed(total_taken, number*2, true));
    }
  }
}
Beispiel #9
0
void goto_inlinet::parameter_assignments(
  const source_locationt &source_location,
  const irep_idt &function_name,
  const code_typet &code_type,
  const exprt::operandst &arguments,
  goto_programt &dest)
{
  // iterates over the operands
  exprt::operandst::const_iterator it1=arguments.begin();

  const code_typet::parameterst &parameter_types=
    code_type.parameters();
  
  // iterates over the types of the parameters
  for(code_typet::parameterst::const_iterator
      it2=parameter_types.begin();
      it2!=parameter_types.end();
      it2++)
  {
    const code_typet::parametert &parameter=*it2;

    // this is the type the n-th argument should be
    const typet &par_type=ns.follow(parameter.type());

    const irep_idt &identifier=parameter.get_identifier();

    if(identifier==irep_idt())
    {
      error().source_location=source_location;
      error() << "no identifier for function parameter" << eom;
      throw 0;
    }

    {
      const symbolt &symbol=ns.lookup(identifier);

      goto_programt::targett decl=dest.add_instruction();
      decl->make_decl();
      decl->code=code_declt(symbol.symbol_expr());
      decl->code.add_source_location()=source_location;
      decl->source_location=source_location;
      decl->function=function_name; 
    }

    // this is the actual parameter
    exprt actual;

    // if you run out of actual arguments there was a mismatch
    if(it1==arguments.end())
    {
      warning().source_location=source_location;
      warning() << "call to `" << function_name << "': "
                << "not enough arguments, "
                << "inserting non-deterministic value" << eom;

      actual=side_effect_expr_nondett(par_type);
    }
    else
      actual=*it1;

    // nil means "don't assign"
    if(actual.is_nil())
    {    
    }
    else
    {
      // it should be the same exact type as the parameter,
      // subject to some exceptions
      if(!base_type_eq(par_type, actual.type(), ns))
      {
        const typet &f_partype = ns.follow(par_type);
        const typet &f_acttype = ns.follow(actual.type());
        
        // we are willing to do some conversion
        if((f_partype.id()==ID_pointer &&
            f_acttype.id()==ID_pointer) ||
           (f_partype.id()==ID_pointer &&
            f_acttype.id()==ID_array &&
            f_partype.subtype()==f_acttype.subtype()))
        {
          actual.make_typecast(par_type);
        }
        else if((f_partype.id()==ID_signedbv ||
                 f_partype.id()==ID_unsignedbv ||
                 f_partype.id()==ID_bool) &&
                (f_acttype.id()==ID_signedbv ||
                 f_acttype.id()==ID_unsignedbv ||
                 f_acttype.id()==ID_bool))  
        {
          actual.make_typecast(par_type);
        }
        else
        {
          error().source_location=actual.find_source_location();

          error() << "function call: argument `" << identifier
                  << "' type mismatch: argument is `"
                  // << from_type(ns, identifier, actual.type())
                  << actual.type().pretty()
                  << "', parameter is `"
                  << from_type(ns, identifier, par_type)
                  << "'" << eom;
          throw 0;
        }
      }

      // adds an assignment of the actual parameter to the formal parameter
      code_assignt assignment(symbol_exprt(identifier, par_type), actual);
      assignment.add_source_location()=source_location;

      dest.add_instruction(ASSIGN);
      dest.instructions.back().source_location=source_location;
      dest.instructions.back().code.swap(assignment);
      dest.instructions.back().function=function_name;      
    }

    if(it1!=arguments.end())
      ++it1;
  }

  if(it1!=arguments.end())
  {
    // too many arguments -- we just ignore that, no harm done
  }
}
Beispiel #10
0
void convert(
  const namespacet &ns,
  const goto_tracet &goto_trace,
  xmlt &dest)
{
  dest=xmlt("goto_trace");

  source_locationt previous_source_location;

  for(const auto & it : goto_trace.steps)
  {
    const source_locationt &source_location=it.pc->source_location;

    xmlt xml_location;
    if(source_location.is_not_nil() && source_location.get_file()!="")
      xml_location=xml(source_location);

    switch(it.type)
    {
    case goto_trace_stept::ASSERT:
      if(!it.cond_value)
      {
        irep_idt property_id;

        if(it.pc->is_assert())
          property_id=source_location.get_property_id();
        else if(it.pc->is_goto()) // unwinding, we suspect
        {
          property_id=
            id2string(it.pc->source_location.get_function())+".unwind."+
            i2string(it.pc->loop_number);
        }

        xmlt &xml_failure=dest.new_element("failure");

        xml_failure.set_attribute_bool("hidden", it.hidden);
        xml_failure.set_attribute("thread", i2string(it.thread_nr));
        xml_failure.set_attribute("step_nr", i2string(it.step_nr));
        xml_failure.set_attribute("reason", id2string(it.comment));
        xml_failure.set_attribute("property", id2string(property_id));

        if(xml_location.name!="")
          xml_failure.new_element().swap(xml_location);
      }
      break;

    case goto_trace_stept::ASSIGNMENT:
    case goto_trace_stept::DECL:
      {
        irep_idt identifier=it.lhs_object.get_identifier();
        xmlt &xml_assignment=dest.new_element("assignment");

        if(xml_location.name!="")
          xml_assignment.new_element().swap(xml_location);

        std::string value_string, binary_string, type_string,
                    full_lhs_string, full_lhs_value_string;

        if(it.lhs_object_value.is_not_nil())
          value_string=from_expr(ns, identifier, it.lhs_object_value);

        if(it.full_lhs.is_not_nil())
          full_lhs_string=from_expr(ns, identifier, it.full_lhs);

        if(it.full_lhs_value.is_not_nil())
          full_lhs_value_string=from_expr(ns, identifier, it.full_lhs_value);

        if(it.lhs_object_value.type().is_not_nil())
          type_string=from_type(ns, identifier, it.lhs_object_value.type());

        const symbolt *symbol;
        irep_idt base_name, display_name;

        if(!ns.lookup(identifier, symbol))
        {
          base_name=symbol->base_name;
          display_name=symbol->display_name();
          if(type_string=="")
            type_string=from_type(ns, identifier, symbol->type);

          xml_assignment.set_attribute("mode", id2string(symbol->mode));
        }

        xml_assignment.new_element("type").data=type_string;
        xml_assignment.new_element("full_lhs").data=full_lhs_string;
        xml_assignment.new_element("full_lhs_value").data=full_lhs_value_string;
        xml_assignment.new_element("value").data=value_string;

        xml_assignment.set_attribute_bool("hidden", it.hidden);
        xml_assignment.set_attribute("thread", i2string(it.thread_nr));
        xml_assignment.set_attribute("identifier", id2string(identifier));
        xml_assignment.set_attribute("base_name", id2string(base_name));
        xml_assignment.set_attribute("display_name", id2string(display_name));
        xml_assignment.set_attribute("step_nr", i2string(it.step_nr));

        xml_assignment.set_attribute("assignment_type",
          it.assignment_type==goto_trace_stept::ACTUAL_PARAMETER?"actual_parameter":
          "state");

        if(it.lhs_object_value.is_not_nil())
          xml_assignment.new_element("value_expression").new_element(xml(it.lhs_object_value, ns));
      }
      break;

    case goto_trace_stept::OUTPUT:
      {
        printf_formattert printf_formatter(ns);
        printf_formatter(id2string(it.format_string), it.io_args);
        std::string text=printf_formatter.as_string();
        xmlt &xml_output=dest.new_element("output");

        xml_output.new_element("text").data=text;

        xml_output.set_attribute_bool("hidden", it.hidden);
        xml_output.set_attribute("thread", i2string(it.thread_nr));
        xml_output.set_attribute("step_nr", i2string(it.step_nr));

        if(xml_location.name!="")
          xml_output.new_element().swap(xml_location);

        for(const auto l_it : it.io_args)
        {
          xml_output.new_element("value").data=from_expr(ns, "", l_it);
          xml_output.new_element("value_expression").
            new_element(xml(l_it, ns));
        }
      }
      break;

    case goto_trace_stept::INPUT:
      {
        xmlt &xml_input=dest.new_element("input");
        xml_input.new_element("input_id").data=id2string(it.io_id);

        xml_input.set_attribute_bool("hidden", it.hidden);
        xml_input.set_attribute("thread", i2string(it.thread_nr));
        xml_input.set_attribute("step_nr", i2string(it.step_nr));

        for(const auto & l_it : it.io_args)
        {
          xml_input.new_element("value").data=from_expr(ns, "", l_it);
          xml_input.new_element("value_expression").
            new_element(xml(l_it, ns));
        }

        if(xml_location.name!="")
          xml_input.new_element().swap(xml_location);
      }
      break;

    case goto_trace_stept::FUNCTION_CALL:
    case goto_trace_stept::FUNCTION_RETURN:
      {
        std::string tag=
          (it.type==goto_trace_stept::FUNCTION_CALL)?"function_call":"function_return";
        xmlt &xml_call_return=dest.new_element(tag);

        xml_call_return.set_attribute_bool("hidden", it.hidden);
        xml_call_return.set_attribute("thread", i2string(it.thread_nr));
        xml_call_return.set_attribute("step_nr", i2string(it.step_nr));

        const symbolt &symbol=ns.lookup(it.identifier);
        xmlt &xml_function=xml_call_return.new_element("function");
        xml_function.set_attribute("display_name", id2string(symbol.display_name()));
        xml_function.set_attribute("identifier", id2string(it.identifier));
        xml_function.new_element()=xml(symbol.location);

        if(xml_location.name!="")
          xml_call_return.new_element().swap(xml_location);
      }
      break;

    default:
      if(source_location!=previous_source_location)
      {
        // just the source location
        if(xml_location.name!="")
        {
          xmlt &xml_location_only=dest.new_element("location-only");

          xml_location_only.set_attribute_bool("hidden", it.hidden);
          xml_location_only.set_attribute("thread", i2string(it.thread_nr));
          xml_location_only.set_attribute("step_nr", i2string(it.step_nr));

          xml_location_only.new_element().swap(xml_location);
        }
      }
    }

    if(source_location.is_not_nil() && source_location.get_file()!="")
      previous_source_location=source_location;
  }
}