Skip to content

Commit 942d4c7

Browse files
committed
Blacklist fn item types from being used with variadic functions.
1 parent 7979dd6 commit 942d4c7

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-12
lines changed

src/librustc_typeck/check/mod.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -2578,24 +2578,33 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
25782578
ty::TyFloat(ast::FloatTy::F32) => {
25792579
fcx.type_error_message(arg.span,
25802580
|t| {
2581-
format!("can't pass an {} to variadic \
2582-
function, cast to c_double", t)
2581+
format!("can't pass an `{}` to variadic \
2582+
function, cast to `c_double`", t)
25832583
}, arg_ty, None);
25842584
}
25852585
ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
25862586
fcx.type_error_message(arg.span, |t| {
2587-
format!("can't pass {} to variadic \
2588-
function, cast to c_int",
2587+
format!("can't pass `{}` to variadic \
2588+
function, cast to `c_int`",
25892589
t)
25902590
}, arg_ty, None);
25912591
}
25922592
ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
25932593
fcx.type_error_message(arg.span, |t| {
2594-
format!("can't pass {} to variadic \
2595-
function, cast to c_uint",
2594+
format!("can't pass `{}` to variadic \
2595+
function, cast to `c_uint`",
25962596
t)
25972597
}, arg_ty, None);
25982598
}
2599+
ty::TyFnDef(_, _, f) => {
2600+
let ptr_ty = fcx.tcx().mk_ty(ty::TyFnPtr(f));
2601+
let ptr_ty = fcx.infcx().resolve_type_vars_if_possible(&ptr_ty);
2602+
fcx.type_error_message(arg.span,
2603+
|t| {
2604+
format!("can't pass `{}` to variadic \
2605+
function, cast to `{}`", t, ptr_ty)
2606+
}, arg_ty, None);
2607+
}
25992608
_ => {}
26002609
}
26012610
}

src/test/compile-fail/issue-32201.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern {
12+
fn foo(a: i32, ...);
13+
}
14+
15+
fn bar(_: *const u8) {}
16+
17+
fn main() {
18+
unsafe {
19+
foo(0, bar);
20+
//~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function, cast to `fn(*const u8)`
21+
}
22+
}

src/test/compile-fail/variadic-ffi-3.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ fn main() {
3333
//~| expected variadic fn
3434
//~| found non-variadic function
3535

36-
foo(1, 2, 3f32); //~ ERROR: can't pass an f32 to variadic function, cast to c_double
37-
foo(1, 2, true); //~ ERROR: can't pass bool to variadic function, cast to c_int
38-
foo(1, 2, 1i8); //~ ERROR: can't pass i8 to variadic function, cast to c_int
39-
foo(1, 2, 1u8); //~ ERROR: can't pass u8 to variadic function, cast to c_uint
40-
foo(1, 2, 1i16); //~ ERROR: can't pass i16 to variadic function, cast to c_int
41-
foo(1, 2, 1u16); //~ ERROR: can't pass u16 to variadic function, cast to c_uint
36+
foo(1, 2, 3f32); //~ ERROR: can't pass an `f32` to variadic function, cast to `c_double`
37+
foo(1, 2, true); //~ ERROR: can't pass `bool` to variadic function, cast to `c_int`
38+
foo(1, 2, 1i8); //~ ERROR: can't pass `i8` to variadic function, cast to `c_int`
39+
foo(1, 2, 1u8); //~ ERROR: can't pass `u8` to variadic function, cast to `c_uint`
40+
foo(1, 2, 1i16); //~ ERROR: can't pass `i16` to variadic function, cast to `c_int`
41+
foo(1, 2, 1u16); //~ ERROR: can't pass `u16` to variadic function, cast to `c_uint`
4242
}
4343
}

0 commit comments

Comments
 (0)