Skip to content

Commit 1685c18

Browse files
committed
ctest: add foreign static test
1 parent 954727f commit 1685c18

File tree

11 files changed

+86
-7
lines changed

11 files changed

+86
-7
lines changed

ctest-next/src/ffi_items.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ impl FfiItems {
6262
}
6363

6464
/// Return a list of all foreign statics found mapped by their ABI.
65-
#[cfg_attr(not(test), expect(unused))]
6665
pub(crate) fn foreign_statics(&self) -> &Vec<Static> {
6766
&self.foreign_statics
6867
}

ctest-next/src/template.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ impl CTestTemplate {
5050
/// Stores all information necessary for generation of tests for all items.
5151
#[derive(Clone, Debug, Default)]
5252
pub(crate) struct TestTemplate {
53+
pub foreign_static_tests: Vec<TestForeignStatic>,
5354
pub field_ptr_tests: Vec<TestFieldPtr>,
5455
pub field_size_offset_tests: Vec<TestFieldSizeOffset>,
5556
pub roundtrip_tests: Vec<TestRoundtrip>,
@@ -77,6 +78,7 @@ impl TestTemplate {
7778
template.populate_field_ptr_tests(&helper)?;
7879
template.populate_roundtrip_tests(&helper)?;
7980
template.populate_foreign_fn_tests(&helper)?;
81+
template.populate_foreign_static_tests(&helper)?;
8082

8183
Ok(template)
8284
}
@@ -414,6 +416,28 @@ impl TestTemplate {
414416

415417
Ok(())
416418
}
419+
420+
/// Populates tests for foreign statics, keeping track of the names of each test.
421+
fn populate_foreign_static_tests(
422+
&mut self,
423+
helper: &TranslateHelper,
424+
) -> Result<(), TranslationError> {
425+
for static_ in helper.ffi_items.foreign_statics() {
426+
let rust_ty = static_.ty.to_token_stream().to_string().into_boxed_str();
427+
428+
let item = TestForeignStatic {
429+
test_name: static_test_ident(static_.ident()),
430+
id: static_.ident().into(),
431+
c_val: helper.c_ident(static_).into_boxed_str(),
432+
rust_ty,
433+
};
434+
435+
self.foreign_static_tests.push(item.clone());
436+
self.test_idents.push(item.test_name);
437+
}
438+
439+
Ok(())
440+
}
417441
}
418442

419443
/* Many test structures have the following fields:
@@ -498,6 +522,14 @@ pub(crate) struct TestForeignFn {
498522
pub id: BoxStr,
499523
}
500524

525+
#[derive(Clone, Debug)]
526+
pub(crate) struct TestForeignStatic {
527+
pub test_name: BoxStr,
528+
pub id: BoxStr,
529+
pub c_val: BoxStr,
530+
pub rust_ty: BoxStr,
531+
}
532+
501533
fn signededness_test_ident(ident: &str) -> BoxStr {
502534
format!("ctest_signededness_{ident}").into()
503535
}
@@ -530,6 +562,10 @@ fn foreign_fn_test_ident(ident: &str) -> BoxStr {
530562
format!("ctest_foreign_fn_{ident}").into()
531563
}
532564

565+
fn static_test_ident(ident: &str) -> BoxStr {
566+
format!("ctest_static_{ident}").into()
567+
}
568+
533569
/// Wrap methods that depend on both ffi items and the generator.
534570
pub(crate) struct TranslateHelper<'a> {
535571
ffi_items: &'a FfiItems,

ctest-next/templates/test.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,12 @@ ctest_void_func ctest_foreign_fn__{{ item.id }}(void) {
137137
#ifdef _MSC_VER
138138
# pragma warning(default:4191)
139139
#endif
140+
141+
{%- for static_ in ctx.foreign_static_tests +%}
142+
143+
// Return a pointer to the static variable content.
144+
void *ctest_static__{{ static_.id }}(void) {
145+
// FIXME(ctest): Not correct due to casting the function to a data pointer.
146+
return (void *)&{{ static_.c_val }};
147+
}
148+
{%- endfor +%}

ctest-next/templates/test.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod generated_tests {
1010
#![allow(non_snake_case)]
1111
#![deny(improper_ctypes_definitions)]
1212
#[allow(unused_imports)]
13-
use std::ffi::{CStr, c_int, c_char};
13+
use std::ffi::{CStr, c_int, c_char, c_uint};
1414
use std::fmt::{Debug, LowerHex};
1515
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
1616
#[allow(unused_imports)]
@@ -327,6 +327,21 @@ mod generated_tests {
327327
check_same(actual, expected, "{{ item.id }} function pointer");
328328
}
329329
{%- endfor +%}
330+
331+
{%- for static_ in ctx.foreign_static_tests +%}
332+
333+
// Tests if the pointer to the static variable matches in both Rust and C.
334+
pub fn {{ static_.test_name }}() {
335+
extern "C" {
336+
fn ctest_static__{{ static_.id }}() -> *const {{ static_.rust_ty }};
337+
}
338+
let actual = (&raw const {{ static_.id }}).addr();
339+
let expected = unsafe {
340+
ctest_static__{{ static_.id }}().addr()
341+
};
342+
check_same(actual, expected, "{{ static_.id }} static");
343+
}
344+
{%- endfor +%}
330345
}
331346

332347
use generated_tests::*;

ctest-next/tests/input/hierarchy.out.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,9 @@ ctest_void_func ctest_foreign_fn__malloc(void) {
8080
#ifdef _MSC_VER
8181
# pragma warning(default:4191)
8282
#endif
83+
84+
// Return a pointer to the static variable content.
85+
void *ctest_static__in6addr_any(void) {
86+
// FIXME(ctest): Not correct due to casting the function to a data pointer.
87+
return (void *)&in6addr_any;
88+
}

ctest-next/tests/input/hierarchy.out.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod generated_tests {
77
#![allow(non_snake_case)]
88
#![deny(improper_ctypes_definitions)]
99
#[allow(unused_imports)]
10-
use std::ffi::{CStr, c_int, c_char};
10+
use std::ffi::{CStr, c_int, c_char, c_uint};
1111
use std::fmt::{Debug, LowerHex};
1212
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
1313
#[allow(unused_imports)]
@@ -223,6 +223,18 @@ mod generated_tests {
223223
let expected = malloc as u64;
224224
check_same(actual, expected, "malloc function pointer");
225225
}
226+
227+
// Tests if the pointer to the static variable matches in both Rust and C.
228+
pub fn ctest_static_in6addr_any() {
229+
extern "C" {
230+
fn ctest_static__in6addr_any() -> *const in6_addr;
231+
}
232+
let actual = (&raw const in6addr_any).addr();
233+
let expected = unsafe {
234+
ctest_static__in6addr_any().addr()
235+
};
236+
check_same(actual, expected, "in6addr_any static");
237+
}
226238
}
227239

228240
use generated_tests::*;
@@ -247,4 +259,5 @@ fn run_all() {
247259
ctest_signededness_in6_addr();
248260
ctest_roundtrip_in6_addr();
249261
ctest_foreign_fn_malloc();
262+
ctest_static_in6addr_any();
250263
}

ctest-next/tests/input/hierarchy/foo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ pub const ON: bool = true;
66
unsafe extern "C" {
77
pub fn malloc(size: usize) -> *mut c_void;
88

9-
static in6addr_any: in6_addr;
9+
pub static in6addr_any: in6_addr;
1010
}

ctest-next/tests/input/macro.out.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod generated_tests {
77
#![allow(non_snake_case)]
88
#![deny(improper_ctypes_definitions)]
99
#[allow(unused_imports)]
10-
use std::ffi::{CStr, c_int, c_char};
10+
use std::ffi::{CStr, c_int, c_char, c_uint};
1111
use std::fmt::{Debug, LowerHex};
1212
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
1313
#[allow(unused_imports)]

ctest-next/tests/input/simple.out.with-renames.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod generated_tests {
77
#![allow(non_snake_case)]
88
#![deny(improper_ctypes_definitions)]
99
#[allow(unused_imports)]
10-
use std::ffi::{CStr, c_int, c_char};
10+
use std::ffi::{CStr, c_int, c_char, c_uint};
1111
use std::fmt::{Debug, LowerHex};
1212
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
1313
#[allow(unused_imports)]

ctest-next/tests/input/simple.out.with-skips.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod generated_tests {
77
#![allow(non_snake_case)]
88
#![deny(improper_ctypes_definitions)]
99
#[allow(unused_imports)]
10-
use std::ffi::{CStr, c_int, c_char};
10+
use std::ffi::{CStr, c_int, c_char, c_uint};
1111
use std::fmt::{Debug, LowerHex};
1212
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
1313
#[allow(unused_imports)]

0 commit comments

Comments
 (0)