forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests for variadic foreign functions.
- Loading branch information
Showing
6 changed files
with
170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
extern { | ||
fn printf(...); //~ ERROR: variadic function must be declared with at least one named argument | ||
fn printf(..., foo: int); //~ ERROR: `...` must be last in argument list for variadic function | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
fn baz(f: extern "stdcall" fn(uint, ...)) { | ||
//~^ ERROR: variadic function must have C calling convention | ||
f(22, 44); | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
fn foo(x: int, ...) { | ||
//~^ ERROR: only foreign functions are allowed to be variadic | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
extern "C" fn foo(x: int, ...) { | ||
//~^ ERROR: only foreign functions are allowed to be variadic | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
extern "stdcall" { | ||
fn printf(_: *u8, ...); //~ ERROR: variadic function must have C calling convention | ||
} | ||
|
||
extern { | ||
fn foo(f: int, x: u8, ...); | ||
} | ||
|
||
extern "C" fn bar(f: int, x: u8) {} | ||
|
||
#[fixed_stack_segment] | ||
fn main() { | ||
unsafe { | ||
foo(); //~ ERROR: this function takes at least 2 parameters but 0 parameters were supplied | ||
foo(1); //~ ERROR: this function takes at least 2 parameters but 1 parameter was supplied | ||
|
||
let x: extern "C" unsafe fn(f: int, x: u8) = foo; | ||
//~^ ERROR: mismatched types: expected `extern "C" unsafe fn(int, u8)` but found `extern "C" unsafe fn(int, u8, ...)` (expected non-variadic fn but found variadic function) | ||
|
||
let y: extern "C" unsafe fn(f: int, x: u8, ...) = bar; | ||
//~^ ERROR: mismatched types: expected `extern "C" unsafe fn(int, u8, ...)` but found `extern "C" extern fn(int, u8)` (expected variadic fn but found non-variadic function) | ||
|
||
foo(1, 2, 3f32); //~ ERROR: can't pass an f32 to variadic function, cast to c_double | ||
foo(1, 2, true); //~ ERROR: can't pass bool to variadic function, cast to c_int | ||
foo(1, 2, 1i8); //~ ERROR: can't pass i8 to variadic function, cast to c_int | ||
foo(1, 2, 1u8); //~ ERROR: can't pass u8 to variadic function, cast to c_uint | ||
foo(1, 2, 1i16); //~ ERROR: can't pass i16 to variadic function, cast to c_int | ||
foo(1, 2, 1u16); //~ ERROR: can't pass u16 to variadic function, cast to c_uint | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use std::c_str::CString; | ||
use std::libc::{c_char, c_int}; | ||
|
||
extern { | ||
fn sprintf(s: *mut c_char, format: *c_char, ...) -> c_int; | ||
} | ||
|
||
unsafe fn check<T>(expected: &str, f: &fn(*mut c_char) -> T) { | ||
let mut x = [0i8, ..50]; | ||
f(&mut x[0] as *mut c_char); | ||
let res = CString::new(&x[0], false); | ||
assert_eq!(expected, res.as_str().unwrap()); | ||
} | ||
|
||
#[fixed_stack_segment] | ||
pub fn main() { | ||
|
||
unsafe { | ||
// Call with just the named parameter | ||
do "Hello World\n".with_c_str |c| { | ||
check("Hello World\n", |s| sprintf(s, c)); | ||
} | ||
|
||
// Call with variable number of arguments | ||
do "%d %f %c %s\n".with_c_str |c| { | ||
do check("42 42.500000 a %d %f %c %s\n\n") |s| { | ||
sprintf(s, c, 42i, 42.5f64, 'a' as c_int, c); | ||
} | ||
} | ||
|
||
// Make a function pointer | ||
let x: extern "C" unsafe fn(*mut c_char, *c_char, ...) -> c_int = sprintf; | ||
|
||
// A function that takes a function pointer | ||
unsafe fn call(p: extern "C" unsafe fn(*mut c_char, *c_char, ...) -> c_int) { | ||
#[fixed_stack_segment]; | ||
|
||
// Call with just the named parameter via fn pointer | ||
do "Hello World\n".with_c_str |c| { | ||
check("Hello World\n", |s| p(s, c)); | ||
} | ||
|
||
// Call with variable number of arguments | ||
do "%d %f %c %s\n".with_c_str |c| { | ||
do check("42 42.500000 a %d %f %c %s\n\n") |s| { | ||
p(s, c, 42i, 42.5f64, 'a' as c_int, c); | ||
} | ||
} | ||
} | ||
|
||
// Pass sprintf directly | ||
call(sprintf); | ||
|
||
// Pass sprintf indirectly | ||
call(x); | ||
} | ||
|
||
} |