Skip to content

Commit f1044cf

Browse files
author
Daniel Kroening
committed
Merge pull request #38 from tautschnig/linking-arrays-and-compound-types
Linking arrays and compound types
2 parents f0e0c40 + 927b9ff commit f1044cf

File tree

2 files changed

+71
-10
lines changed

2 files changed

+71
-10
lines changed

src/ansi-c/type2name.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,10 @@ static std::string type2name(
187187
{
188188
const array_typet &t=to_array_type(type);
189189
mp_integer size;
190-
if(to_integer(t.size(), size))
191-
result+="ARR?";
192-
else if(t.size().id()==ID_symbol)
190+
if(t.size().id()==ID_symbol)
193191
result+="ARR"+t.size().get_string(ID_identifier);
192+
else if(to_integer(t.size(), size))
193+
result+="ARR?";
194194
else
195195
result+="ARR"+integer2string(size);
196196
}

src/linking/linking.cpp

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ void linkingt::detailed_conflict_report_rec(
217217
const struct_union_typet::componentst &components2=
218218
to_struct_union_type(t2).components();
219219

220+
exprt conflict_path_before=conflict_path;
221+
220222
if(components1.size()!=components2.size())
221223
{
222224
msg="number of members is different (";
@@ -238,11 +240,25 @@ void linkingt::detailed_conflict_report_rec(
238240
}
239241
else if(!base_type_eq(subtype1, subtype2, ns))
240242
{
243+
typedef hash_set_cont<typet, irep_hash> type_sett;
244+
type_sett parent_types;
245+
246+
exprt e=conflict_path_before;
247+
while(e.id()==ID_dereference ||
248+
e.id()==ID_member ||
249+
e.id()==ID_index)
250+
{
251+
parent_types.insert(e.type());
252+
e=e.op0();
253+
}
254+
255+
conflict_path=conflict_path_before;
241256
conflict_path.type()=t1;
242257
conflict_path=
243258
member_exprt(conflict_path, components1[i].get_name());
244259

245-
if(depth>0)
260+
if(depth>0 &&
261+
parent_types.find(t1)==parent_types.end())
246262
detailed_conflict_report_rec(
247263
old_symbol,
248264
new_symbol,
@@ -251,11 +267,29 @@ void linkingt::detailed_conflict_report_rec(
251267
depth-1,
252268
conflict_path);
253269
else
270+
{
254271
msg="type of member "+
255272
id2string(components1[i].get_name())+
256273
" differs";
274+
if(depth>0)
275+
{
276+
std::string msg_bak;
277+
msg_bak.swap(msg);
278+
symbol_exprt c(ID_C_this);
279+
detailed_conflict_report_rec(
280+
old_symbol,
281+
new_symbol,
282+
subtype1,
283+
subtype2,
284+
depth-1,
285+
c);
286+
msg.swap(msg_bak);
287+
}
257288

258-
break;
289+
}
290+
291+
if(parent_types.find(t1)==parent_types.end())
292+
break;
259293
}
260294
}
261295
}
@@ -563,6 +597,32 @@ void linkingt::duplicate_code_symbol(
563597
old_symbol.location=new_symbol.location;
564598
}
565599
}
600+
// Linux kernel uses void f(void) as generic prototype
601+
else if((old_t.return_type().id()==ID_empty &&
602+
old_t.parameters().empty() &&
603+
!old_t.has_ellipsis() &&
604+
old_symbol.value.is_nil()) ||
605+
(new_t.return_type().id()==ID_empty &&
606+
new_t.parameters().empty() &&
607+
!new_t.has_ellipsis() &&
608+
new_symbol.value.is_nil()))
609+
{
610+
// issue a warning
611+
link_warning(
612+
old_symbol,
613+
new_symbol,
614+
"ignoring conflicting void f(void) function declaration");
615+
616+
if(old_t.return_type().id()==ID_empty &&
617+
old_t.parameters().empty() &&
618+
!old_t.has_ellipsis() &&
619+
old_symbol.value.is_nil())
620+
{
621+
old_symbol.type=new_symbol.type;
622+
old_symbol.location=new_symbol.location;
623+
old_symbol.is_weak=new_symbol.is_weak;
624+
}
625+
}
566626
// mismatch on number of parameters is definitively an error
567627
else if((old_t.parameters().size()<new_t.parameters().size() &&
568628
!old_t.has_ellipsis()) ||
@@ -1081,7 +1141,7 @@ Function: linkingt::do_type_dependencies
10811141

10821142
void linkingt::do_type_dependencies(id_sett &needs_to_be_renamed)
10831143
{
1084-
// Any type that uses a type that will be renamed also
1144+
// Any type that uses a symbol that will be renamed also
10851145
// needs to be renamed, and so on, until saturation.
10861146

10871147
used_byt used_by;
@@ -1090,12 +1150,13 @@ void linkingt::do_type_dependencies(id_sett &needs_to_be_renamed)
10901150
{
10911151
if(s_it->second.is_type)
10921152
{
1093-
find_symbols_sett type_symbols_used;
1094-
find_type_symbols(s_it->second.type, type_symbols_used);
1153+
// find type and array-size symbols
1154+
find_symbols_sett symbols_used;
1155+
find_type_and_expr_symbols(s_it->second.type, symbols_used);
10951156

10961157
for(find_symbols_sett::const_iterator
1097-
it=type_symbols_used.begin();
1098-
it!=type_symbols_used.end();
1158+
it=symbols_used.begin();
1159+
it!=symbols_used.end();
10991160
it++)
11001161
{
11011162
used_by[*it].insert(s_it->first);

0 commit comments

Comments
 (0)