Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with passing struct to C function on windows #11198

Closed
ghost opened this issue Dec 29, 2013 · 6 comments · Fixed by #12762
Closed

Problem with passing struct to C function on windows #11198

ghost opened this issue Dec 29, 2013 · 6 comments · Fixed by #12762

Comments

@ghost
Copy link

ghost commented Dec 29, 2013

I prepared some files that should illustrate the problem: click

Struct Color is passed incorrectly to function in C library. I pass {1,2,3,4} but receive {1,0,0,0}.

It happens on Windows 7 64bit, but not on Linux Mint 64bit.
Using external LLVM to compile bitcode (on Windows) works too.

@alexcrichton
Copy link
Member

Can you provide a slightly more minimized test case? It would also be useful to have content hosted in a github gist instead of a 7z archive that's much more easily accessible.

@ghost
Copy link
Author

ghost commented Dec 29, 2013

@alexcrichton
Copy link
Member

Thanks!

cc @jld, @nikomatsakis

@alexcrichton
Copy link
Member

It appears that gcc treats the struct as an immediate 32-bit value (one register), and our call to the function generate a function call with 4 arguments. I would copy-paste more assembly, but I'm not sure how to copy out of a windows VM...

@ghost
Copy link
Author

ghost commented Dec 30, 2013

These parts are probably relevant:
https://gist.github.com/krzat/8181219#file-windows_external_llvm-asm-L34-L52
https://gist.github.com/krzat/8181219#file-windows_internal_llvm-asm-L43-L66

windows_internal_llvm.asm was generated by LLVM integrated with rust
windows_external_llvm.asm was generated by my own LLVM build and it works OK

Are there some parameters passed to integrated LLVM that could cause this?

@ghost
Copy link
Author

ghost commented Jan 11, 2014

I wrote a small utility to bypass the problem: https://gist.github.com/krzat/8374078
It worked with rsfml, though I guess rust uses LLVM fork for a reason.

@bors bors closed this as completed in 61d5bc5 Mar 19, 2014
flip1995 pushed a commit to flip1995/rust that referenced this issue Jul 31, 2023
[`slow_vector_initialization`]: catch `Vec::new()` followed by `.resize(len, 0)`

Closes rust-lang#10938

changelog: [`slow_vector_initialization`]: catch `Vec::new()` followed by `.resize(len, 0)`
flip1995 pushed a commit to flip1995/rust that referenced this issue Aug 11, 2023
…=xFrednet,djc

[`slow_vector_initialization`]: clarify why `Vec::new()` + resize is worse

rust-lang#11198 extended this lint to also warn on `Vec::new()` + `resize(0, len)`, but did not update the lint documentation, so it left some confused (rust-lang/rust-clippy#10938 (comment)).
This PR should make it a bit more clear. (cc `@djc` `@vi` what do you think about this?)

<details>
<summary>More details</summary>

Godbolt for `Vec::new()` + `.resize(x, 0)`: https://godbolt.org/z/e7q9xc9rG

The resize call first does a normal allocation (`__rust_alloc`):
```asm
alloc::raw_vec::finish_grow:
  ...
  cmp     qword ptr [rcx + 8], 0
  je      .LBB1_7  ; if capacity == 0 -> LBB1_7

.LBB1_7:
  ...
  call    qword ptr [rip + __rust_alloc@GOTPCREL]
```

*Then* a memset for zero initialization:
```asm
example::f:
  ...
  xor     esi, esi  ; 0
  call    qword ptr [rip + memset@GOTPCREL]
```
------------

Godbolt for `vec![0; len]`: https://godbolt.org/z/M3vr53vWY

Important bit:
```asm
example::f:
  ...
  call    qword ptr [rip + __rust_alloc_zeroed@GOTPCREL]
```

</details>

changelog: [`slow_vector_initialization`]: clarify why `Vec::new()` + resize is worse than `vec![0; len]`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant