32 if(type.
id() == ID_c_enum_tag)
34 else if(type.
id()==ID_struct_tag)
36 else if(type.
id()==ID_union_tag)
59 if(src_symbol_table.
symbols.find(new_identifier)!=
63 return new_identifier;
75 return renamingt::RENAME_NEW;
77 return renamingt::RENAME_OLD;
79 return renamingt::NO_RENAMING;
89 if(old_symbol.
type != new_symbol.
type)
96 diag.warning(old_symbol, new_symbol,
"implicit function declaration");
108 "ignoring conflicting implicit function declaration");
133 "function declaration conflicts with with weak definition");
148 "ignoring conflicting weak function declaration");
162 "ignoring conflicting function alias declaration");
169 old_symbol, new_symbol,
"ignoring conflicting function declarations");
189 "conflicting parameter counts of function declarations");
198 std::string warn_msg;
200 typedef std::deque<std::pair<typet, typet> > conflictst;
201 conflictst conflicts;
205 diag.warning(old_symbol, new_symbol,
"conflicting return types");
210 code_typet::parameterst::const_iterator
218 if(o_it->type() != n_it->type())
220 std::make_pair(o_it->type(), n_it->type()));
229 "conflicting parameter counts of function declarations");
244 "conflicting parameter counts of function declarations");
253 while(!conflicts.empty())
260 (t1.
id() == ID_pointer || t2.
id() == ID_pointer) &&
265 warn_msg=
"different pointer types in extern function";
270 else if((t1.
id()==ID_pointer || t2.
id()==ID_pointer) &&
276 warn_msg=
"pointer parameter types differ between "
277 "declaration and definition";
285 else if((t1.
id()==ID_union &&
286 (t1.
get_bool(ID_C_transparent_union) ||
287 conflicts.front().first.get_bool(ID_C_transparent_union))) ||
288 (t2.
id()==ID_union &&
289 (t2.
get_bool(ID_C_transparent_union) ||
290 conflicts.front().second.get_bool(ID_C_transparent_union))))
294 (t1.
get_bool(ID_C_transparent_union) ||
295 conflicts.front().first.get_bool(ID_C_transparent_union)) &&
300 const typet &src_type=t1.
id()==ID_union?t2:t1;
304 if(c.type() == src_type)
308 warn_msg=
"conflict on transparent union parameter in function";
322 warn_msg=
"non-pointer parameter types differ between "
323 "declaration and definition";
329 conflicts.pop_front();
332 if(!conflicts.empty())
334 diag.detailed_conflict_report(
337 conflicts.front().first,
338 conflicts.front().second);
340 diag.error(old_symbol, new_symbol,
"conflicting function declarations");
348 diag.warning(old_symbol, new_symbol, warn_msg);
384 else if(old_symbol.
type == new_symbol.
type)
389 log.debug() <<
"function '" << old_symbol.
name <<
"' in module '"
391 <<
"' is shadowed by a definition in module '"
396 diag.error(old_symbol, new_symbol,
"duplicate definition of function");
410 t1.
id() == ID_struct_tag || t1.
id() == ID_union_tag ||
411 t1.
id() == ID_c_enum_tag)
415 if(info.
o_symbols.insert(identifier).second)
427 t2.
id() == ID_struct_tag || t2.
id() == ID_union_tag ||
428 t2.
id() == ID_c_enum_tag)
432 if(info.
n_symbols.insert(identifier).second)
443 else if(t1.
id()==ID_pointer && t2.
id()==ID_array)
449 else if(t1.
id()==ID_array && t2.
id()==ID_pointer)
484 else if(t1.
id()!=t2.
id())
490 if(t1.
id()==ID_pointer)
500 "conflicting pointer types for variable");
507 "conflicting pointer types for variable");
518 t1.
id() == ID_array &&
532 else if(new_size.
is_nil() ||
540 if(new_size.
type() != old_size.
type())
546 "conflicting array sizes for variable");
560 "conflicting array sizes for variable");
569 else if(t1.
id()==ID_struct || t1.
id()==ID_union)
577 struct_union_typet::componentst::const_iterator
578 it1=components1.begin(), it2=components2.begin();
580 it1!=components1.end() && it2!=components2.end();
583 if(it1->get_name()!=it2->get_name() ||
587 if(it1!=components1.end() || it2!=components2.end())
616 bool set_to_new =
false;
618 if(old_symbol.
type != new_symbol.
type)
631 if(old_type.
id()==ID_struct ||
632 old_type.
id()==ID_union ||
633 old_type.
id()==ID_array ||
634 old_type.
id()==ID_c_enum)
636 diag.detailed_conflict_report(
637 old_symbol, new_symbol, old_symbol.
type, new_symbol.
type);
640 diag.error(old_symbol, new_symbol,
"conflicting types for variable");
667 tmp_new=new_symbol.
value;
672 if(tmp_old == tmp_new)
679 log.warning().source_location = new_symbol.
location;
681 log.warning() <<
"conflicting initializers for"
682 <<
" variable '" << old_symbol.
name <<
"'\n";
683 log.warning() <<
"using old value in module " << old_symbol.
module
686 log.warning() <<
"ignoring new value in module " << new_symbol.
module
710 old_symbol.
type != new_symbol.
type))
713 diag.error(old_symbol, new_symbol,
"conflict on code contract");
718 bool is_code_old_symbol=old_symbol.
type.
id()==ID_code;
719 bool is_code_new_symbol=new_symbol.
type.
id()==ID_code;
721 if(is_code_old_symbol!=is_code_new_symbol)
724 diag.error(old_symbol, new_symbol,
"conflicting definition for symbol");
730 if(is_code_old_symbol)
753 diag.error(old_symbol, new_symbol,
"conflicting definition for symbol");
759 if(old_symbol.
type==new_symbol.
type)
763 old_symbol.
type.
id() == ID_struct &&
765 new_symbol.
type.
id() == ID_struct &&
774 old_symbol.
type.
id() == ID_struct &&
776 new_symbol.
type.
id() == ID_struct &&
784 old_symbol.
type.
id() == ID_union &&
786 new_symbol.
type.
id() == ID_union &&
795 old_symbol.
type.
id() == ID_union &&
797 new_symbol.
type.
id() == ID_union &&
805 old_symbol.
type.
id() == ID_array && new_symbol.
type.
id() == ID_array &&
827 diag.detailed_conflict_report(
828 old_symbol, new_symbol, old_symbol.
type, new_symbol.
type);
831 old_symbol, new_symbol,
"unexpected difference between type symbols");
841 return renamingt::RENAME_NEW;
843 if(old_symbol.
type==new_symbol.
type)
844 return renamingt::NO_RENAMING;
847 old_symbol.
type.
id() == ID_struct &&
849 new_symbol.
type.
id() == ID_struct &&
852 return renamingt::NO_RENAMING;
856 old_symbol.
type.
id() == ID_struct &&
858 new_symbol.
type.
id() == ID_struct &&
861 return renamingt::NO_RENAMING;
865 old_symbol.
type.
id() == ID_union &&
867 new_symbol.
type.
id() == ID_union &&
870 return renamingt::NO_RENAMING;
874 old_symbol.
type.
id() == ID_union &&
876 new_symbol.
type.
id() == ID_union &&
879 return renamingt::NO_RENAMING;
883 old_symbol.
type.
id() == ID_array && new_symbol.
type.
id() == ID_array &&
890 return renamingt::NO_RENAMING;
896 return renamingt::NO_RENAMING;
900 return renamingt::RENAME_NEW;
905 std::unordered_set<irep_idt> &needs_to_be_renamed,
912 std::unordered_map<irep_idt, std::unordered_set<irep_idt>> used_by;
914 for(
const auto &symbol_pair : src_symbol_table.
symbols)
916 if(symbol_pair.second.is_type)
922 for(
const auto &symbol_used : symbols_used)
924 used_by[symbol_used].insert(symbol_pair.first);
929 std::deque<irep_idt> queue(
930 needs_to_be_renamed.begin(), needs_to_be_renamed.end());
932 while(!queue.empty())
937 const std::unordered_set<irep_idt> &u = used_by[id];
939 for(
const auto &dep : u)
940 if(needs_to_be_renamed.insert(dep).second)
942 queue.push_back(dep);
945 log.debug() <<
"LINKING: needs to be renamed (dependency): " << dep
954 const std::unordered_set<irep_idt> &needs_to_be_renamed)
956 std::unordered_map<irep_idt, irep_idt> new_identifiers;
959 for(
const irep_idt &
id : needs_to_be_renamed)
968 new_identifier =
rename(src_symbol_table,
id);
970 new_identifiers.emplace(
id, new_identifier);
974 log.debug() <<
"LINKING: renaming " <<
id <<
" to " << new_identifier
984 return new_identifiers;
989 const std::unordered_map<irep_idt, irep_idt> &new_identifiers)
991 std::map<irep_idt, symbolt> src_symbols;
993 for(
const auto &named_symbol : src_symbol_table.
symbols)
995 symbolt symbol=named_symbol.second;
999 auto it = new_identifiers.find(named_symbol.first);
1000 if(it != new_identifiers.end())
1001 symbol.
name = it->second;
1003 src_symbols.emplace(named_symbol.first, std::move(symbol));
1007 std::unordered_set<irep_idt> collisions;
1009 for(
const auto &named_symbol : src_symbols)
1012 if(named_symbol.first!=named_symbol.second.name)
1025 collisions.insert(named_symbol.first);
1030 for(
const irep_idt &collision : collisions)
1033 symbolt &new_symbol=src_symbols.at(collision);
1045 !it->second.is_type && !it->second.is_macro &&
1046 it->second.value.is_not_nil())
1055 const unsigned errors_before =
1064 std::unordered_set<irep_idt> needs_to_be_renamed;
1066 for(
const auto &symbol_pair : src_symbol_table.
symbols)
1068 symbol_table_baset::symbolst::const_iterator m_it =
1076 case renamingt::NO_RENAMING:
1078 case renamingt::RENAME_OLD:
1080 symbolt renamed_symbol = m_it->second;
1081 renamed_symbol.
name =
rename(src_symbol_table, symbol_pair.first);
1082 if(m_it->second.is_type)
1090 case renamingt::RENAME_NEW:
1092 needs_to_be_renamed.insert(symbol_pair.first);
1095 log.debug() <<
"LINKING: needs to be renamed: " << symbol_pair.first
1107 symbolt tmp = symbol_pair.second;
1114 *sym_ptr = std::move(tmp);
1122 auto new_identifiers =
rename_symbols(src_symbol_table, needs_to_be_renamed);
1137 return linking.link(new_symbol_table);
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
const typet & element_type() const
The type of the elements of the array.
const exprt & size() const
const typet & return_type() const
bool has_ellipsis() const
const parameterst & parameters() const
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Base class for all expressions.
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
bool is_zero() const
Return whether the expression is a constant representing 0.
typet & type()
Return the type of the expression.
bool get_bool(const irep_idt &name) const
const irep_idt & id() const
std::unordered_map< irep_idt, irep_idt > rename_symbols(const symbol_table_baset &, const std::unordered_set< irep_idt > &needs_to_be_renamed)
void duplicate_non_type_symbol(symbolt &old_symbol, symbolt &new_symbol)
bool adjust_object_type(const symbolt &old_symbol, const symbolt &new_symbol, bool &set_to_new)
bool link(const symbol_table_baset &src_symbol_table)
Merges the symbol table src_symbol_table into main_symbol_table, renaming symbols from src_symbol_tab...
renamingt needs_renaming(const symbolt &old_symbol, const symbolt &new_symbol)
bool adjust_object_type_rec(const typet &type1, const typet &type2, adjust_type_infot &info)
rename_symbolt rename_main_symbol
void copy_symbols(const symbol_table_baset &, const std::unordered_map< irep_idt, irep_idt > &)
irep_idt rename(const symbol_table_baset &, const irep_idt &)
renamingt needs_renaming_type(const symbolt &old_symbol, const symbolt &new_symbol)
symbol_table_baset & main_symbol_table
renamingt needs_renaming_non_type(const symbolt &old_symbol, const symbolt &new_symbol)
void duplicate_object_symbol(symbolt &old_symbol, symbolt &new_symbol)
casting_replace_symbolt object_type_updates
std::unordered_set< irep_idt > renamed_ids
void duplicate_type_symbol(symbolt &old_symbol, const symbolt &new_symbol)
rename_symbolt rename_new_symbol
void duplicate_code_symbol(symbolt &old_symbol, symbolt &new_symbol)
message_handlert & message_handler
std::size_t get_message_count(unsigned level) const
Class that provides messages with a built-in verbosity 'level'.
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
void insert_type(const irep_idt &old_id, const irep_idt &new_id)
void insert_expr(const irep_idt &old_id, const irep_idt &new_id)
std::size_t erase(const irep_idt &id)
void insert(const class symbol_exprt &old_expr, const exprt &new_expr)
Sets old_expr to be replaced by new_expr if we don't already have a replacement; otherwise does nothi...
bool is_incomplete() const
A struct/union may be incomplete.
const componentst & components() const
std::vector< componentt > componentst
The symbol table base class interface.
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
virtual void erase(const symbolst::const_iterator &entry)=0
Remove a symbol from the symbol table.
virtual iteratort begin()=0
const symbolst & symbols
Read-only field, used to look up symbols given their names.
virtual iteratort end()=0
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
virtual symbolt * get_writeable(const irep_idt &name)=0
Find a symbol in the symbol table for read-write access.
virtual std::pair< symbolt &, bool > insert(symbolt symbol)=0
Move or copy a new symbol to the symbol table.
irep_idt module
Name of module the symbol belongs to.
source_locationt location
Source code location of definition of symbol.
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
typet type
Type of symbol.
irep_idt name
The unique identifier.
exprt value
Initial value of symbol.
const irep_idt & get_identifier() const
Semantic type conversion.
The type of an expression, extends irept.
void find_type_and_expr_symbols(const exprt &src, find_symbols_sett &dest, const std::vector< irep_idt > &subs_to_find)
Find identifiers with id ID_symbol of the sub expressions and the subs with ID in subs_to_find consid...
std::unordered_set< irep_idt > find_symbols_sett
const std::string & id2string(const irep_idt &d)
std::string from_expr(const namespacet &ns, const irep_idt &identifier, const exprt &expr)
std::string type_to_name(const namespacet &ns, const irep_idt &identifier, const typet &type)
static void do_type_dependencies(const symbol_table_baset &src_symbol_table, std::unordered_set< irep_idt > &needs_to_be_renamed, message_handlert &message_handler)
static const typet & follow_tags_symbols(const namespacet &ns, const typet &type)
bool linking(symbol_table_baset &dest_symbol_table, const symbol_table_baset &new_symbol_table, message_handlert &message_handler)
Merges the symbol table new_symbol_table into dest_symbol_table, renaming symbols from new_symbol_tab...
bool is_true(const literalt &l)
std::optional< mp_integer > pointer_offset_bits(const typet &type, const namespacet &ns)
bool simplify(exprt &expr, const namespacet &ns)
exprt simplify_expr(exprt src, const namespacet &ns)
#define CHECK_RETURN(CONDITION)
#define PRECONDITION(CONDITION)
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
const tag_typet & to_tag_type(const typet &type)
Cast a typet to a tag_typet.
void replace(const union_find_replacet &replace_map, string_not_contains_constraintt &constraint)
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
const symbolt & old_symbol
std::unordered_set< irep_idt > o_symbols
std::unordered_set< irep_idt > n_symbols
const symbolt & new_symbol
static bool failed(bool error_indicator)