Skip to content

Commit af7554d

Browse files
committed
Auto merge of #56396 - dlrobertson:fix_va_list_tests, r=nikic
tests: Simplify VaList run-make test The va_list tests were too complex and were causing some spurious test failures on Windows. Example: #55011 (comment)
2 parents d311571 + 28ca35f commit af7554d

File tree

2 files changed

+57
-174
lines changed

2 files changed

+57
-174
lines changed

src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs

+45-107
Original file line numberDiff line numberDiff line change
@@ -16,127 +16,65 @@ extern crate libc;
1616

1717
use libc::{c_char, c_double, c_int, c_long, c_longlong};
1818
use std::ffi::VaList;
19-
use std::slice;
20-
use std::ffi::CStr;
19+
use std::ffi::{CString, CStr};
2120

22-
#[repr(C)]
23-
#[derive(Clone, Copy, Debug)]
24-
pub enum AnswerType {
25-
Double,
26-
Long,
27-
LongLong,
28-
Int,
29-
Byte,
30-
CStr,
31-
Skip,
21+
macro_rules! continue_if {
22+
($cond:expr) => {
23+
if !($cond) {
24+
return 0xff;
25+
}
26+
}
3227
}
3328

34-
#[repr(C)]
35-
pub union AnswerData {
36-
pub double: c_double,
37-
pub long: c_long,
38-
pub longlong: c_longlong,
39-
pub int: c_int,
40-
pub byte: c_char,
41-
pub cstr: *const c_char,
42-
pub skip_ty: AnswerType,
29+
unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool {
30+
let cstr0 = CStr::from_ptr(ptr);
31+
let cstr1 = CString::new(val).unwrap();
32+
&*cstr1 == cstr0
4333
}
4434

45-
#[repr(C)]
46-
pub struct Answer {
47-
tag: AnswerType,
48-
data: AnswerData,
35+
#[no_mangle]
36+
pub unsafe extern "C" fn check_list_0(mut ap: VaList) -> usize {
37+
continue_if!(ap.arg::<c_longlong>() == 1);
38+
continue_if!(ap.arg::<c_int>() == 2);
39+
continue_if!(ap.arg::<c_longlong>() == 3);
40+
0
4941
}
5042

5143
#[no_mangle]
52-
pub unsafe fn compare_answers(answers: &[Answer], mut ap: VaList) -> usize {
53-
for (i, answer) in answers.iter().enumerate() {
54-
match answer {
55-
Answer { tag: AnswerType::Double, data: AnswerData { double: d } } => {
56-
let tmp = ap.arg::<c_double>();
57-
if d.floor() != tmp.floor() {
58-
println!("Double: {} != {}", d, tmp);
59-
return i + 1;
60-
}
61-
}
62-
Answer { tag: AnswerType::Long, data: AnswerData { long: l } } => {
63-
let tmp = ap.arg::<c_long>();
64-
if *l != tmp {
65-
println!("Long: {} != {}", l, tmp);
66-
return i + 1;
67-
}
68-
}
69-
Answer { tag: AnswerType::LongLong, data: AnswerData { longlong: l } } => {
70-
let tmp = ap.arg::<c_longlong>();
71-
if *l != tmp {
72-
println!("Long Long: {} != {}", l, tmp);
73-
return i + 1;
74-
}
75-
}
76-
Answer { tag: AnswerType::Int, data: AnswerData { int: n } } => {
77-
let tmp = ap.arg::<c_int>();
78-
if *n != tmp {
79-
println!("Int: {} != {}", n, tmp);
80-
return i + 1;
81-
}
82-
}
83-
Answer { tag: AnswerType::Byte, data: AnswerData { byte: b } } => {
84-
let tmp = ap.arg::<c_char>();
85-
if *b != tmp {
86-
println!("Byte: {} != {}", b, tmp);
87-
return i + 1;
88-
}
89-
}
90-
Answer { tag: AnswerType::CStr, data: AnswerData { cstr: c0 } } => {
91-
let c1 = ap.arg::<*const c_char>();
92-
let cstr0 = CStr::from_ptr(*c0);
93-
let cstr1 = CStr::from_ptr(c1);
94-
if cstr0 != cstr1 {
95-
println!("C String: {:?} != {:?}", cstr0, cstr1);
96-
return i + 1;
97-
}
98-
}
99-
_ => {
100-
println!("Unknown type!");
101-
return i + 1;
102-
}
103-
}
104-
}
105-
return 0;
44+
pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize {
45+
continue_if!(ap.arg::<c_int>() == -1);
46+
continue_if!(ap.arg::<c_char>() == 'A' as c_char);
47+
continue_if!(ap.arg::<c_char>() == '4' as c_char);
48+
continue_if!(ap.arg::<c_char>() == ';' as c_char);
49+
continue_if!(ap.arg::<c_int>() == 0x32);
50+
continue_if!(ap.arg::<c_int>() == 0x10000001);
51+
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Valid!"));
52+
0
10653
}
10754

10855
#[no_mangle]
109-
pub unsafe extern "C" fn check_rust(argc: usize, answers: *const Answer, ap: VaList) -> usize {
110-
let slice = slice::from_raw_parts(answers, argc);
111-
compare_answers(slice, ap)
56+
pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize {
57+
continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor());
58+
continue_if!(ap.arg::<c_long>() == 12);
59+
continue_if!(ap.arg::<c_char>() == 'a' as c_char);
60+
continue_if!(ap.arg::<c_double>().floor() == 6.18f64.floor());
61+
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello"));
62+
continue_if!(ap.arg::<c_int>() == 42);
63+
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World"));
64+
0
11265
}
11366

11467
#[no_mangle]
115-
pub unsafe extern "C" fn check_rust_copy(argc: usize, answers: *const Answer,
116-
mut ap: VaList) -> usize {
117-
let slice = slice::from_raw_parts(answers, argc);
118-
let mut skip_n = 0;
119-
for (i, answer) in slice.iter().enumerate() {
120-
match answer {
121-
Answer { tag: AnswerType::Skip, data: AnswerData { skip_ty } } => {
122-
match skip_ty {
123-
AnswerType::Double => { ap.arg::<c_double>(); }
124-
AnswerType::Long => { ap.arg::<c_long>(); }
125-
AnswerType::LongLong => { ap.arg::<c_longlong>(); }
126-
AnswerType::Int => { ap.arg::<c_int>(); }
127-
AnswerType::Byte => { ap.arg::<c_char>(); }
128-
AnswerType::CStr => { ap.arg::<*const c_char>(); }
129-
_ => { return i; }
130-
};
131-
}
132-
_ => {
133-
skip_n = i;
134-
break;
135-
}
68+
pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize {
69+
continue_if!(ap.arg::<c_double>().floor() == 6.28f64.floor());
70+
continue_if!(ap.arg::<c_int>() == 16);
71+
continue_if!(ap.arg::<c_char>() == 'A' as c_char);
72+
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!"));
73+
ap.copy(|mut ap| {
74+
if compare_c_str(ap.arg::<*const c_char>(), "Correct") {
75+
0
76+
} else {
77+
0xff
13678
}
137-
}
138-
139-
ap.copy(|ap| {
140-
compare_answers(&slice[skip_n..], ap)
14179
})
14280
}

src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c

+12-67
Original file line numberDiff line numberDiff line change
@@ -12,84 +12,29 @@
1212
#include <assert.h>
1313
#include <stdint.h>
1414
#include <stdlib.h>
15+
#include <stdio.h>
1516

16-
typedef enum {
17-
TAG_DOUBLE,
18-
TAG_LONG,
19-
TAG_LONGLONG,
20-
TAG_INT,
21-
TAG_BYTE,
22-
TAG_CSTR,
23-
TAG_SKIP,
24-
} tag;
17+
extern size_t check_list_0(va_list ap);
18+
extern size_t check_list_1(va_list ap);
19+
extern size_t check_list_2(va_list ap);
20+
extern size_t check_list_copy_0(va_list ap);
2521

26-
typedef struct {
27-
tag answer_type;
28-
union {
29-
double double_precision;
30-
long num_long;
31-
long long num_longlong;
32-
int num_int;
33-
int8_t byte;
34-
char* cstr;
35-
tag skip_ty;
36-
} answer_data;
37-
} answer;
38-
39-
#define MK_DOUBLE(n) \
40-
{ TAG_DOUBLE, { .double_precision = n } }
41-
#define MK_LONG(n) \
42-
{ TAG_LONG, { .num_long = n } }
43-
#define MK_LONGLONG(n) \
44-
{ TAG_LONGLONG, { .num_longlong = n } }
45-
#define MK_INT(n) \
46-
{ TAG_INT, { .num_int = n } }
47-
#define MK_BYTE(b) \
48-
{ TAG_BYTE, { .byte = b } }
49-
#define MK_CSTR(s) \
50-
{ TAG_CSTR, { .cstr = s } }
51-
#define MK_SKIP(ty) \
52-
{ TAG_SKIP, { .skip_ty = TAG_ ## ty } }
53-
54-
extern size_t check_rust(size_t argc, const answer* answers, va_list ap);
55-
extern size_t check_rust_copy(size_t argc, const answer* answers, va_list ap);
56-
57-
size_t test_check_rust(size_t argc, const answer* answers, ...) {
58-
size_t ret = 0;
59-
va_list ap;
60-
va_start(ap, answers);
61-
ret = check_rust(argc, answers, ap);
62-
va_end(ap);
63-
return ret;
64-
}
65-
66-
size_t test_check_rust_copy(size_t argc, const answer* answers, ...) {
22+
int test_rust(size_t (*fn)(va_list), ...) {
6723
size_t ret = 0;
6824
va_list ap;
69-
va_start(ap, answers);
70-
ret = check_rust_copy(argc, answers, ap);
25+
va_start(ap, fn);
26+
ret = fn(ap);
7127
va_end(ap);
7228
return ret;
7329
}
7430

7531
int main(int argc, char* argv[]) {
76-
answer test_alignment0[] = {MK_LONGLONG(0x01LL), MK_INT(0x02), MK_LONGLONG(0x03LL)};
77-
assert(test_check_rust(3, test_alignment0, 0x01LL, 0x02, 0x03LL) == 0);
32+
assert(test_rust(check_list_0, 0x01LL, 0x02, 0x03LL) == 0);
7833

79-
answer test_alignment1[] = {MK_INT(-1), MK_BYTE('A'), MK_BYTE('4'), MK_BYTE(';'),
80-
MK_INT(0x32), MK_INT(0x10000001), MK_CSTR("Valid!")};
81-
assert(test_check_rust(7, test_alignment1, -1, 'A', '4', ';', 0x32, 0x10000001,
82-
"Valid!") == 0);
34+
assert(test_rust(check_list_1, -1, 'A', '4', ';', 0x32, 0x10000001, "Valid!") == 0);
8335

84-
answer basic_answers[] = {MK_DOUBLE(3.14), MK_LONG(12l), MK_BYTE('a'),
85-
MK_DOUBLE(6.28), MK_CSTR("Hello"), MK_INT(42),
86-
MK_CSTR("World")};
87-
assert(test_check_rust(7, basic_answers, 3.14, 12l, 'a', 6.28, "Hello",
88-
42, "World") == 0);
36+
assert(test_rust(check_list_2, 3.14, 12l, 'a', 6.28, "Hello", 42, "World") == 0);
8937

90-
answer copy_answers[] = { MK_SKIP(DOUBLE), MK_SKIP(INT), MK_SKIP(BYTE), MK_SKIP(CSTR),
91-
MK_CSTR("Correctly skipped and copied list") };
92-
assert(test_check_rust_copy(5, copy_answers, 6.28, 16, 'A', "Skip Me!",
93-
"Correctly skipped and copied list") == 0);
38+
assert(test_rust(check_list_copy_0, 6.28, 16, 'A', "Skip Me!", "Correct") == 0);
9439
return 0;
9540
}

0 commit comments

Comments
 (0)