@@ -808,22 +808,24 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
808
808
fn check_field_type_for_ffi (
809
809
& self ,
810
810
cache : & mut FxHashSet < Ty < ' tcx > > ,
811
+ abi : SpecAbi ,
811
812
field : & ty:: FieldDef ,
812
813
substs : SubstsRef < ' tcx > ,
813
814
) -> FfiResult < ' tcx > {
814
815
let field_ty = field. ty ( self . cx . tcx , substs) ;
815
816
if field_ty. has_opaque_types ( ) {
816
- self . check_type_for_ffi ( cache, field_ty)
817
+ self . check_type_for_ffi ( cache, abi , field_ty)
817
818
} else {
818
819
let field_ty = self . cx . tcx . normalize_erasing_regions ( self . cx . param_env , field_ty) ;
819
- self . check_type_for_ffi ( cache, field_ty)
820
+ self . check_type_for_ffi ( cache, abi , field_ty)
820
821
}
821
822
}
822
823
823
824
/// Checks if the given `VariantDef`'s field types are "ffi-safe".
824
825
fn check_variant_for_ffi (
825
826
& self ,
826
827
cache : & mut FxHashSet < Ty < ' tcx > > ,
828
+ abi : SpecAbi ,
827
829
ty : Ty < ' tcx > ,
828
830
def : & ty:: AdtDef ,
829
831
variant : & ty:: VariantDef ,
@@ -835,7 +837,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
835
837
// Can assume that only one field is not a ZST, so only check
836
838
// that field's type for FFI-safety.
837
839
if let Some ( field) = transparent_newtype_field ( self . cx . tcx , variant) {
838
- self . check_field_type_for_ffi ( cache, field, substs)
840
+ self . check_field_type_for_ffi ( cache, abi , field, substs)
839
841
} else {
840
842
bug ! ( "malformed transparent type" ) ;
841
843
}
@@ -844,7 +846,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
844
846
// actually safe.
845
847
let mut all_phantom = !variant. fields . is_empty ( ) ;
846
848
for field in & variant. fields {
847
- match self . check_field_type_for_ffi ( cache, & field, substs) {
849
+ match self . check_field_type_for_ffi ( cache, abi , & field, substs) {
848
850
FfiSafe => {
849
851
all_phantom = false ;
850
852
}
@@ -866,7 +868,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
866
868
867
869
/// Checks if the given type is "ffi-safe" (has a stable, well-defined
868
870
/// representation which can be exported to C code).
869
- fn check_type_for_ffi ( & self , cache : & mut FxHashSet < Ty < ' tcx > > , ty : Ty < ' tcx > ) -> FfiResult < ' tcx > {
871
+ fn check_type_for_ffi (
872
+ & self ,
873
+ cache : & mut FxHashSet < Ty < ' tcx > > ,
874
+ abi : SpecAbi ,
875
+ ty : Ty < ' tcx > ,
876
+ ) -> FfiResult < ' tcx > {
870
877
use FfiResult :: * ;
871
878
872
879
let tcx = self . cx . tcx ;
@@ -922,7 +929,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
922
929
} ;
923
930
}
924
931
925
- self . check_variant_for_ffi ( cache, ty, def, def. non_enum_variant ( ) , substs)
932
+ self . check_variant_for_ffi (
933
+ cache,
934
+ abi,
935
+ ty,
936
+ def,
937
+ def. non_enum_variant ( ) ,
938
+ substs,
939
+ )
926
940
}
927
941
AdtKind :: Enum => {
928
942
if def. variants . is_empty ( ) {
@@ -967,7 +981,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
967
981
} ;
968
982
}
969
983
970
- match self . check_variant_for_ffi ( cache, ty, def, variant, substs) {
984
+ match self . check_variant_for_ffi ( cache, abi , ty, def, variant, substs) {
971
985
FfiSafe => ( ) ,
972
986
r => return r,
973
987
}
@@ -984,11 +998,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
984
998
help : Some ( "consider using `u32` or `libc::wchar_t` instead" . into ( ) ) ,
985
999
} ,
986
1000
987
- ty:: Int ( ast:: IntTy :: I128 ) | ty:: Uint ( ast:: UintTy :: U128 ) => FfiUnsafe {
988
- ty,
989
- reason : "128-bit integers don't currently have a known stable ABI" . into ( ) ,
990
- help : None ,
991
- } ,
1001
+ ty:: Int ( ast:: IntTy :: I128 ) | ty:: Uint ( ast:: UintTy :: U128 ) if abi != SpecAbi :: SysV64 => {
1002
+ FfiUnsafe {
1003
+ ty,
1004
+ reason : "128-bit integers don't currently have a known stable ABI" . into ( ) ,
1005
+ help : None ,
1006
+ }
1007
+ }
992
1008
993
1009
// Primitive types with a stable representation.
994
1010
ty:: Bool | ty:: Int ( ..) | ty:: Uint ( ..) | ty:: Float ( ..) | ty:: Never => FfiSafe ,
@@ -1025,10 +1041,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1025
1041
}
1026
1042
1027
1043
ty:: RawPtr ( ty:: TypeAndMut { ty, .. } ) | ty:: Ref ( _, ty, _) => {
1028
- self . check_type_for_ffi ( cache, ty)
1044
+ self . check_type_for_ffi ( cache, abi , ty)
1029
1045
}
1030
1046
1031
- ty:: Array ( inner_ty, _) => self . check_type_for_ffi ( cache, inner_ty) ,
1047
+ ty:: Array ( inner_ty, _) => self . check_type_for_ffi ( cache, abi , inner_ty) ,
1032
1048
1033
1049
ty:: FnPtr ( sig) => {
1034
1050
if self . is_internal_abi ( sig. abi ( ) ) {
@@ -1045,7 +1061,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1045
1061
1046
1062
let sig = tcx. erase_late_bound_regions ( & sig) ;
1047
1063
if !sig. output ( ) . is_unit ( ) {
1048
- let r = self . check_type_for_ffi ( cache, sig. output ( ) ) ;
1064
+ let r = self . check_type_for_ffi ( cache, abi , sig. output ( ) ) ;
1049
1065
match r {
1050
1066
FfiSafe => { }
1051
1067
_ => {
@@ -1054,7 +1070,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1054
1070
}
1055
1071
}
1056
1072
for arg in sig. inputs ( ) {
1057
- let r = self . check_type_for_ffi ( cache, arg) ;
1073
+ let r = self . check_type_for_ffi ( cache, abi , arg) ;
1058
1074
match r {
1059
1075
FfiSafe => { }
1060
1076
_ => {
@@ -1166,6 +1182,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1166
1182
1167
1183
fn check_type_for_ffi_and_report_errors (
1168
1184
& mut self ,
1185
+ abi : SpecAbi ,
1169
1186
sp : Span ,
1170
1187
ty : Ty < ' tcx > ,
1171
1188
is_static : bool ,
@@ -1196,7 +1213,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1196
1213
return ;
1197
1214
}
1198
1215
1199
- match self . check_type_for_ffi ( & mut FxHashSet :: default ( ) , ty) {
1216
+ match self . check_type_for_ffi ( & mut FxHashSet :: default ( ) , abi , ty) {
1200
1217
FfiResult :: FfiSafe => { }
1201
1218
FfiResult :: FfiPhantom ( ty) => {
1202
1219
self . emit_ffi_unsafe_type_lint ( ty, sp, "composed only of `PhantomData`" , None ) ;
@@ -1210,25 +1227,25 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1210
1227
}
1211
1228
}
1212
1229
1213
- fn check_foreign_fn ( & mut self , id : hir:: HirId , decl : & hir:: FnDecl < ' _ > ) {
1230
+ fn check_foreign_fn ( & mut self , abi : SpecAbi , id : hir:: HirId , decl : & hir:: FnDecl < ' _ > ) {
1214
1231
let def_id = self . cx . tcx . hir ( ) . local_def_id ( id) ;
1215
1232
let sig = self . cx . tcx . fn_sig ( def_id) ;
1216
1233
let sig = self . cx . tcx . erase_late_bound_regions ( & sig) ;
1217
1234
1218
1235
for ( input_ty, input_hir) in sig. inputs ( ) . iter ( ) . zip ( decl. inputs ) {
1219
- self . check_type_for_ffi_and_report_errors ( input_hir. span , input_ty, false , false ) ;
1236
+ self . check_type_for_ffi_and_report_errors ( abi , input_hir. span , input_ty, false , false ) ;
1220
1237
}
1221
1238
1222
1239
if let hir:: FnRetTy :: Return ( ref ret_hir) = decl. output {
1223
1240
let ret_ty = sig. output ( ) ;
1224
- self . check_type_for_ffi_and_report_errors ( ret_hir. span , ret_ty, false , true ) ;
1241
+ self . check_type_for_ffi_and_report_errors ( abi , ret_hir. span , ret_ty, false , true ) ;
1225
1242
}
1226
1243
}
1227
1244
1228
- fn check_foreign_static ( & mut self , id : hir:: HirId , span : Span ) {
1245
+ fn check_foreign_static ( & mut self , abi : SpecAbi , id : hir:: HirId , span : Span ) {
1229
1246
let def_id = self . cx . tcx . hir ( ) . local_def_id ( id) ;
1230
1247
let ty = self . cx . tcx . type_of ( def_id) ;
1231
- self . check_type_for_ffi_and_report_errors ( span, ty, true , false ) ;
1248
+ self . check_type_for_ffi_and_report_errors ( abi , span, ty, true , false ) ;
1232
1249
}
1233
1250
1234
1251
fn is_internal_abi ( & self , abi : SpecAbi ) -> bool {
@@ -1252,10 +1269,10 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations {
1252
1269
if !vis. is_internal_abi ( abi) {
1253
1270
match it. kind {
1254
1271
hir:: ForeignItemKind :: Fn ( ref decl, _, _) => {
1255
- vis. check_foreign_fn ( it. hir_id , decl) ;
1272
+ vis. check_foreign_fn ( abi , it. hir_id , decl) ;
1256
1273
}
1257
1274
hir:: ForeignItemKind :: Static ( ref ty, _) => {
1258
- vis. check_foreign_static ( it. hir_id , ty. span ) ;
1275
+ vis. check_foreign_static ( abi , it. hir_id , ty. span ) ;
1259
1276
}
1260
1277
hir:: ForeignItemKind :: Type => ( ) ,
1261
1278
}
@@ -1283,7 +1300,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
1283
1300
1284
1301
let mut vis = ImproperCTypesVisitor { cx, mode : CItemKind :: Definition } ;
1285
1302
if !vis. is_internal_abi ( abi) {
1286
- vis. check_foreign_fn ( hir_id, decl) ;
1303
+ vis. check_foreign_fn ( abi , hir_id, decl) ;
1287
1304
}
1288
1305
}
1289
1306
}
0 commit comments