21
21
#include < util/pointer_expr.h>
22
22
#include < util/pointer_offset_size.h>
23
23
#include < util/simplify_expr.h>
24
+ #include < util/std_code.h>
24
25
#include < util/symbol_table.h>
25
26
26
27
#include < langapi/language_util.h>
27
28
28
29
#include " linking_class.h"
29
30
31
+ bool casting_replace_symbolt::replace (exprt &dest) const
32
+ {
33
+ bool result = true ; // unchanged
34
+
35
+ // first look at type
36
+
37
+ const exprt &const_dest (dest);
38
+ if (have_to_replace (const_dest.type ()))
39
+ if (!replace_symbolt::replace (dest.type ()))
40
+ result = false ;
41
+
42
+ // now do expression itself
43
+
44
+ if (!have_to_replace (dest))
45
+ return result;
46
+
47
+ if (dest.id () == ID_side_effect)
48
+ {
49
+ if (auto call = expr_try_dynamic_cast<side_effect_expr_function_callt>(dest))
50
+ {
51
+ if (!have_to_replace (call->function ()))
52
+ return replace_symbolt::replace (dest);
53
+
54
+ exprt before = dest;
55
+ code_typet type = to_code_type (call->function ().type ());
56
+
57
+ result &= replace_symbolt::replace (call->function ());
58
+
59
+ // maybe add type casts here?
60
+ for (auto &arg : call->arguments ())
61
+ result &= replace_symbolt::replace (arg);
62
+
63
+ if (
64
+ type.return_type () !=
65
+ to_code_type (call->function ().type ()).return_type ())
66
+ {
67
+ call->type () = to_code_type (call->function ().type ()).return_type ();
68
+ dest = typecast_exprt (*call, type.return_type ());
69
+ result = true ;
70
+ }
71
+
72
+ return result;
73
+ }
74
+ }
75
+ else if (dest.id () == ID_address_of)
76
+ {
77
+ pointer_typet ptr_type = to_pointer_type (dest.type ());
78
+
79
+ result &= replace_symbolt::replace (dest);
80
+
81
+ address_of_exprt address_of = to_address_of_expr (dest);
82
+ if (address_of.object ().type () != ptr_type.subtype ())
83
+ {
84
+ to_pointer_type (address_of.type ()).subtype () = address_of.object ().type ();
85
+ dest = typecast_exprt (address_of, ptr_type);
86
+ result = true ;
87
+ }
88
+
89
+ return result;
90
+ }
91
+
92
+ return replace_symbolt::replace (dest);
93
+ }
94
+
30
95
bool casting_replace_symbolt::replace_symbol_expr (symbol_exprt &s) const
31
96
{
32
97
expr_mapt::const_iterator it = expr_map.find (s.get_identifier ());
@@ -36,7 +101,7 @@ bool casting_replace_symbolt::replace_symbol_expr(symbol_exprt &s) const
36
101
37
102
const exprt &e = it->second ;
38
103
39
- if (e.type ().id () != ID_array)
104
+ if (e.type ().id () != ID_array && e. type (). id () != ID_code )
40
105
{
41
106
typet type = s.type ();
42
107
static_cast <exprt &>(s) = typecast_exprt::conditional_cast (e, type);
@@ -480,22 +545,9 @@ void linkingt::duplicate_code_symbol(
480
545
const code_typet &old_t =to_code_type (old_symbol.type );
481
546
const code_typet &new_t =to_code_type (new_symbol.type );
482
547
483
- // if one of them was an implicit declaration then only conflicts on the
484
- // return type are an error as we would end up with assignments with
485
- // mismatching types; as we currently do not patch these by inserting type
486
- // casts we need to fail hard
487
548
if (old_symbol.type .get_bool (ID_C_incomplete) && old_symbol.value .is_nil ())
488
549
{
489
- if (base_type_eq (old_t .return_type (), new_t .return_type (), ns))
490
- link_warning (
491
- old_symbol,
492
- new_symbol,
493
- " implicit function declaration" );
494
- else
495
- link_error (
496
- old_symbol,
497
- new_symbol,
498
- " implicit function declaration" );
550
+ link_warning (old_symbol, new_symbol, " implicit function declaration" );
499
551
500
552
old_symbol.type =new_symbol.type ;
501
553
old_symbol.location =new_symbol.location ;
@@ -504,24 +556,15 @@ void linkingt::duplicate_code_symbol(
504
556
else if (
505
557
new_symbol.type .get_bool (ID_C_incomplete) && new_symbol.value .is_nil ())
506
558
{
507
- if (base_type_eq (old_t .return_type (), new_t .return_type (), ns))
508
- link_warning (
509
- old_symbol,
510
- new_symbol,
511
- " ignoring conflicting implicit function declaration" );
512
- else
513
- link_error (
514
- old_symbol,
515
- new_symbol,
516
- " implicit function declaration" );
559
+ link_warning (
560
+ old_symbol,
561
+ new_symbol,
562
+ " ignoring conflicting implicit function declaration" );
517
563
}
518
564
// handle (incomplete) function prototypes
519
- else if (base_type_eq (old_t .return_type (), new_t .return_type (), ns) &&
520
- ((old_t .parameters ().empty () &&
521
- old_t .has_ellipsis () &&
565
+ else if (((old_t .parameters ().empty () && old_t .has_ellipsis () &&
522
566
old_symbol.value .is_nil ()) ||
523
- (new_t .parameters ().empty () &&
524
- new_t .has_ellipsis () &&
567
+ (new_t .parameters ().empty () && new_t .has_ellipsis () &&
525
568
new_symbol.value .is_nil ())))
526
569
{
527
570
if (old_t .parameters ().empty () &&
@@ -572,9 +615,7 @@ void linkingt::duplicate_code_symbol(
572
615
}
573
616
// conflicting declarations without a definition, matching return
574
617
// types
575
- else if (base_type_eq (old_t .return_type (), new_t .return_type (), ns) &&
576
- old_symbol.value .is_nil () &&
577
- new_symbol.value .is_nil ())
618
+ else if (old_symbol.value .is_nil () && new_symbol.value .is_nil ())
578
619
{
579
620
link_warning (
580
621
old_symbol,
@@ -614,8 +655,11 @@ void linkingt::duplicate_code_symbol(
614
655
conflictst conflicts;
615
656
616
657
if (!base_type_eq (old_t .return_type (), new_t .return_type (), ns))
617
- conflicts.push_back (
618
- std::make_pair (old_t .return_type (), new_t .return_type ()));
658
+ {
659
+ link_warning (old_symbol, new_symbol, " conflicting return types" );
660
+
661
+ conflicts.emplace_back (old_t .return_type (), new_t .return_type ());
662
+ }
619
663
620
664
code_typet::parameterst::const_iterator
621
665
n_it=new_t .parameters ().begin (),
@@ -665,21 +709,11 @@ void linkingt::duplicate_code_symbol(
665
709
const typet &t1=follow_tags_symbols (ns, conflicts.front ().first );
666
710
const typet &t2=follow_tags_symbols (ns, conflicts.front ().second );
667
711
668
- // void vs. non-void return type may be acceptable if the
669
- // return value is never used
670
- if ((t1.id ()==ID_empty || t2.id ()==ID_empty) &&
671
- (old_symbol.value .is_nil () || new_symbol.value .is_nil ()))
672
- {
673
- if (warn_msg.empty ())
674
- warn_msg=" void/non-void return type conflict on function" ;
675
- replace=
676
- new_symbol.value .is_not_nil () ||
677
- (old_symbol.value .is_nil () && t2.id ()==ID_empty);
678
- }
679
712
// different pointer arguments without implementation may work
680
- else if ((t1.id ()==ID_pointer || t2.id ()==ID_pointer) &&
681
- pointer_offset_bits (t1, ns)==pointer_offset_bits (t2, ns) &&
682
- old_symbol.value .is_nil () && new_symbol.value .is_nil ())
713
+ if (
714
+ (t1.id () == ID_pointer || t2.id () == ID_pointer) &&
715
+ pointer_offset_bits (t1, ns) == pointer_offset_bits (t2, ns) &&
716
+ old_symbol.value .is_nil () && new_symbol.value .is_nil ())
683
717
{
684
718
if (warn_msg.empty ())
685
719
warn_msg=" different pointer types in extern function" ;
@@ -782,6 +816,9 @@ void linkingt::duplicate_code_symbol(
782
816
}
783
817
}
784
818
}
819
+
820
+ object_type_updates.insert (
821
+ old_symbol.symbol_expr (), old_symbol.symbol_expr ());
785
822
}
786
823
787
824
if (!new_symbol.value .is_nil ())
@@ -796,6 +833,11 @@ void linkingt::duplicate_code_symbol(
796
833
old_symbol.is_weak =new_symbol.is_weak ;
797
834
old_symbol.location =new_symbol.location ;
798
835
old_symbol.is_macro =new_symbol.is_macro ;
836
+
837
+ // replace any previous update
838
+ object_type_updates.erase (old_symbol.name );
839
+ object_type_updates.insert (
840
+ old_symbol.symbol_expr (), old_symbol.symbol_expr ());
799
841
}
800
842
else if (to_code_type (old_symbol.type ).get_inlined ())
801
843
{
0 commit comments