コード例 #1
0
void c_typecheck_baset::typecheck_symbol_type(typet &type)
{
  {
    // add prefix
    symbol_typet &symbol_type=to_symbol_type(type);
    symbol_type.set_identifier(add_language_prefix(symbol_type.get_identifier()));
  }

  // adjust identifier, if needed
  replace_symbol(type);

  const irep_idt &identifier=
    to_symbol_type(type).get_identifier();

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

  if(s_it==symbol_table.symbols.end())
  {
    err_location(type);
    str << "type symbol `" << identifier << "' not found";
    throw 0;
  }

  const symbolt &symbol=s_it->second;

  if(!symbol.is_type)
  {
    err_location(type);
    throw "expected type symbol";
  }
  
  if(symbol.is_macro)
  {
    // overwrite, but preserve (add) any qualifiers and other flags

    c_qualifierst c_qualifiers(type);
    bool is_packed=type.get_bool(ID_C_packed);
    irept alignment=type.find(ID_C_alignment);
    
    c_qualifiers+=c_qualifierst(symbol.type);
    type=symbol.type;
    c_qualifiers.write(type);
    
    if(is_packed) type.set(ID_C_packed, true);
    if(alignment.is_not_nil()) type.set(ID_C_alignment, alignment);
  }
    
  // CPROVER extensions
  if(symbol.base_name=="__CPROVER_rational")
  {
    type=rational_typet();
  }
  else if(symbol.base_name=="__CPROVER_integer")
  {
    type=integer_typet();
  }
}
コード例 #2
0
void java_bytecode_convertt::add_array_types()
{
  const char letters[]="ijsbcfdza";

  for(unsigned i=0; letters[i]!=0; i++)
  {
    symbol_typet symbol_type=
      to_symbol_type(java_array_type(letters[i]).subtype());
    
    struct_typet struct_type;
    // we have the base class, java.lang.Object, length and data
    // of appropriate type
    struct_type.set_tag(symbol_type.get_identifier());
    struct_type.components().resize(3);
    struct_type.components()[0].set_name("@java.lang.Object");
    struct_type.components()[0].type()=symbol_typet("java::java.lang.Object");
    struct_type.components()[1].set_name("length");
    struct_type.components()[1].type()=java_int_type();
    struct_type.components()[2].set_name("data");
    struct_type.components()[2].type()=
      pointer_typet(java_type_from_char(letters[i]));

    symbolt symbol;
    symbol.name=symbol_type.get_identifier();
    symbol.base_name=symbol_type.get(ID_C_base_name);
    symbol.is_type=true;
    symbol.type=struct_type;
    symbol_table.add(symbol);
  }
}
コード例 #3
0
void linkingt::rename_type_symbol(symbolt &new_symbol)
{
  replace_symbolt::type_mapt::const_iterator replace_entry=
    replace_symbol.type_map.find(new_symbol.name);

  if(replace_entry!=replace_symbol.type_map.end())
  {
    new_symbol.name=to_symbol_type(replace_entry->second).get_identifier();
  }
  else
  {
    // rename!
    irep_idt old_identifier=new_symbol.name;
    irep_idt new_identifier=rename(old_identifier);

    replace_symbol.insert(old_identifier, symbol_typet(new_identifier));

    new_symbol.name=new_identifier;
  }

  // need to replace again
  replace_symbol.replace(new_symbol.type);

  // move over!
  bool result=main_context.move(new_symbol);
  assert(!result);
}
コード例 #4
0
void java_bytecode_convert_classt::add_array_types()
{
  const std::string letters="ijsbcfdza";

  for(const char l : letters)
  {
    symbol_typet symbol_type=
      to_symbol_type(java_array_type(l).subtype());

    struct_typet struct_type;
    // we have the base class, java.lang.Object, length and data
    // of appropriate type
    struct_type.set_tag(symbol_type.get_identifier());

    struct_type.components().reserve(3);
    struct_typet::componentt
      comp0("@java.lang.Object", symbol_typet("java::java.lang.Object"));
    struct_type.components().push_back(comp0);

    struct_typet::componentt comp1("length", java_int_type());
    struct_type.components().push_back(comp1);

    struct_typet::componentt
      comp2("data", pointer_typet(java_type_from_char(l)));
    struct_type.components().push_back(comp2);

    symbolt symbol;
    symbol.name=symbol_type.get_identifier();
    symbol.base_name=symbol_type.get(ID_C_base_name);
    symbol.is_type=true;
    symbol.type=struct_type;
    symbol_table.add(symbol);
  }
}
コード例 #5
0
ファイル: jsa_meta_data.cpp プロジェクト: lihaol/cbmc
bool is_jsa_heap(const typet &type)
{
  const irep_idt &type_id=type.id();
  if (ID_symbol == type_id)
    return id2string(to_symbol_type(type).get_identifier()) == JSA_HEAP_TAG;
  if (ID_struct != type_id) return false;
  const irep_idt tag(to_struct_type(type).get_tag());
  return id2string(tag) == JSA_HEAP_TAG;
}
コード例 #6
0
ファイル: refined_string_type.cpp プロジェクト: danpoe/cbmc
/// \par parameters: a type
/// \return Boolean telling whether the type is that of java string
bool refined_string_typet::is_java_string_type(const typet &type)
{
  if(type.id()==ID_symbol)
  {
    irep_idt tag=to_symbol_type(type).get_identifier();
    return tag=="java::java.lang.String";
  }
  else if(type.id()==ID_struct)
  {
    irep_idt tag=to_struct_type(type).get_tag();
    return tag=="java.lang.String";
  }
  return false;
}
コード例 #7
0
void goto_convertt::do_java_new(
  const exprt &lhs,
  const side_effect_exprt &rhs,
  goto_programt &dest)
{
  if(lhs.is_nil())
    throw "do_java_new without lhs is yet to be implemented";
    
  source_locationt location=rhs.source_location();

  assert(rhs.operands().empty());

  if(rhs.type().id()!=ID_pointer)
    throw "do_java_new returns pointer";

  typet object_type=rhs.type().subtype();
  
  // build size expression
  exprt object_size=size_of_expr(object_type, ns);
  
  if(object_size.is_nil())
    throw "do_java_new got nil object_size";

  // we produce a malloc side-effect, which stays
  side_effect_exprt malloc_expr(ID_malloc);
  malloc_expr.copy_to_operands(object_size);
  malloc_expr.type()=pointer_typet(object_type);

  goto_programt::targett t_n=dest.add_instruction(ASSIGN);
  t_n->code=code_assignt(lhs, malloc_expr);
  t_n->source_location=location;
  
  // zero-initialize the object
  dereference_exprt deref(lhs, object_type);
  exprt zero_object=zero_initializer(object_type, location, ns, get_message_handler());
  set_class_identifier(to_struct_expr(zero_object), ns, to_symbol_type(object_type));
  goto_programt::targett t_i=dest.add_instruction(ASSIGN);
  t_i->code=code_assignt(deref, zero_object);
  t_i->source_location=location;
}
コード例 #8
0
void java_bytecode_typecheckt::typecheck_type(typet &type)
{
  if(type.id()==ID_symbol)
  {
    irep_idt identifier=to_symbol_type(type).get_identifier();

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

    // must exist already in the symbol table
    if(s_it==symbol_table.symbols.end())
    {
      error() << "failed to find type symbol "<< identifier << eom;
      throw 0;
    }

    assert(s_it->second.is_type);
  }
  else if(type.id()==ID_pointer)
  {
    typecheck_type(type.subtype());
  }
  else if(type.id()==ID_array)
  {
    typecheck_type(type.subtype());
    typecheck_expr(to_array_type(type).size());
  }
  else if(type.id()==ID_code)
  {
    code_typet &code_type=to_code_type(type);
    typecheck_type(code_type.return_type());

    code_typet::parameterst &parameters=code_type.parameters();

    for(code_typet::parameterst::iterator
        it=parameters.begin(); it!=parameters.end(); it++)
      typecheck_type(it->type());
  }
}
コード例 #9
0
ファイル: control_types.cpp プロジェクト: lihaol/cbmc
const symbol_typet &control_solution_type(const symbol_tablet &st)
{
  return to_symbol_type(st.lookup(CEGIS_CONTROL_SOLUTION_VAR_NAME).type);
}
コード例 #10
0
ファイル: c_typecheck_base.cpp プロジェクト: Dthird/CBMC
void c_typecheck_baset::typecheck_redefinition_non_type(
  symbolt &old_symbol,
  symbolt &new_symbol)
{
  const typet &final_old=follow(old_symbol.type);
  const typet &initial_new=follow(new_symbol.type);

  if(final_old.id()==ID_array &&
     to_array_type(final_old).size().is_not_nil() &&
     initial_new.id()==ID_array &&
     to_array_type(initial_new).size().is_nil() &&
     final_old.subtype()==initial_new.subtype())
  {
    // this is ok, just use old type
    new_symbol.type=old_symbol.type;
  }

  // do initializer, this may change the type
  if(follow(new_symbol.type).id()!=ID_code)
    do_initializer(new_symbol);
  
  const typet &final_new=follow(new_symbol.type);
  
  // K&R stuff?
  if(old_symbol.type.id()==ID_KnR)
  {
    // check the type
    if(final_new.id()==ID_code)
    {
      err_location(new_symbol.location);
      throw "function type not allowed for K&R function parameter";
    }
    
    // fix up old symbol -- we now got the type
    old_symbol.type=new_symbol.type;
    return;
  }
  
  if(final_new.id()==ID_code)
  {
    bool inlined=
       (new_symbol.type.get_bool(ID_C_inlined) ||
        old_symbol.type.get_bool(ID_C_inlined));
        
    if(final_old.id()!=ID_code)
    {
      err_location(new_symbol.location);
      str << "error: function symbol `" << new_symbol.display_name()
          << "' redefined with a different type:" << "\n";
      str << "Original: " << to_string(old_symbol.type) << "\n";
      str << "     New: " << to_string(new_symbol.type);
      throw 0;
    }

    code_typet &old_ct=to_code_type(old_symbol.type);
    code_typet &new_ct=to_code_type(new_symbol.type);
    
    if(old_ct.has_ellipsis() && !new_ct.has_ellipsis())
      old_ct=new_ct;
    else if(!old_ct.has_ellipsis() && new_ct.has_ellipsis())
      new_ct=old_ct;

    if(inlined)
    {
      old_symbol.type.set(ID_C_inlined, true);
      new_symbol.type.set(ID_C_inlined, true);
    }

    // do body
    
    if(new_symbol.value.is_not_nil())
    {  
      if(old_symbol.value.is_not_nil())
      {
        // gcc allows re-definition if the first
        // definition is marked as "extern inline"
        
        if(old_symbol.type.get_bool(ID_C_inlined) &&
           (config.ansi_c.mode==configt::ansi_ct::flavourt::MODE_GCC_C ||
            config.ansi_c.mode==configt::ansi_ct::flavourt::MODE_ARM_C_CPP))
        {
          // overwrite "extern inline" properties
          old_symbol.is_extern=new_symbol.is_extern;
          old_symbol.is_file_local=new_symbol.is_file_local;

          // remove parameter declarations to avoid conflicts
          const code_typet::parameterst &old_p=old_ct.parameters();
          for(code_typet::parameterst::const_iterator
              p_it=old_p.begin();
              p_it!=old_p.end();
              p_it++)
          {
            const irep_idt &identifier=p_it->get_identifier();

            symbol_tablet::symbolst::iterator p_s_it=
              symbol_table.symbols.find(identifier);
            if(p_s_it!=symbol_table.symbols.end())
              symbol_table.symbols.erase(p_s_it);
          }
        }
        else
        {
          err_location(new_symbol.location);
          str << "function body `" << new_symbol.display_name()
              << "' defined twice";
          error_msg();
          throw 0;
        }
      }
      else if(inlined)
      {
        // preserve "extern inline" properties
        old_symbol.is_extern=new_symbol.is_extern;
        old_symbol.is_file_local=new_symbol.is_file_local;
      }

      typecheck_function_body(new_symbol);
    
      // overwrite location
      old_symbol.location=new_symbol.location;
    
      // move body
      old_symbol.value.swap(new_symbol.value);

      // overwrite type (because of parameter names)
      old_symbol.type=new_symbol.type;
    }

    return;
  }

  if(final_old!=final_new)
  {
    if(final_old.id()==ID_array &&
            to_array_type(final_old).size().is_nil() &&
            final_new.id()==ID_array &&
            to_array_type(final_new).size().is_not_nil() &&
            final_old.subtype()==final_new.subtype())
    {
      // this is also ok
      if(old_symbol.type.id()==ID_symbol)
      {
        // fix the symbol, not just the type
        const irep_idt identifier=
          to_symbol_type(old_symbol.type).get_identifier();

        symbol_tablet::symbolst::iterator s_it=symbol_table.symbols.find(identifier);
  
        if(s_it==symbol_table.symbols.end())
        {
          err_location(old_symbol.location);
          str << "typecheck_redefinition_non_type: "
                 "failed to find symbol `" << identifier << "'";
          throw 0;
        }
                  
        symbolt &symbol=s_it->second;
          
        symbol.type=final_new;          
      }
      else
        old_symbol.type=new_symbol.type;
    }
    else if((final_old.id()==ID_incomplete_c_enum ||
             final_old.id()==ID_c_enum) &&
            (final_new.id()==ID_incomplete_c_enum ||
             final_new.id()==ID_c_enum))
    {
      // this is ok for now
    }
    else if(final_old.id()==ID_pointer &&
            follow(final_old).subtype().id()==ID_code &&
            to_code_type(follow(final_old).subtype()).has_ellipsis() &&
            final_new.id()==ID_pointer &&
            follow(final_new).subtype().id()==ID_code)
    {
      // to allow 
      // int (*f) ();
      // int (*f) (int)=0;
      old_symbol.type=new_symbol.type;
    }
    else if(final_old.id()==ID_pointer &&
            follow(final_old).subtype().id()==ID_code &&
            final_new.id()==ID_pointer &&
            follow(final_new).subtype().id()==ID_code &&
            to_code_type(follow(final_new).subtype()).has_ellipsis())
    {
      // to allow 
      // int (*f) (int)=0;
      // int (*f) ();
    }
    else
    {
      err_location(new_symbol.location);
      str << "error: symbol `" << new_symbol.display_name()
          << "' redefined with a different type:" << "\n";
      str << "Original: " << to_string(old_symbol.type) << "\n";
      str << "     New: " << to_string(new_symbol.type);
      throw 0;
    }
  }
  else // finals are equal
  {
  }

  // do value
  if(new_symbol.value.is_not_nil())
  {
    // see if we already have one
    if(old_symbol.value.is_not_nil())
    {
      if(new_symbol.value.get_bool(ID_C_zero_initializer))
      {
        // do nothing
      }
      else if(old_symbol.value.get_bool(ID_C_zero_initializer))
      {
        old_symbol.value=new_symbol.value;
        old_symbol.type=new_symbol.type;
      }
      else
      {
        if(new_symbol.is_macro &&
           (final_new.id()==ID_incomplete_c_enum ||
            final_new.id()==ID_c_enum) &&
            old_symbol.value.is_constant() &&
            new_symbol.value.is_constant() &&
            old_symbol.value.get(ID_value)==new_symbol.value.get(ID_value))
        {
          // ignore
        }
        else
        {
          err_location(new_symbol.value);
          str << "symbol `" << new_symbol.display_name()
              << "' already has an initial value";
          warning_msg();
        }
      }
    }
    else
    {
      old_symbol.value=new_symbol.value;
      old_symbol.type=new_symbol.type;
    }
  }
  
  // take care of some flags
  if(old_symbol.is_extern && !new_symbol.is_extern)
    old_symbol.location=new_symbol.location;

  old_symbol.is_extern=old_symbol.is_extern && new_symbol.is_extern;
  
  // We should likely check is_volatile and
  // is_thread_local for consistency. GCC complains if these
  // mismatch.
}
コード例 #11
0
void c_typecheck_baset::clean_type(
  const irep_idt &base_symbol_identifier,
  typet &type,
  std::list<codet> &code)
{
  if(type.id()==ID_symbol)
  {
    // we need to follow for structs and such, but only once
    irep_idt identifier=to_symbol_type(type).get_identifier();
    if(already_cleaned.insert(identifier).second)
    {
      symbol_tablet::symbolst::iterator s_it=symbol_table.symbols.find(identifier);
      assert(s_it!=symbol_table.symbols.end());
      clean_type(identifier, s_it->second.type, code);
    }
  }
  else if(type.id()==ID_array)
  {
    array_typet &array_type=to_array_type(type);
  
    clean_type(base_symbol_identifier, array_type.subtype(), code);

    // The size need not be a constant!
    // This was simplified already by typecheck_array_type.
    
    exprt &size=array_type.size();
    
    if(size.is_not_nil() &&
       !size.is_constant() &&
       size.id()!=ID_infinity &&
       !(size.id()==ID_symbol && size.type().get_bool(ID_C_constant)))
    {
      // The criterion above can be tricked:
      // Of course we can modify a 'const' symbol, e.g.,
      // using a pointer type cast. Interestingly,
      // at least gcc 4.2.1 makes the very same mistake!
    
      assert(current_symbol_id!=irep_idt());
        
      const symbolt &base_symbol=
        lookup(
          base_symbol_identifier!=irep_idt()?
          base_symbol_identifier:
          current_symbol_id);
      
      // Need to pull out! We insert new symbol.
      locationt location=size.find_location();
      unsigned count=0;
      irep_idt temp_identifier;
      std::string suffix;

      do
      {
        suffix="$array_size"+i2string(count);
        temp_identifier=id2string(base_symbol.name)+suffix;
        count++;
      }
      while(symbol_table.symbols.find(temp_identifier)!=symbol_table.symbols.end());

      // add the symbol to symbol table
      symbolt new_symbol;
      new_symbol.name=temp_identifier;
      new_symbol.pretty_name=id2string(base_symbol.pretty_name)+suffix;
      new_symbol.base_name=id2string(base_symbol.base_name)+suffix;
      new_symbol.type=size.type();
      new_symbol.type.set(ID_C_constant, true);
      new_symbol.is_file_local=true;
      new_symbol.is_type=false;
      new_symbol.is_thread_local=true;
      new_symbol.is_static_lifetime=false;
      new_symbol.value.make_nil();
      new_symbol.location=location;
      
      symbol_table.add(new_symbol);

      // produce the code that declares and initializes the symbol
      symbol_exprt symbol_expr;
      symbol_expr.set_identifier(temp_identifier);
      symbol_expr.type()=new_symbol.type;
      
      code_declt declaration(symbol_expr);
      declaration.location()=location;

      code_assignt assignment;
      assignment.lhs()=symbol_expr;
      assignment.rhs()=size;
      assignment.location()=location;

      // store the code
      code.push_back(declaration);
      code.push_back(assignment);

      // fix type
      size=symbol_expr;
    }
  }
  else if(type.id()==ID_struct ||
          type.id()==ID_union)
  {
    struct_union_typet::componentst &components=
      to_struct_union_type(type).components();

    for(struct_union_typet::componentst::iterator
        it=components.begin();
        it!=components.end();
        it++)
      clean_type(base_symbol_identifier, it->type(), code);
  }
  else if(type.id()==ID_code)
  {
    // done, can't contain arrays
  }
  else if(type.id()==ID_pointer)
  {
    clean_type(base_symbol_identifier, type.subtype(), code);
  }
  else if(type.id()==ID_vector)
  {
    // should be clean
  }
}
コード例 #12
0
ファイル: java_bytecode_parser.cpp プロジェクト: lihaol/cbmc
void java_bytecode_parsert::rmethod_attribute(methodt &method)
{
  u2 attribute_name_index=read_u2();
  u4 attribute_length=read_u4();

  irep_idt attribute_name=pool_entry(attribute_name_index).s;

  if(attribute_name=="Code")
  {
    u2 UNUSED max_stack=read_u2();
    u2 UNUSED max_locals=read_u2();

    rbytecode(method.instructions);

    u2 exception_table_length=read_u2();
    method.exception_table.resize(exception_table_length);

    for(std::size_t e=0; e<exception_table_length; e++)
    {
      u2 start_pc=read_u2();
      u2 end_pc=read_u2();
      u2 handler_pc=read_u2();
      u2 catch_type=read_u2();
      method.exception_table[e].start_pc=start_pc;
      method.exception_table[e].end_pc=end_pc;
      method.exception_table[e].handler_pc=handler_pc;
      if(catch_type!=0)
        method.exception_table[e].catch_type=
          to_symbol_type(pool_entry(catch_type).expr.type());
    }

    u2 attributes_count=read_u2();

    for(std::size_t j=0; j<attributes_count; j++)
      rcode_attribute(method);

    irep_idt line_number;

    // add missing line numbers
    for(methodt::instructionst::iterator
        it=method.instructions.begin();
        it!=method.instructions.end();
        it++)
    {
      if(!it->source_location.get_line().empty())
        line_number=it->source_location.get_line();
      else if(!line_number.empty())
        it->source_location.set_line(line_number);
      it->source_location
        .set_function(
          "java::"+id2string(parse_tree.parsed_class.name)+"."+
          id2string(method.name)+":"+method.signature);
    }

    // line number of method
    if(!method.instructions.empty())
      method.source_location.set_line(
        method.instructions.begin()->source_location.get_line());
  }
  else if(attribute_name=="RuntimeInvisibleAnnotations" ||
          attribute_name=="RuntimeVisibleAnnotations")
  {
    rRuntimeAnnotation_attribute(method.annotations);
  }
  else
    skip_bytes(attribute_length);
}