]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #57760 - dlrobertson:varargs1, r=alexreg
authorbors <bors@rust-lang.org>
Thu, 28 Feb 2019 15:00:25 +0000 (15:00 +0000)
committerbors <bors@rust-lang.org>
Thu, 28 Feb 2019 15:00:25 +0000 (15:00 +0000)
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

1  2 
src/librustc/hir/lowering.rs
src/librustc_save_analysis/sig.rs
src/librustc_typeck/astconv.rs
src/libsyntax/ast.rs
src/libsyntax/ext/build.rs
src/libsyntax/feature_gate.rs
src/libsyntax/mut_visit.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 669c68eda39d2a5261892799a6016fc33ccfa5f5,fad370d768e8d91af79a40393b0eb187771090fe..1c0b931b289c23d8826d02030b67fb07e3b5bd10
@@@ -1898,9 -1901,14 +1901,14 @@@ impl<'a> Visitor<'a> for PostExpansionV
          match fn_kind {
              FnKind::ItemFn(_, header, _, _) => {
                  // Check for const fn and async fn declarations.
 -                if header.asyncness.is_async() {
 +                if header.asyncness.node.is_async() {
                      gate_feature_post!(&self, async_await, span, "async fn is unstable");
                  }
+                 if fn_decl.c_variadic {
+                     gate_feature_post!(&self, c_variadic, span,
+                                        "C-varaidic functions are unstable");
+                 }
                  // Stability of const fn methods are covered in
                  // `visit_trait_item` and `visit_impl_item` below; this is
                  // because default methods don't pass through this point.
Simple merge
Simple merge
Simple merge
Simple merge