16
16
#include < util/std_expr.h>
17
17
#include < util/std_types.h>
18
18
#include < util/simplify_expr.h>
19
+ #include < util/pointer_offset_size.h>
19
20
20
21
#include < langapi/language_util.h>
21
22
@@ -619,26 +620,31 @@ void linkingt::duplicate_code_symbol(
619
620
" ignoring conflicting weak function declaration" );
620
621
}
621
622
}
622
- // Linux kernel uses void f(void) as generic prototype
623
- else if ((old_t .return_type ().id ()==ID_empty &&
624
- old_t .parameters ().empty () &&
625
- !old_t .has_ellipsis () &&
623
+ // aliasing may alter the type
624
+ else if ((new_symbol.is_macro &&
625
+ new_symbol.value .is_not_nil () &&
626
626
old_symbol.value .is_nil ()) ||
627
- (new_t .return_type ().id ()==ID_empty &&
628
- new_t .parameters ().empty () &&
629
- !new_t .has_ellipsis () &&
627
+ (old_symbol.is_macro &&
628
+ old_symbol.value .is_not_nil () &&
630
629
new_symbol.value .is_nil ()))
631
630
{
632
- // issue a warning
633
631
link_warning (
634
632
old_symbol,
635
633
new_symbol,
636
- " ignoring conflicting void f(void) function declaration" );
634
+ " ignoring conflicting function alias declaration" );
635
+ }
636
+ // conflicting declarations without a definition, matching return
637
+ // types
638
+ else if (base_type_eq (old_t .return_type (), new_t .return_type (), ns) &&
639
+ old_symbol.value .is_nil () &&
640
+ new_symbol.value .is_nil ())
641
+ {
642
+ link_warning (
643
+ old_symbol,
644
+ new_symbol,
645
+ " ignoring conflicting function declarations" );
637
646
638
- if (old_t .return_type ().id ()==ID_empty &&
639
- old_t .parameters ().empty () &&
640
- !old_t .has_ellipsis () &&
641
- old_symbol.value .is_nil ())
647
+ if (old_t .parameters ().size ()<new_t .parameters ().size ())
642
648
{
643
649
old_symbol.type =new_symbol.type ;
644
650
old_symbol.location =new_symbol.location ;
@@ -647,8 +653,10 @@ void linkingt::duplicate_code_symbol(
647
653
}
648
654
// mismatch on number of parameters is definitively an error
649
655
else if ((old_t .parameters ().size ()<new_t .parameters ().size () &&
656
+ new_symbol.value .is_not_nil () &&
650
657
!old_t .has_ellipsis ()) ||
651
658
(old_t .parameters ().size ()>new_t .parameters ().size () &&
659
+ old_symbol.value .is_not_nil () &&
652
660
!new_t .has_ellipsis ()))
653
661
{
654
662
link_error (
@@ -683,12 +691,20 @@ void linkingt::duplicate_code_symbol(
683
691
}
684
692
if (o_it!=old_t .parameters ().end ())
685
693
{
686
- assert (new_t .has_ellipsis ());
694
+ if (!new_t .has_ellipsis () && old_symbol.value .is_not_nil ())
695
+ link_error (
696
+ old_symbol,
697
+ new_symbol,
698
+ " conflicting parameter counts of function declarations" );
687
699
replace=new_symbol.value .is_not_nil ();
688
700
}
689
701
else if (n_it!=new_t .parameters ().end ())
690
702
{
691
- assert (old_t .has_ellipsis ());
703
+ if (!old_t .has_ellipsis () && new_symbol.value .is_not_nil ())
704
+ link_error (
705
+ old_symbol,
706
+ new_symbol,
707
+ " conflicting parameter counts of function declarations" );
692
708
replace=new_symbol.value .is_not_nil ();
693
709
}
694
710
@@ -709,7 +725,8 @@ void linkingt::duplicate_code_symbol(
709
725
(old_symbol.value .is_nil () && t2.id ()==ID_empty);
710
726
}
711
727
// different pointer arguments without implementation may work
712
- else if (t1.id ()==ID_pointer && t2.id ()==ID_pointer &&
728
+ else if ((t1.id ()==ID_pointer || t2.id ()==ID_pointer) &&
729
+ pointer_offset_bits (t1, ns)==pointer_offset_bits (t2, ns) &&
713
730
old_symbol.value .is_nil () && new_symbol.value .is_nil ())
714
731
{
715
732
if (warn_msg.empty ())
@@ -718,7 +735,8 @@ void linkingt::duplicate_code_symbol(
718
735
// different pointer arguments with implementation - the
719
736
// implementation is always right, even though such code may
720
737
// be severely broken
721
- else if (t1.id ()==ID_pointer && t2.id ()==ID_pointer &&
738
+ else if ((t1.id ()==ID_pointer || t2.id ()==ID_pointer) &&
739
+ pointer_offset_bits (t1, ns)==pointer_offset_bits (t2, ns) &&
722
740
old_symbol.value .is_nil ()!=new_symbol.value .is_nil ())
723
741
{
724
742
if (warn_msg.empty ())
@@ -828,7 +846,7 @@ void linkingt::duplicate_code_symbol(
828
846
829
847
/* ******************************************************************\
830
848
831
- Function: linkingt::duplicate_object_symbol
849
+ Function: linkingt::adjust_object_type_rec
832
850
833
851
Inputs:
834
852
@@ -838,71 +856,225 @@ Function: linkingt::duplicate_object_symbol
838
856
839
857
\*******************************************************************/
840
858
841
- void linkingt::duplicate_object_symbol (
842
- symbolt &old_symbol,
843
- symbolt &new_symbol)
859
+ bool linkingt::adjust_object_type_rec (
860
+ const typet &t1,
861
+ const typet &t2,
862
+ adjust_type_infot &info)
844
863
{
845
- // both are variables
864
+ if (base_type_eq (t1, t2, ns))
865
+ return false ;
846
866
847
- if (!base_type_eq (old_symbol.type , new_symbol.type , ns))
867
+ if (t1.id ()==ID_symbol ||
868
+ t1.id ()==ID_struct_tag ||
869
+ t1.id ()==ID_union_tag ||
870
+ t1.id ()==ID_c_enum_tag)
848
871
{
849
- const typet &old_type=ns.follow (old_symbol.type );
850
- const typet &new_type=ns.follow (new_symbol.type );
851
-
852
- if (old_type.id ()==ID_array && new_type.id ()==ID_array &&
853
- base_type_eq (old_type.subtype (), new_type.subtype (), ns))
854
- {
855
- // still need to compare size
856
- const exprt &old_size=to_array_type (old_type).size ();
857
- const exprt &new_size=to_array_type (new_type).size ();
858
-
859
- if (old_size.is_nil () && new_size.is_not_nil ())
860
- {
861
- old_symbol.type =new_symbol.type ; // store new type
862
- }
863
- else if (old_size.is_not_nil () && new_size.is_nil ())
864
- {
865
- // ok, we will use the old type
866
- }
867
- else
868
- link_error (
869
- old_symbol,
870
- new_symbol,
871
- " conflicting array sizes for variable" );
872
- }
873
- else if (old_type.id ()==ID_pointer && new_type.id ()==ID_array)
872
+ const irep_idt &identifier=t1.get (ID_identifier);
873
+
874
+ if (info.o_symbols .insert (identifier).second )
874
875
{
875
- // store new type
876
- old_symbol.type =new_symbol.type ;
876
+ bool result=
877
+ adjust_object_type_rec (follow_tags_symbols (ns, t1), t2, info);
878
+ info.o_symbols .erase (identifier);
879
+
880
+ return result;
877
881
}
878
- else if (old_type.id ()==ID_array && new_type.id ()==ID_pointer)
882
+
883
+ return false ;
884
+ }
885
+ else if (t2.id ()==ID_symbol ||
886
+ t2.id ()==ID_struct_tag ||
887
+ t2.id ()==ID_union_tag ||
888
+ t2.id ()==ID_c_enum_tag)
889
+ {
890
+ const irep_idt &identifier=t2.get (ID_identifier);
891
+
892
+ if (info.n_symbols .insert (identifier).second )
879
893
{
880
- // ignore
894
+ bool result=
895
+ adjust_object_type_rec (t1, follow_tags_symbols (ns, t2), info);
896
+ info.n_symbols .erase (identifier);
897
+
898
+ return result;
881
899
}
882
- else if (old_type.id ()==ID_pointer && new_type.id ()==ID_pointer)
900
+
901
+ return false ;
902
+ }
903
+ else if (t1.id ()==ID_pointer && t2.id ()==ID_array)
904
+ {
905
+ info.set_to_new =true ; // store new type
906
+
907
+ return false ;
908
+ }
909
+ else if (t1.id ()==ID_array && t2.id ()==ID_pointer)
910
+ {
911
+ // ignore
912
+ return false ;
913
+ }
914
+ else if ((t1.id ()==ID_incomplete_struct && t2.id ()==ID_struct) ||
915
+ (t1.id ()==ID_incomplete_union && t2.id ()==ID_union))
916
+ {
917
+ info.set_to_new =true ; // store new type
918
+
919
+ return false ;
920
+ }
921
+ else if ((t1.id ()==ID_struct && t2.id ()==ID_incomplete_struct) ||
922
+ (t1.id ()==ID_union && t2.id ()==ID_incomplete_union))
923
+ {
924
+ // ignore
925
+ return false ;
926
+ }
927
+ else if (t1.id ()!=t2.id ())
928
+ {
929
+ // type classes do not match and can't be fixed
930
+ #ifdef DEBUG
931
+ str << " LINKING: cannot join " << t1.id () << " vs. " << t2.id ();
932
+ debug_msg ();
933
+ #endif
934
+
935
+ return true ;
936
+ }
937
+
938
+ if (t1.id ()==ID_pointer)
939
+ {
940
+ #if 0
941
+ bool s=info.set_to_new;
942
+ if(adjust_object_type_rec(t1.subtype(), t2.subtype(), info))
883
943
{
884
944
link_warning(
885
- old_symbol,
886
- new_symbol,
945
+ info. old_symbol,
946
+ info. new_symbol,
887
947
"conflicting pointer types for variable");
948
+ info.set_to_new=s;
888
949
}
889
- else if ((old_type.id ()==ID_incomplete_struct &&
890
- new_type.id ()==ID_struct) ||
891
- (old_type.id ()==ID_incomplete_union &&
892
- new_type.id ()==ID_union))
950
+ #else
951
+ link_warning (
952
+ info.old_symbol ,
953
+ info.new_symbol ,
954
+ " conflicting pointer types for variable" );
955
+ #endif
956
+
957
+ return false ;
958
+ }
959
+ else if (t1.id ()==ID_array &&
960
+ !adjust_object_type_rec (t1.subtype (), t2.subtype (), info))
961
+ {
962
+ // still need to compare size
963
+ const exprt &old_size=to_array_type (t1).size ();
964
+ const exprt &new_size=to_array_type (t2).size ();
965
+
966
+ if ((old_size.is_nil () && new_size.is_not_nil ()) ||
967
+ (old_size.is_zero () && new_size.is_not_nil ()) ||
968
+ info.old_symbol .is_weak )
893
969
{
894
- // store new type
895
- old_symbol.type =new_symbol.type ;
970
+ info.set_to_new =true ; // store new type
896
971
}
897
- else if ((old_type.id ()==ID_struct &&
898
- new_type.id ()==ID_incomplete_struct) ||
899
- (old_type.id ()==ID_union &&
900
- new_type.id ()==ID_incomplete_union))
972
+ else if (new_size.is_nil () ||
973
+ new_size.is_zero () ||
974
+ info.new_symbol .is_weak )
901
975
{
902
- // ignore
976
+ // ok, we will use the old type
903
977
}
904
978
else
905
979
{
980
+ equal_exprt eq (old_size, new_size);
981
+
982
+ if (!simplify_expr (eq, ns).is_true ())
983
+ link_error (
984
+ info.old_symbol ,
985
+ info.new_symbol ,
986
+ " conflicting array sizes for variable" );
987
+ }
988
+
989
+ return false ;
990
+ }
991
+ else if (t1.id ()==ID_struct || t1.id ()==ID_union)
992
+ {
993
+ const struct_union_typet::componentst &components1=
994
+ to_struct_union_type (t1).components ();
995
+
996
+ const struct_union_typet::componentst &components2=
997
+ to_struct_union_type (t2).components ();
998
+
999
+ struct_union_typet::componentst::const_iterator
1000
+ it1=components1.begin (), it2=components2.begin ();
1001
+ for ( ;
1002
+ it1!=components1.end () && it2!=components2.end ();
1003
+ ++it1, ++it2)
1004
+ {
1005
+ if (it1->get_name ()!=it2->get_name () ||
1006
+ adjust_object_type_rec (it1->type (), it2->type (), info))
1007
+ return true ;
1008
+ }
1009
+ if (it1!=components1.end () || it2!=components2.end ())
1010
+ return true ;
1011
+
1012
+ return false ;
1013
+ }
1014
+
1015
+ return true ;
1016
+ }
1017
+
1018
+ /* ******************************************************************\
1019
+
1020
+ Function: linkingt::adjust_object_type
1021
+
1022
+ Inputs:
1023
+
1024
+ Outputs:
1025
+
1026
+ Purpose:
1027
+
1028
+ \*******************************************************************/
1029
+
1030
+ bool linkingt::adjust_object_type (
1031
+ const symbolt &old_symbol,
1032
+ const symbolt &new_symbol,
1033
+ bool &set_to_new)
1034
+ {
1035
+ #ifdef DEBUG
1036
+ str << " LINKING: trying to adjust types of " << old_symbol.name ;
1037
+ debug_msg ();
1038
+ #endif
1039
+
1040
+ const typet &old_type=follow_tags_symbols (ns, old_symbol.type );
1041
+ const typet &new_type=follow_tags_symbols (ns, new_symbol.type );
1042
+
1043
+ adjust_type_infot info (old_symbol, new_symbol);
1044
+ bool result=adjust_object_type_rec (old_type, new_type, info);
1045
+ set_to_new=info.set_to_new ;
1046
+
1047
+ return result;
1048
+ }
1049
+
1050
+ /* ******************************************************************\
1051
+
1052
+ Function: linkingt::duplicate_object_symbol
1053
+
1054
+ Inputs:
1055
+
1056
+ Outputs:
1057
+
1058
+ Purpose:
1059
+
1060
+ \*******************************************************************/
1061
+
1062
+ void linkingt::duplicate_object_symbol (
1063
+ symbolt &old_symbol,
1064
+ symbolt &new_symbol)
1065
+ {
1066
+ // both are variables
1067
+
1068
+ if (!base_type_eq (old_symbol.type , new_symbol.type , ns))
1069
+ {
1070
+ bool set_to_new=false ;
1071
+ bool failed=
1072
+ adjust_object_type (old_symbol, new_symbol, set_to_new);
1073
+
1074
+ if (failed)
1075
+ {
1076
+ const typet &old_type=follow_tags_symbols (ns, old_symbol.type );
1077
+
906
1078
// provide additional diagnostic output for
907
1079
// struct/union/array/enum
908
1080
if (old_type.id ()==ID_struct ||
@@ -920,6 +1092,8 @@ void linkingt::duplicate_object_symbol(
920
1092
new_symbol,
921
1093
" conflicting types for variable" );
922
1094
}
1095
+ else if (set_to_new)
1096
+ old_symbol.type =new_symbol.type ;
923
1097
}
924
1098
925
1099
// care about initializers
0 commit comments