@@ -250,7 +250,16 @@ impl FnType {
250
250
extra_args
251
251
} ;
252
252
253
- let arg_of = |ty : Ty < ' tcx > | {
253
+ let target = & ccx. sess ( ) . target . target ;
254
+ let win_x64_gnu = target. target_os == "windows"
255
+ && target. arch == "x86_64"
256
+ && target. target_env == "gnu" ;
257
+ let rust_abi = match abi {
258
+ RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true ,
259
+ _ => false
260
+ } ;
261
+
262
+ let arg_of = |ty : Ty < ' tcx > , is_return : bool | {
254
263
if ty. is_bool ( ) {
255
264
let llty = Type :: i1 ( ccx) ;
256
265
let mut arg = ArgType :: new ( llty, llty) ;
@@ -260,7 +269,11 @@ impl FnType {
260
269
let mut arg = ArgType :: new ( type_of:: type_of ( ccx, ty) ,
261
270
type_of:: sizing_type_of ( ccx, ty) ) ;
262
271
if llsize_of_real ( ccx, arg. ty ) == 0 {
263
- arg. ignore ( ) ;
272
+ // For some forsaken reason, x86_64-pc-windows-gnu
273
+ // doesn't ignore zero-sized struct arguments.
274
+ if is_return || rust_abi || !win_x64_gnu {
275
+ arg. ignore ( ) ;
276
+ }
264
277
}
265
278
arg
266
279
}
@@ -270,7 +283,7 @@ impl FnType {
270
283
ty:: FnConverging ( ret_ty) => ret_ty,
271
284
ty:: FnDiverging => ccx. tcx ( ) . mk_nil ( )
272
285
} ;
273
- let mut ret = arg_of ( ret_ty) ;
286
+ let mut ret = arg_of ( ret_ty, true ) ;
274
287
275
288
if !type_is_fat_ptr ( ccx. tcx ( ) , ret_ty) {
276
289
// The `noalias` attribute on the return value is useful to a
@@ -335,7 +348,7 @@ impl FnType {
335
348
} ;
336
349
337
350
for ty in inputs. iter ( ) . chain ( extra_args. iter ( ) ) {
338
- let mut arg = arg_of ( ty) ;
351
+ let mut arg = arg_of ( ty, false ) ;
339
352
340
353
if type_is_fat_ptr ( ccx. tcx ( ) , ty) {
341
354
let original_tys = arg. original_ty . field_types ( ) ;
0 commit comments