From 82f08ea21c38d28d9337c0372eb7deec13003425 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 15 Oct 2015 17:03:27 -0400 Subject: [PATCH] trans: Use an isize to count the number of registers so we don't underflow for fn's with > 7 args in debug builds. --- src/librustc_trans/trans/cabi_x86_64.rs | 6 ++--- .../extern-fn-struct-passing-abi/test.c | 22 +++++++++++++++++++ .../extern-fn-struct-passing-abi/test.rs | 3 +++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs index 3ca82b673ff..00d8fdad32d 100644 --- a/src/librustc_trans/trans/cabi_x86_64.rs +++ b/src/librustc_trans/trans/cabi_x86_64.rs @@ -411,7 +411,7 @@ pub fn compute_abi_info(ccx: &CrateContext, } let mut int_regs = 6; // RDI, RSI, RDX, RCX, R8, R9 - let mut sse_regs = 8; + let mut sse_regs = 8; // XMM0-7 let ret_ty = if ret_def { x86_64_ty(ccx, rty, |cls| { @@ -430,8 +430,8 @@ pub fn compute_abi_info(ccx: &CrateContext, let mut arg_tys = Vec::new(); for t in atys { let ty = x86_64_ty(ccx, *t, |cls| { - let needed_int = cls.iter().filter(|&&c| c == Int).count(); - let needed_sse = cls.iter().filter(|c| c.is_sse()).count(); + let needed_int = cls.iter().filter(|&&c| c == Int).count() as isize; + let needed_sse = cls.iter().filter(|c| c.is_sse()).count() as isize; let in_mem = cls.is_pass_byval() || int_regs < needed_int || sse_regs < needed_sse; diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.c b/src/test/run-make/extern-fn-struct-passing-abi/test.c index 1a7e3389b7f..4253767ee76 100644 --- a/src/test/run-make/extern-fn-struct-passing-abi/test.c +++ b/src/test/run-make/extern-fn-struct-passing-abi/test.c @@ -58,6 +58,28 @@ void byval_rect(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, struct Re assert(s.d == 556); } +// System V x86_64 ABI: +// a, b, c, d, e, f should be in registers +// s should be byval pointer on the stack +// +// Win64 ABI: +// a, b, c, d should be in registers +// e, f should be on the stack +// s should be byval pointer on the stack +void byval_many_rect(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, + int32_t f, struct Rect s) { + assert(a == 1); + assert(b == 2); + assert(c == 3); + assert(d == 4); + assert(e == 5); + assert(f == 6); + assert(s.a == 553); + assert(s.b == 554); + assert(s.c == 555); + assert(s.d == 556); +} + // System V x86_64 ABI: // a, b, c, d, e, f, g should be in sse registers // s should be split across 2 registers diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.rs b/src/test/run-make/extern-fn-struct-passing-abi/test.rs index f223a8ddc06..b91362b8edc 100644 --- a/src/test/run-make/extern-fn-struct-passing-abi/test.rs +++ b/src/test/run-make/extern-fn-struct-passing-abi/test.rs @@ -50,6 +50,8 @@ struct Huge { extern { fn byval_rect(a: i32, b: i32, c: i32, d: i32, e: i32, s: Rect); + fn byval_many_rect(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, s: Rect); + fn byval_rect_floats(a: f32, b: f32, c: f64, d: f32, e: f32, f: f32, g: f64, s: Rect, t: FloatRect); @@ -80,6 +82,7 @@ fn main() { unsafe { byval_rect(1, 2, 3, 4, 5, s); + byval_many_rect(1, 2, 3, 4, 5, 6, s); byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u); byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s); split_rect(1, 2, s);