@@ -251,22 +251,21 @@ fn check_struct_for_power_alignment<'tcx>(
251251 item : & ' tcx hir:: Item < ' tcx > ,
252252 adt_def : AdtDef < ' tcx > ,
253253) {
254- let tcx = cx. tcx ;
255-
256254 // Only consider structs (not enums or unions) on AIX.
257- if tcx. sess . target . os != "aix" || !adt_def. is_struct ( ) {
255+ if cx . tcx . sess . target . os != "aix" || !adt_def. is_struct ( ) {
258256 return ;
259257 }
260258
261259 // The struct must be repr(C), but ignore it if it explicitly specifies its alignment with
262260 // either `align(N)` or `packed(N)`.
263- if adt_def. repr ( ) . c ( ) && !adt_def. repr ( ) . packed ( ) && adt_def. repr ( ) . align . is_none ( ) {
261+ debug_assert ! ( adt_def. repr( ) . c( ) && !adt_def. repr( ) . packed( ) && adt_def. repr( ) . align. is_none( ) ) ;
262+ if cx. tcx . sess . target . os == "aix" && !adt_def. all_fields ( ) . next ( ) . is_none ( ) {
264263 let struct_variant_data = item. expect_struct ( ) . 2 ;
265264 for field_def in struct_variant_data. fields ( ) . iter ( ) . skip ( 1 ) {
266265 // Struct fields (after the first field) are checked for the
267266 // power alignment rule, as fields after the first are likely
268267 // to be the fields that are misaligned.
269- let ty = tcx. type_of ( field_def. def_id ) . instantiate_identity ( ) ;
268+ let ty = cx . tcx . type_of ( field_def. def_id ) . instantiate_identity ( ) ;
270269 if check_arg_for_power_alignment ( cx, ty) {
271270 cx. emit_span_lint ( USES_POWER_ALIGNMENT , field_def. span , UsesPowerAlignment ) ;
272271 }
@@ -1060,7 +1059,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10601059 // otherwise, having all fields be phantoms
10611060 // takes priority over transparent_with_all_zst_fields
10621061 if let FfiUnsafe ( explanations) = ffires_accumulator {
1063- debug_assert ! ( def. repr( ) . c( ) || def. repr( ) . transparent( ) || def. repr( ) . int. is_some( ) ) ;
1062+ debug_assert ! (
1063+ ( def. repr( ) . c( ) && !def. repr( ) . packed( ) )
1064+ || def. repr( ) . transparent( )
1065+ || def. repr( ) . int. is_some( )
1066+ ) ;
10641067
10651068 if def. repr ( ) . transparent ( ) || matches ! ( def. adt_kind( ) , AdtKind :: Enum ) {
10661069 let field_ffires = FfiUnsafe ( explanations) . wrap_all (
@@ -1130,7 +1133,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11301133 ) -> FfiResult < ' tcx > {
11311134 debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Struct | AdtKind :: Union ) ) ;
11321135
1133- if !def. repr ( ) . c ( ) && !def. repr ( ) . transparent ( ) {
1136+ if !( ( def. repr ( ) . c ( ) && !def. repr ( ) . packed ( ) ) || def. repr ( ) . transparent ( ) ) {
1137+ // FIXME(ctypes) packed reprs prevent C compatibility, right?
11341138 return FfiResult :: new_with_reason (
11351139 ty,
11361140 if def. is_struct ( ) {
@@ -1202,7 +1206,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12021206 }
12031207 // Check for a repr() attribute to specify the size of the
12041208 // discriminant.
1205- if !def. repr ( ) . c ( ) && !def. repr ( ) . transparent ( ) && def. repr ( ) . int . is_none ( ) {
1209+ if !( def. repr ( ) . c ( ) && !def. repr ( ) . packed ( ) )
1210+ && !def. repr ( ) . transparent ( )
1211+ && def. repr ( ) . int . is_none ( )
1212+ {
12061213 // Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>`
12071214 if let Some ( inner_ty) = repr_nullable_ptr ( self . cx . tcx , self . cx . typing_env ( ) , ty) {
12081215 return self . visit_type ( state. get_next ( ty) , inner_ty) ;
0 commit comments