@@ -129,7 +129,7 @@ std::string linkingt::type_to_string_verbose(
129
129
130
130
/* ******************************************************************\
131
131
132
- Function: linkingt::link_error
132
+ Function: linkingt::detailed_conflict_report
133
133
134
134
Inputs:
135
135
@@ -139,37 +139,192 @@ Function: linkingt::link_error
139
139
140
140
\*******************************************************************/
141
141
142
- void linkingt::show_struct_diff (
143
- const struct_typet &old_type, const struct_typet &new_type)
142
+ void linkingt::detailed_conflict_report_rec (
143
+ const symbolt &old_symbol,
144
+ const symbolt &new_symbol,
145
+ const typet &type1,
146
+ const typet &type2,
147
+ unsigned depth,
148
+ exprt &conflict_path)
144
149
{
145
- if (old_type.components ().size ()!=new_type.components ().size ())
146
- str << " number of members is different" ;
147
- else
150
+ #ifdef DEBUG
151
+ str << " <BEGIN DEPTH " << depth << " >" ;
152
+ debug ();
153
+ #endif
154
+
155
+ std::string msg;
156
+
157
+ const typet &t1=ns.follow (type1);
158
+ const typet &t2=ns.follow (type2);
159
+
160
+ if (t1.id ()!=t2.id ())
161
+ msg=" type classes differ" ;
162
+ else if (t1.id ()==ID_pointer ||
163
+ t1.id ()==ID_array)
164
+ {
165
+ if (depth>0 &&
166
+ !base_type_eq (t1.subtype (), t2.subtype (), ns))
167
+ {
168
+ conflict_path=dereference_exprt (conflict_path);
169
+
170
+ detailed_conflict_report_rec (
171
+ old_symbol,
172
+ new_symbol,
173
+ t1.subtype (),
174
+ t2.subtype (),
175
+ depth-1 ,
176
+ conflict_path);
177
+ }
178
+ else if (t1.id ()==ID_pointer)
179
+ msg=" pointer types differ" ;
180
+ else
181
+ msg=" array types differ" ;
182
+ }
183
+ else if (t1.id ()==ID_struct ||
184
+ t1.id ()==ID_union)
148
185
{
149
- for (unsigned i=0 ; i<old_type.components ().size (); i++)
186
+ const struct_union_typet::componentst &components1=
187
+ to_struct_union_type (t1).components ();
188
+
189
+ const struct_union_typet::componentst &components2=
190
+ to_struct_union_type (t2).components ();
191
+
192
+ if (components1.size ()!=components2.size ())
150
193
{
151
- if (old_type.components ()[i].get_name ()!=new_type.components ()[i].get_name ())
194
+ msg=" number of members is different (" ;
195
+ msg+=i2string (components1.size ())+' /' ;
196
+ msg+=i2string (components2.size ())+' )' ;
197
+ }
198
+ else
199
+ for (std::size_t i=0 ; i<components1.size (); ++i)
152
200
{
153
- str << " name of member differs: "
154
- << old_type.components ()[i].get_name () << " vs. "
155
- << new_type.components ()[i].get_name ();
156
- break ;
201
+ const typet &subtype1=components1[i].type ();
202
+ const typet &subtype2=components2[i].type ();
203
+
204
+ if (components1[i].get_name ()!=components2[i].get_name ())
205
+ {
206
+ msg=" names of member " +i2string (i)+" differ (" ;
207
+ msg+=id2string (components1[i].get_name ())+' /' ;
208
+ msg+=id2string (components2[i].get_name ())+' )' ;
209
+ break ;
210
+ }
211
+ else if (!base_type_eq (subtype1, subtype2, ns))
212
+ {
213
+ conflict_path.type ()=t1;
214
+ conflict_path=
215
+ member_exprt (conflict_path, components1[i].get_name ());
216
+
217
+ if (depth>0 )
218
+ detailed_conflict_report_rec (
219
+ old_symbol,
220
+ new_symbol,
221
+ subtype1,
222
+ subtype2,
223
+ depth-1 ,
224
+ conflict_path);
225
+ else
226
+ msg=" type of member " +
227
+ id2string (components1[i].get_name ())+
228
+ " differs" ;
229
+
230
+ break ;
231
+ }
157
232
}
158
-
159
- if (!base_type_eq (old_type.components ()[i].type (), new_type.components ()[i].type (), ns))
233
+ }
234
+ else if (t1.id ()==ID_code)
235
+ {
236
+ const code_typet::parameterst ¶meters1=
237
+ to_code_type (t1).parameters ();
238
+
239
+ const code_typet::parameterst ¶meters2=
240
+ to_code_type (t2).parameters ();
241
+
242
+ const typet &return_type1=to_code_type (t1).return_type ();
243
+ const typet &return_type2=to_code_type (t2).return_type ();
244
+
245
+ if (parameters1.size ()!=parameters2.size ())
246
+ {
247
+ msg=" parameter counts differ (" ;
248
+ msg+=i2string (parameters1.size ())+' /' ;
249
+ msg+=i2string (parameters2.size ())+' )' ;
250
+ }
251
+ else if (!base_type_eq (return_type1, return_type2, ns))
252
+ {
253
+ conflict_path=
254
+ index_exprt (conflict_path,
255
+ constant_exprt (i2string (-1 ), integer_typet ()));
256
+
257
+ if (depth>0 )
258
+ detailed_conflict_report_rec (
259
+ old_symbol,
260
+ new_symbol,
261
+ return_type1,
262
+ return_type2,
263
+ depth-1 ,
264
+ conflict_path);
265
+ else
266
+ msg=" return types differ" ;
267
+ }
268
+ else
269
+ for (std::size_t i=0 ; i<parameters1.size (); i++)
160
270
{
161
- str << " type of member "
162
- << old_type.components ()[i].get_name () << " differs: "
163
- << type_to_string (ns, " " , old_type.components ()[i].type ()) << " vs. "
164
- << type_to_string (ns, " " , new_type.components ()[i].type ());
165
- str << " \n " << old_type.components ()[i].type ().pretty () << " \n " ;
166
- str << " \n " << new_type.components ()[i].type ().pretty () << " \n " ;
167
- break ;
271
+ const typet &subtype1=parameters1[i].type ();
272
+ const typet &subtype2=parameters2[i].type ();
273
+
274
+ if (!base_type_eq (subtype1, subtype2, ns))
275
+ {
276
+ conflict_path=
277
+ index_exprt (conflict_path,
278
+ constant_exprt (i2string (i), integer_typet ()));
279
+
280
+ if (depth>0 )
281
+ detailed_conflict_report_rec (
282
+ old_symbol,
283
+ new_symbol,
284
+ subtype1,
285
+ subtype2,
286
+ depth-1 ,
287
+ conflict_path);
288
+ else
289
+ msg=" parameter types differ" ;
290
+
291
+ break ;
292
+ }
168
293
}
169
- }
170
294
}
295
+ else
296
+ msg=" conflict on POD" ;
297
+
298
+ if (!msg.empty ())
299
+ {
300
+ str << std::endl;
301
+ str << " reason for conflict at "
302
+ << expr_to_string (ns, " " , conflict_path)
303
+ << " : " << msg << std::endl;
304
+
305
+ str << std::endl;
306
+ str << type_to_string_verbose (ns, old_symbol, t1) << std::endl;
307
+ str << type_to_string_verbose (ns, new_symbol, t2) << std::endl;
308
+ }
309
+
310
+ #ifdef DEBUG
311
+ str << " <END DEPTH " << depth << " >" ;
312
+ debug ();
313
+ #endif
171
314
}
172
315
316
+ /* ******************************************************************\
317
+
318
+ Function: linkingt::link_error
319
+
320
+ Inputs:
321
+
322
+ Outputs:
323
+
324
+ Purpose:
325
+
326
+ \*******************************************************************/
327
+
173
328
void linkingt::link_error (
174
329
const symbolt &old_symbol,
175
330
const symbolt &new_symbol,
@@ -187,15 +342,6 @@ void linkingt::link_error(
187
342
<< " ' " << new_symbol.location << " \n "
188
343
<< type_to_string_verbose (ns, new_symbol);
189
344
190
- if (ns.follow (old_symbol.type ).id ()==ID_struct &&
191
- ns.follow (new_symbol.type ).id ()==ID_struct)
192
- {
193
- str << " \n " ;
194
- str << " Difference between struct types:\n " ;
195
- show_struct_diff (to_struct_type (ns.follow (old_symbol.type )),
196
- to_struct_type (ns.follow (new_symbol.type )));
197
- }
198
-
199
345
throw 0 ;
200
346
}
201
347
@@ -224,7 +370,7 @@ void linkingt::link_warning(
224
370
<< type_to_string_verbose (ns, old_symbol) << std::endl;
225
371
str << " new definition in module " << new_symbol.module
226
372
<< " " << new_symbol.location << std::endl
227
- << type_to_string_verbose (ns, new_symbol);
373
+ << type_to_string_verbose (ns, new_symbol) << std::endl ;
228
374
229
375
warning_msg ();
230
376
}
@@ -457,10 +603,18 @@ void linkingt::duplicate_code_symbol(
457
603
}
458
604
459
605
if (!conflicts.empty ())
606
+ {
607
+ detailed_conflict_report (
608
+ old_symbol,
609
+ new_symbol,
610
+ conflicts.front ().first ,
611
+ conflicts.front ().second );
612
+
460
613
link_error (
461
614
old_symbol,
462
615
new_symbol,
463
616
" conflicting function declarations" );
617
+ }
464
618
else
465
619
{
466
620
// warns about the first inconsistency
@@ -494,7 +648,7 @@ void linkingt::duplicate_code_symbol(
494
648
// keep the one in old_symbol -- libraries come last!
495
649
str << " warning: function `" << old_symbol.name << " ' in module `" <<
496
650
new_symbol.module << " ' is shadowed by a definition in module `" <<
497
- old_symbol.module << " '" ;
651
+ old_symbol.module << " '" << std::endl ;
498
652
warning_msg ();
499
653
}
500
654
else
@@ -582,6 +736,16 @@ void linkingt::duplicate_object_symbol(
582
736
}
583
737
else
584
738
{
739
+ // provide additional diagnostic output for struct/union/array
740
+ if (old_type.id ()==ID_struct ||
741
+ old_type.id ()==ID_union ||
742
+ old_type.id ()==ID_array)
743
+ detailed_conflict_report (
744
+ old_symbol,
745
+ new_symbol,
746
+ old_symbol.type ,
747
+ new_symbol.type );
748
+
585
749
link_error (
586
750
old_symbol,
587
751
new_symbol,
@@ -749,6 +913,12 @@ void linkingt::duplicate_type_symbol(
749
913
}
750
914
}
751
915
916
+ detailed_conflict_report (
917
+ old_symbol,
918
+ new_symbol,
919
+ old_symbol.type ,
920
+ new_symbol.type );
921
+
752
922
link_error (
753
923
old_symbol,
754
924
new_symbol,
0 commit comments