Skip to content

Swapped Arguments in Generated Code for extern-C func on x64 #41375

Closed
@Gankra

Description

@Gankra

The following program has arg9 and arg10 swapped on the Rust side (C++ is passing the args correctly, as far as the AMD64 ABI is concerned).

Test Platform: macos x64

Reproduced On:

  • rustc 1.16.0 (30cf806 2017-03-10)
  • rustc 1.18.0-nightly (7627e3d 2017-04-16)

Reproduction Steps:

// lib.rs
pub struct BigArg1(u32, usize, usize, u32);
#[repr(C)] pub struct U32Arg2(u32);
#[repr(C)] pub struct TwoU32Arg5(u32, u32);
#[repr(C)] pub struct ComplexArg6 { size: usize, serialize_start_time: u64, serialize_end_time: u64 }
#[repr(C)] pub struct UsizeArg9 { size: usize }

#[no_mangle]
pub unsafe extern "C" fn wr_api_set_root_display_list(arg1: &mut BigArg1,
                                                      arg2: U32Arg2,
                                                      arg3: f32,
                                                      arg4: f32,
                                                      arg5: TwoU32Arg5,
                                                      arg6: ComplexArg6,
                                                      arg7: *mut u8,
                                                      arg8: usize,
                                                      arg9: UsizeArg9,
                                                      arg10: *mut u8,
                                                      arg11: usize) {

      println!("Arg01 (addr) {:?}", arg1 as *mut _);
      println!("Arg02 {:?}", arg2.0);
      println!("Arg03 {:?}", arg3);
      println!("Arg04 {:?}", arg4);
      println!("Arg05 {:?} {:?}", arg5.0, arg5.1);
      println!("Arg06 {:?} {:?} {:?}", arg6.size, arg6.serialize_start_time, arg6.serialize_end_time);
      println!("Arg07 {:?}", arg7);
      println!("Arg08 {:?}", arg8);
      println!("Arg09 {:?}", arg9.size);
      println!("Arg10 {:?}", arg10);
      println!("Arg11 {:?}", arg11);
}
// main.cpp

#include <stdlib.h>
#include <stdint.h>

struct BigArg1;
struct U32Arg2 { uint32_t a; };
struct TwoU32Arg5 { uint32_t a; uint32_t b; };
struct ComplexArg6 { size_t size; uint64_t serialize_start_time; uint64_t serialize_end_time; };
struct UsizeArg9 { size_t size; };

extern "C" {
  inline void
  wr_api_set_root_display_list(BigArg1* arg1,
      U32Arg2 arg2,
      float arg3,
      float arg4,
      TwoU32Arg5 arg5,
      ComplexArg6 arg6,
      uint8_t* arg7,
      size_t arg8,
      UsizeArg9 arg9,
      uint8_t* arg10,
      size_t arg11);
}


int main() {
  U32Arg2 arg2 = { 2 };
  TwoU32Arg5 arg5 = { 50, 51 };
  ComplexArg6 arg6 = { 60, 61, 62 };
  UsizeArg9 arg9 = { 9 };

  wr_api_set_root_display_list(
      (BigArg1*) 1,
      arg2,
      3.0,
      4.0,
      arg5,
      arg6,
      (uint8_t*) 7,
      8,
      arg9,
      (uint8_t*) 10,
      11
  );
}
rustc --crate-type=staticlib lib.rs
clang++ main.cpp liblib.a
./a.out

Arg01 (addr) 0x1
Arg02 2
Arg03 3
Arg04 4
Arg05 50 51
Arg06 60 61 62
Arg07 0x7
Arg08 8
Arg09 10
Arg10 0x9
Arg11 11

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions