10
10
// / ANSI-C Linking
11
11
12
12
#include " linking.h"
13
-
14
- #include < deque>
15
- #include < unordered_set>
13
+ #include " linking_class.h"
16
14
17
15
#include < util/base_type.h>
18
16
#include < util/c_types.h>
21
19
#include < util/pointer_expr.h>
22
20
#include < util/pointer_offset_size.h>
23
21
#include < util/simplify_expr.h>
22
+ #include < util/std_code.h>
24
23
#include < util/symbol_table.h>
25
24
26
25
#include < langapi/language_util.h>
27
26
28
- #include " linking_class.h"
27
+ #include < deque>
28
+
29
+ bool casting_replace_symbolt::replace (exprt &dest) const
30
+ {
31
+ bool result = true ; // unchanged
32
+
33
+ // first look at type
34
+
35
+ const exprt &const_dest (dest);
36
+ if (have_to_replace (const_dest.type ()))
37
+ if (!replace_symbolt::replace (dest.type ()))
38
+ result = false ;
39
+
40
+ // now do expression itself
41
+
42
+ if (!have_to_replace (dest))
43
+ return result;
44
+
45
+ if (dest.id () == ID_side_effect)
46
+ {
47
+ if (auto call = expr_try_dynamic_cast<side_effect_expr_function_callt>(dest))
48
+ {
49
+ if (!have_to_replace (call->function ()))
50
+ return replace_symbolt::replace (dest);
51
+
52
+ exprt before = dest;
53
+ code_typet type = to_code_type (call->function ().type ());
54
+
55
+ result &= replace_symbolt::replace (call->function ());
56
+
57
+ // maybe add type casts here?
58
+ for (auto &arg : call->arguments ())
59
+ result &= replace_symbolt::replace (arg);
60
+
61
+ if (
62
+ type.return_type () !=
63
+ to_code_type (call->function ().type ()).return_type ())
64
+ {
65
+ call->type () = to_code_type (call->function ().type ()).return_type ();
66
+ dest = typecast_exprt (*call, type.return_type ());
67
+ result = true ;
68
+ }
69
+
70
+ return result;
71
+ }
72
+ }
73
+ else if (dest.id () == ID_address_of)
74
+ {
75
+ pointer_typet ptr_type = to_pointer_type (dest.type ());
76
+
77
+ result &= replace_symbolt::replace (dest);
78
+
79
+ address_of_exprt address_of = to_address_of_expr (dest);
80
+ if (address_of.object ().type () != ptr_type.subtype ())
81
+ {
82
+ to_pointer_type (address_of.type ()).subtype () = address_of.object ().type ();
83
+ dest = typecast_exprt (address_of, ptr_type);
84
+ result = true ;
85
+ }
86
+
87
+ return result;
88
+ }
89
+
90
+ return replace_symbolt::replace (dest);
91
+ }
29
92
30
93
bool casting_replace_symbolt::replace_symbol_expr (symbol_exprt &s) const
31
94
{
@@ -36,7 +99,7 @@ bool casting_replace_symbolt::replace_symbol_expr(symbol_exprt &s) const
36
99
37
100
const exprt &e = it->second ;
38
101
39
- if (e.type ().id () != ID_array)
102
+ if (e.type ().id () != ID_array && e. type (). id () != ID_code )
40
103
{
41
104
typet type = s.type ();
42
105
static_cast <exprt &>(s) = typecast_exprt::conditional_cast (e, type);
@@ -491,22 +554,9 @@ void linkingt::duplicate_code_symbol(
491
554
const code_typet &old_t =to_code_type (old_symbol.type );
492
555
const code_typet &new_t =to_code_type (new_symbol.type );
493
556
494
- // if one of them was an implicit declaration then only conflicts on the
495
- // return type are an error as we would end up with assignments with
496
- // mismatching types; as we currently do not patch these by inserting type
497
- // casts we need to fail hard
498
557
if (old_symbol.type .get_bool (ID_C_incomplete) && old_symbol.value .is_nil ())
499
558
{
500
- if (base_type_eq (old_t .return_type (), new_t .return_type (), ns))
501
- link_warning (
502
- old_symbol,
503
- new_symbol,
504
- " implicit function declaration" );
505
- else
506
- link_error (
507
- old_symbol,
508
- new_symbol,
509
- " implicit function declaration" );
559
+ link_warning (old_symbol, new_symbol, " implicit function declaration" );
510
560
511
561
old_symbol.type =new_symbol.type ;
512
562
old_symbol.location =new_symbol.location ;
@@ -515,24 +565,15 @@ void linkingt::duplicate_code_symbol(
515
565
else if (
516
566
new_symbol.type .get_bool (ID_C_incomplete) && new_symbol.value .is_nil ())
517
567
{
518
- if (base_type_eq (old_t .return_type (), new_t .return_type (), ns))
519
- link_warning (
520
- old_symbol,
521
- new_symbol,
522
- " ignoring conflicting implicit function declaration" );
523
- else
524
- link_error (
525
- old_symbol,
526
- new_symbol,
527
- " implicit function declaration" );
568
+ link_warning (
569
+ old_symbol,
570
+ new_symbol,
571
+ " ignoring conflicting implicit function declaration" );
528
572
}
529
573
// handle (incomplete) function prototypes
530
- else if (base_type_eq (old_t .return_type (), new_t .return_type (), ns) &&
531
- ((old_t .parameters ().empty () &&
532
- old_t .has_ellipsis () &&
574
+ else if (((old_t .parameters ().empty () && old_t .has_ellipsis () &&
533
575
old_symbol.value .is_nil ()) ||
534
- (new_t .parameters ().empty () &&
535
- new_t .has_ellipsis () &&
576
+ (new_t .parameters ().empty () && new_t .has_ellipsis () &&
536
577
new_symbol.value .is_nil ())))
537
578
{
538
579
if (old_t .parameters ().empty () &&
@@ -583,9 +624,7 @@ void linkingt::duplicate_code_symbol(
583
624
}
584
625
// conflicting declarations without a definition, matching return
585
626
// types
586
- else if (base_type_eq (old_t .return_type (), new_t .return_type (), ns) &&
587
- old_symbol.value .is_nil () &&
588
- new_symbol.value .is_nil ())
627
+ else if (old_symbol.value .is_nil () && new_symbol.value .is_nil ())
589
628
{
590
629
link_warning (
591
630
old_symbol,
@@ -625,8 +664,11 @@ void linkingt::duplicate_code_symbol(
625
664
conflictst conflicts;
626
665
627
666
if (!base_type_eq (old_t .return_type (), new_t .return_type (), ns))
628
- conflicts.push_back (
629
- std::make_pair (old_t .return_type (), new_t .return_type ()));
667
+ {
668
+ link_warning (old_symbol, new_symbol, " conflicting return types" );
669
+
670
+ conflicts.emplace_back (old_t .return_type (), new_t .return_type ());
671
+ }
630
672
631
673
code_typet::parameterst::const_iterator
632
674
n_it=new_t .parameters ().begin (),
@@ -676,21 +718,11 @@ void linkingt::duplicate_code_symbol(
676
718
const typet &t1=follow_tags_symbols (ns, conflicts.front ().first );
677
719
const typet &t2=follow_tags_symbols (ns, conflicts.front ().second );
678
720
679
- // void vs. non-void return type may be acceptable if the
680
- // return value is never used
681
- if ((t1.id ()==ID_empty || t2.id ()==ID_empty) &&
682
- (old_symbol.value .is_nil () || new_symbol.value .is_nil ()))
683
- {
684
- if (warn_msg.empty ())
685
- warn_msg=" void/non-void return type conflict on function" ;
686
- replace=
687
- new_symbol.value .is_not_nil () ||
688
- (old_symbol.value .is_nil () && t2.id ()==ID_empty);
689
- }
690
721
// different pointer arguments without implementation may work
691
- else if ((t1.id ()==ID_pointer || t2.id ()==ID_pointer) &&
692
- pointer_offset_bits (t1, ns)==pointer_offset_bits (t2, ns) &&
693
- old_symbol.value .is_nil () && new_symbol.value .is_nil ())
722
+ if (
723
+ (t1.id () == ID_pointer || t2.id () == ID_pointer) &&
724
+ pointer_offset_bits (t1, ns) == pointer_offset_bits (t2, ns) &&
725
+ old_symbol.value .is_nil () && new_symbol.value .is_nil ())
694
726
{
695
727
if (warn_msg.empty ())
696
728
warn_msg=" different pointer types in extern function" ;
@@ -793,6 +825,9 @@ void linkingt::duplicate_code_symbol(
793
825
}
794
826
}
795
827
}
828
+
829
+ object_type_updates.insert (
830
+ old_symbol.symbol_expr (), old_symbol.symbol_expr ());
796
831
}
797
832
798
833
if (!new_symbol.value .is_nil ())
@@ -807,6 +842,11 @@ void linkingt::duplicate_code_symbol(
807
842
old_symbol.is_weak =new_symbol.is_weak ;
808
843
old_symbol.location =new_symbol.location ;
809
844
old_symbol.is_macro =new_symbol.is_macro ;
845
+
846
+ // replace any previous update
847
+ object_type_updates.erase (old_symbol.name );
848
+ object_type_updates.insert (
849
+ old_symbol.symbol_expr (), old_symbol.symbol_expr ());
810
850
}
811
851
else if (to_code_type (old_symbol.type ).get_inlined ())
812
852
{
0 commit comments