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);
@@ -491,22 +556,9 @@ void linkingt::duplicate_code_symbol(
491
556
const code_typet &old_t =to_code_type (old_symbol.type );
492
557
const code_typet &new_t =to_code_type (new_symbol.type );
493
558
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
559
if (old_symbol.type .get_bool (ID_C_incomplete) && old_symbol.value .is_nil ())
499
560
{
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" );
561
+ link_warning (old_symbol, new_symbol, " implicit function declaration" );
510
562
511
563
old_symbol.type =new_symbol.type ;
512
564
old_symbol.location =new_symbol.location ;
@@ -515,24 +567,15 @@ void linkingt::duplicate_code_symbol(
515
567
else if (
516
568
new_symbol.type .get_bool (ID_C_incomplete) && new_symbol.value .is_nil ())
517
569
{
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" );
570
+ link_warning (
571
+ old_symbol,
572
+ new_symbol,
573
+ " ignoring conflicting implicit function declaration" );
528
574
}
529
575
// 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 () &&
576
+ else if (((old_t .parameters ().empty () && old_t .has_ellipsis () &&
533
577
old_symbol.value .is_nil ()) ||
534
- (new_t .parameters ().empty () &&
535
- new_t .has_ellipsis () &&
578
+ (new_t .parameters ().empty () && new_t .has_ellipsis () &&
536
579
new_symbol.value .is_nil ())))
537
580
{
538
581
if (old_t .parameters ().empty () &&
@@ -583,9 +626,7 @@ void linkingt::duplicate_code_symbol(
583
626
}
584
627
// conflicting declarations without a definition, matching return
585
628
// 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 ())
629
+ else if (old_symbol.value .is_nil () && new_symbol.value .is_nil ())
589
630
{
590
631
link_warning (
591
632
old_symbol,
@@ -625,8 +666,11 @@ void linkingt::duplicate_code_symbol(
625
666
conflictst conflicts;
626
667
627
668
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 ()));
669
+ {
670
+ link_warning (old_symbol, new_symbol, " conflicting return types" );
671
+
672
+ conflicts.emplace_back (old_t .return_type (), new_t .return_type ());
673
+ }
630
674
631
675
code_typet::parameterst::const_iterator
632
676
n_it=new_t .parameters ().begin (),
@@ -676,21 +720,11 @@ void linkingt::duplicate_code_symbol(
676
720
const typet &t1=follow_tags_symbols (ns, conflicts.front ().first );
677
721
const typet &t2=follow_tags_symbols (ns, conflicts.front ().second );
678
722
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
723
// 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 ())
724
+ if (
725
+ (t1.id () == ID_pointer || t2.id () == ID_pointer) &&
726
+ pointer_offset_bits (t1, ns) == pointer_offset_bits (t2, ns) &&
727
+ old_symbol.value .is_nil () && new_symbol.value .is_nil ())
694
728
{
695
729
if (warn_msg.empty ())
696
730
warn_msg=" different pointer types in extern function" ;
@@ -793,6 +827,9 @@ void linkingt::duplicate_code_symbol(
793
827
}
794
828
}
795
829
}
830
+
831
+ object_type_updates.insert (
832
+ old_symbol.symbol_expr (), old_symbol.symbol_expr ());
796
833
}
797
834
798
835
if (!new_symbol.value .is_nil ())
@@ -807,6 +844,11 @@ void linkingt::duplicate_code_symbol(
807
844
old_symbol.is_weak =new_symbol.is_weak ;
808
845
old_symbol.location =new_symbol.location ;
809
846
old_symbol.is_macro =new_symbol.is_macro ;
847
+
848
+ // replace any previous update
849
+ object_type_updates.erase (old_symbol.name );
850
+ object_type_updates.insert (
851
+ old_symbol.symbol_expr (), old_symbol.symbol_expr ());
810
852
}
811
853
else if (to_code_type (old_symbol.type ).get_inlined ())
812
854
{
0 commit comments