-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Support defining C compatible variadic functions #57760
Conversation
This comment has been minimized.
This comment has been minimized.
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work on this! :-D I think you've essentially taken a sound approach to implementing this feature, though others who are probably more qualified than me will hopefully confirm that. See my suggestions about the codegen from MIR, but otherwise my comments are just nits (really minor things). Feel free to ping me again for a final review, once you've ironed out everything and added more tests. (A brief chapter in the Unstable Book would be nice too.)
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
I noticed some typos I was going to push before I saw this PR, you might just want to take them into this PR instead master...parched:va-args |
@parched 👍 good catch! I'll merge it in. |
@parched now that I think about it that will likely solve a aarch64 issue I saw previously, so it might be worth merging as a standalone PR. |
9dca909
to
0322ede
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
Currently this PR causes an issue with |
Figured out what is causing the issue with When running the following using let fmt_str = CString::new("%d%d\n").unwrap();
printf(fmt_str.as_ptr(), 0, 42); We currently emit the following LLVM IR:
When we should emit the following LLVM IR:
So clearly at some point when attempting to remove the "spoofed" |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
This comment has been minimized.
This comment has been minimized.
36e5d87
to
285ec4e
Compare
⌛ Testing commit f7dd438 with merge 35046f85f921a5daadfcd7be66cd82ea27352f2b... |
@bors retry - prioritize stable backport |
Support defining C compatible variadic functions ## Summary Add support for defining C compatible variadic functions in unsafe rust with `extern "C"` according to [RFC 2137]. ## Details ### Parsing When parsing a user defined function that is `unsafe` and `extern "C"` allow variadic signatures and inject a "spoofed" `VaList` in the new functions signature. This allows the user to interact with the variadic arguments via a `VaList` instead of manually using `va_start` and `va_end` (See [RFC 2137] for details). ### Codegen When running codegen for a variadic function, remove the "spoofed" `VaList` from the function signature and inject `va_start` when the arg local references are created for the function and `va_end` on return. ## TODO - [x] Get feedback on injecting `va_start/va_end` in MIR vs codegen - [x] Properly inject `va_end` - It seems like it should be possible to inject `va_end` on the `TerminatorKind::Return`. I just need to figure out how to get the `LocalRef` here. - [x] Properly call Rust defined C variadic functions in Rust - The spoofed `VaList` causes problems here. Related to: #44930 r? @ghost [RFC 2137]: https://github.com/rust-lang/rfcs/blob/master/text/2137-variadic.md
☀️ Test successful - checks-travis, status-appveyor |
@dlrobertson I think this may have regressed macros and variadic functions slightly, I've got a test that looks like: #[foo]
extern "C" {
pub fn foo3(x: i32, ...);
} but the input to the macro extern "C" {
pub fn foo3(x: i32, ..., ...);
} Do you think this may have accidentally broken the pretty printer for variadic functions? |
(I've opened up #58853 to track regardless) |
It is very likely.
Thanks! |
@dlrobertson I appreciate your hard work on this feature. I think hitting an issue in release mode on the latest nightly ( #![feature(c_variadic)]
extern "C" {
#[no_mangle]
fn vprintf(_: *const libc::c_char, _: ...) -> libc::c_int;
}
#[no_mangle]
unsafe extern "C" fn variadic(fmt: *const libc::c_char, a: ...)
-> libc::c_int {
vprintf(fmt, a)
}
fn main() {
let fmt = std::ffi::CString::new("test %d %d %d\n").expect("new failed");
unsafe {
variadic(fmt.as_ptr(), 1, 2, 3);
}
} Advance apologies if I'm doing something that isn't expected to work. |
@thedataking: Can you open this example up as a new issue, so we don't lose track of it here? |
@thedataking Thanks for the catch. A issue would definitely be appreciated. |
@dlrobertson @varkor I opened up #58980 to track this issue. Thanks! |
Summary
Add support for defining C compatible variadic functions in unsafe rust with
extern "C"
according to RFC 2137.Details
Parsing
When parsing a user defined function that is
unsafe
andextern "C"
allowvariadic signatures and inject a "spoofed"
VaList
in the new functionssignature. This allows the user to interact with the variadic arguments via a
VaList
instead of manually usingva_start
andva_end
(See RFC 2137 fordetails).
Codegen
When running codegen for a variadic function, remove the "spoofed"
VaList
from the function signature and inject
va_start
when the arg localreferences are created for the function and
va_end
on return.TODO
va_start/va_end
in MIR vs codegenva_end
- It seems like it should be possible to injectva_end
on theTerminatorKind::Return
. I just need to figure out howto get the
LocalRef
here.VaList
causes problems here.Related to: #44930
r? @ghost