@@ -126,25 +126,30 @@ std::string linkingt::type_to_string_verbose(
126126 return type_to_string (symbol.name , type);
127127}
128128
129- void linkingt::detailed_conflict_report_rec (
129+ bool linkingt::detailed_conflict_report_rec (
130130 const symbolt &old_symbol,
131131 const symbolt &new_symbol,
132132 const typet &type1,
133133 const typet &type2,
134134 unsigned depth,
135135 exprt &conflict_path)
136136{
137- #ifdef DEBUG
137+ bool conclusive = false ;
138+
139+ #ifdef DEBUG
138140 debug () << " <BEGIN DEPTH " << depth << " >" << eom;
139- #endif
141+ #endif
140142
141143 std::string msg;
142144
143145 const typet &t1=follow_tags_symbols (ns, type1);
144146 const typet &t2=follow_tags_symbols (ns, type2);
145147
146148 if (t1.id ()!=t2.id ())
149+ {
147150 msg=" type classes differ" ;
151+ conclusive = true ;
152+ }
148153 else if (t1.id ()==ID_pointer ||
149154 t1.id ()==ID_array)
150155 {
@@ -155,7 +160,7 @@ void linkingt::detailed_conflict_report_rec(
155160 if (conflict_path.type ().id () == ID_pointer)
156161 conflict_path = dereference_exprt (conflict_path);
157162
158- detailed_conflict_report_rec (
163+ conclusive = detailed_conflict_report_rec (
159164 old_symbol,
160165 new_symbol,
161166 to_type_with_subtype (t1).subtype (),
@@ -184,6 +189,7 @@ void linkingt::detailed_conflict_report_rec(
184189 msg=" number of members is different (" ;
185190 msg+=std::to_string (components1.size ())+' /' ;
186191 msg+=std::to_string (components2.size ())+' )' ;
192+ conclusive = true ;
187193 }
188194 else
189195 {
@@ -197,7 +203,7 @@ void linkingt::detailed_conflict_report_rec(
197203 msg=" names of member " +std::to_string (i)+" differ (" ;
198204 msg+=id2string (components1[i].get_name ())+' /' ;
199205 msg+=id2string (components2[i].get_name ())+' )' ;
200- break ;
206+ conclusive = true ;
201207 }
202208 else if (subtype1 != subtype2)
203209 {
@@ -210,6 +216,7 @@ void linkingt::detailed_conflict_report_rec(
210216 e.id ()==ID_index)
211217 {
212218 parent_types.insert (e.type ());
219+ parent_types.insert (follow_tags_symbols (ns, e.type ()));
213220 if (e.id () == ID_dereference)
214221 e = to_dereference_expr (e).pointer ();
215222 else if (e.id () == ID_member)
@@ -220,44 +227,32 @@ void linkingt::detailed_conflict_report_rec(
220227 UNREACHABLE;
221228 }
222229
223- conflict_path=conflict_path_before;
224- conflict_path.type ()=t1;
225- conflict_path=
226- member_exprt (conflict_path, components1[i]);
227-
228- if (depth>0 &&
229- parent_types.find (t1)==parent_types.end ())
230- detailed_conflict_report_rec (
231- old_symbol,
232- new_symbol,
233- subtype1,
234- subtype2,
235- depth-1 ,
236- conflict_path);
237- else
230+ if (parent_types.find (subtype1) == parent_types.end ())
238231 {
239- msg=" type of member " +
240- id2string (components1[i].get_name ())+
241- " differs" ;
242- if (depth>0 )
232+ conflict_path = conflict_path_before;
233+ conflict_path.type () = t1;
234+ conflict_path = member_exprt (conflict_path, components1[i]);
235+
236+ if (depth > 0 )
243237 {
244- std::string msg_bak;
245- msg_bak.swap (msg);
246- symbol_exprt c = symbol_exprt::typeless (ID_C_this);
247- detailed_conflict_report_rec (
238+ conclusive = detailed_conflict_report_rec (
248239 old_symbol,
249240 new_symbol,
250241 subtype1,
251242 subtype2,
252- depth-1 ,
253- c);
254- msg.swap (msg_bak);
243+ depth - 1 ,
244+ conflict_path);
255245 }
256246 }
257-
258- if (parent_types.find (t1)==parent_types.end ())
259- break ;
247+ else
248+ {
249+ msg = " type of member " + id2string (components1[i].get_name ()) +
250+ " differs (recursive)" ;
251+ }
260252 }
253+
254+ if (conclusive)
255+ break ;
261256 }
262257 }
263258 }
@@ -280,12 +275,14 @@ void linkingt::detailed_conflict_report_rec(
280275 msg +=
281276 type_to_string (new_symbol.name , to_c_enum_type (t2).underlying_type ()) +
282277 ' )' ;
278+ conclusive = true ;
283279 }
284280 else if (members1.size ()!=members2.size ())
285281 {
286282 msg=" number of enum members is different (" ;
287283 msg+=std::to_string (members1.size ())+' /' ;
288284 msg+=std::to_string (members2.size ())+' )' ;
285+ conclusive = true ;
289286 }
290287 else
291288 {
@@ -296,15 +293,18 @@ void linkingt::detailed_conflict_report_rec(
296293 msg=" names of member " +std::to_string (i)+" differ (" ;
297294 msg+=id2string (members1[i].get_base_name ())+' /' ;
298295 msg+=id2string (members2[i].get_base_name ())+' )' ;
299- break ;
296+ conclusive = true ;
300297 }
301298 else if (members1[i].get_value ()!=members2[i].get_value ())
302299 {
303300 msg=" values of member " +std::to_string (i)+" differ (" ;
304301 msg+=id2string (members1[i].get_value ())+' /' ;
305302 msg+=id2string (members2[i].get_value ())+' )' ;
306- break ;
303+ conclusive = true ;
307304 }
305+
306+ if (conclusive)
307+ break ;
308308 }
309309 }
310310
@@ -328,21 +328,25 @@ void linkingt::detailed_conflict_report_rec(
328328 msg=" parameter counts differ (" ;
329329 msg+=std::to_string (parameters1.size ())+' /' ;
330330 msg+=std::to_string (parameters2.size ())+' )' ;
331+ conclusive = true ;
331332 }
332333 else if (return_type1 != return_type2)
333334 {
335+ conflict_path.type () = array_typet{void_type (), nil_exprt{}};
334336 conflict_path=
335337 index_exprt (conflict_path,
336338 constant_exprt (std::to_string (-1 ), integer_typet ()));
337339
338340 if (depth>0 )
339- detailed_conflict_report_rec (
341+ {
342+ conclusive = detailed_conflict_report_rec (
340343 old_symbol,
341344 new_symbol,
342345 return_type1,
343346 return_type2,
344- depth- 1 ,
347+ depth - 1 ,
345348 conflict_path);
349+ }
346350 else
347351 msg=" return types differ" ;
348352 }
@@ -355,30 +359,37 @@ void linkingt::detailed_conflict_report_rec(
355359
356360 if (subtype1 != subtype2)
357361 {
362+ conflict_path.type () = array_typet{void_type (), nil_exprt{}};
358363 conflict_path=
359364 index_exprt (conflict_path,
360365 constant_exprt (std::to_string (i), integer_typet ()));
361366
362367 if (depth>0 )
363- detailed_conflict_report_rec (
368+ {
369+ conclusive = detailed_conflict_report_rec (
364370 old_symbol,
365371 new_symbol,
366372 subtype1,
367373 subtype2,
368- depth- 1 ,
374+ depth - 1 ,
369375 conflict_path);
376+ }
370377 else
371378 msg=" parameter types differ" ;
379+ }
372380
381+ if (conclusive)
373382 break ;
374- }
375383 }
376384 }
377385 }
378386 else
387+ {
379388 msg=" conflict on POD" ;
389+ conclusive = true ;
390+ }
380391
381- if (!msg.empty ())
392+ if (conclusive && !msg.empty ())
382393 {
383394 error () << ' \n ' ;
384395 error () << " reason for conflict at "
@@ -392,6 +403,8 @@ void linkingt::detailed_conflict_report_rec(
392403 #ifdef DEBUG
393404 debug () << " <END DEPTH " << depth << " >" << eom;
394405 #endif
406+
407+ return conclusive;
395408}
396409
397410void linkingt::link_error (
@@ -685,8 +698,16 @@ void linkingt::duplicate_code_symbol(
685698 old_symbol.value .is_nil ()!=new_symbol.value .is_nil ())
686699 {
687700 if (warn_msg.empty ())
701+ {
688702 warn_msg=" pointer parameter types differ between "
689703 " declaration and definition" ;
704+ detailed_conflict_report (
705+ old_symbol,
706+ new_symbol,
707+ conflicts.front ().first ,
708+ conflicts.front ().second );
709+ }
710+
690711 replace=new_symbol.value .is_not_nil ();
691712 }
692713 // transparent union with (or entirely without) implementation is
0 commit comments