Skip to content

Commit 5d2398a

Browse files
committed
Reapply fixes
1 parent ff00738 commit 5d2398a

File tree

23 files changed

+106
-58
lines changed

23 files changed

+106
-58
lines changed

c2rust-transpile/src/rust_ast/set_span.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ impl SetSpan for Expr {
140140
RangeLimits::Closed(mut r) => r.spans[0] = s,
141141
RangeLimits::HalfOpen(mut r) => r.spans[0] = s,
142142
},
143+
Expr::RawAddr(e) => e.and_token.span = s,
143144
Expr::Reference(e) => e.and_token.span = s,
144145
Expr::Return(e) => e.return_token.span = s,
145146
Expr::Try(e) => e.question_token.span = s,

c2rust-transpile/src/translator/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4523,6 +4523,7 @@ impl<'c> Translation<'c> {
45234523
self.use_feature("raw_ref_op");
45244524
let borrow = mk().set_mutbl(mutbl).raw_borrow_expr(x);
45254525
// TODO: Change to call `ptr::as_[mut]_ptr` once that is available.
4526+
// (`array_ptr_get` feature added to nightly in January 2024)
45264527
mk().cast_expr(borrow, target_ty)
45274528
}))
45284529
}

c2rust-transpile/src/translator/operators.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ impl<'c> Translation<'c> {
901901
lrvalue: LRValue,
902902
) -> TranslationResult<WithStmts<Box<Expr>>> {
903903
let CQualTypeId { ctype, .. } = cqual_type;
904+
let ty = self.convert_type(ctype)?;
904905
let resolved_ctype = self.ast_context.resolve_type(ctype);
905906

906907
let mut unary = match name {
@@ -941,8 +942,25 @@ impl<'c> Translation<'c> {
941942
Mutability::Mutable
942943
};
943944

944-
self.use_feature("raw_ref_op");
945-
Ok(arg.map(|a| mk().set_mutbl(mutbl).raw_borrow_expr(a)))
945+
Ok(arg.map(|mut arg| {
946+
if matches!(
947+
arg_kind,
948+
CExprKind::CompoundLiteral(..) | CExprKind::Literal(..)
949+
) {
950+
// Rust does not extend the lifetime of temporaries with a raw borrow,
951+
// but will do so with a regular borrow.
952+
arg = mk().set_mutbl(mutbl).borrow_expr(arg);
953+
954+
if ctx.decay_ref.is_yes() {
955+
mk().cast_expr(arg, ty)
956+
} else {
957+
arg
958+
}
959+
} else {
960+
self.use_feature("raw_ref_op");
961+
mk().set_mutbl(mutbl).raw_borrow_expr(arg)
962+
}
963+
}))
946964
}
947965
}
948966
c_ast::UnOp::PreIncrement => self.convert_pre_increment(ctx, cqual_type, true, arg),

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ input_file: c2rust-transpile/tests/snapshots/arrays.c
1212
unused_assignments,
1313
unused_mut
1414
)]
15+
#![feature(raw_ref_op)]
1516
#[derive(Copy, Clone)]
1617
#[repr(C)]
1718
pub struct C2RustUnnamed {
@@ -79,11 +80,9 @@ pub unsafe extern "C" fn entry() {
7980
&[u8; 20],
8081
&mut [std::ffi::c_char; 20],
8182
>(b"abc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
82-
let mut past_end: *mut std::ffi::c_char = &mut *simple
83-
.as_mut_ptr()
84-
.offset(::core::mem::size_of::<[std::ffi::c_char; 9]>() as isize)
85-
as *mut std::ffi::c_char;
86-
past_end = &mut *foo.offset(8 as std::ffi::c_int as isize) as *mut std::ffi::c_char;
83+
let mut past_end: *mut std::ffi::c_char = &raw mut *(&raw mut simple as *mut std::ffi::c_char)
84+
.offset(::core::mem::size_of::<[std::ffi::c_char; 9]>() as isize);
85+
past_end = &raw mut *foo.offset(8 as std::ffi::c_int as isize);
8786
}
8887
#[no_mangle]
8988
pub unsafe extern "C" fn short_initializer() {

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,29 @@ input_file: c2rust-transpile/tests/snapshots/atomics.c
1212
unused_assignments,
1313
unused_mut
1414
)]
15-
#![feature(core_intrinsics)]
15+
#![feature(core_intrinsics, raw_ref_op)]
1616
#[no_mangle]
1717
pub unsafe extern "C" fn c11_atomics(mut x: std::ffi::c_int) -> std::ffi::c_int {
18-
*&mut x = 0 as std::ffi::c_int;
19-
::core::intrinsics::atomic_store_seqcst(&mut x, 1 as std::ffi::c_int);
20-
::core::intrinsics::atomic_load_seqcst(&mut x);
21-
::core::intrinsics::atomic_xadd_seqcst(&mut x, 2 as std::ffi::c_int);
22-
::core::intrinsics::atomic_xsub_seqcst(&mut x, 1 as std::ffi::c_int);
23-
::core::intrinsics::atomic_and_seqcst(&mut x, 0xf as std::ffi::c_int);
24-
::core::intrinsics::atomic_or_seqcst(&mut x, 0x10 as std::ffi::c_int);
25-
::core::intrinsics::atomic_nand_seqcst(&mut x, 0xff as std::ffi::c_int);
26-
::core::intrinsics::atomic_xchg_seqcst(&mut x, 42 as std::ffi::c_int);
18+
*&raw mut x = 0 as std::ffi::c_int;
19+
::core::intrinsics::atomic_store_seqcst(&raw mut x, 1 as std::ffi::c_int);
20+
::core::intrinsics::atomic_load_seqcst(&raw mut x);
21+
::core::intrinsics::atomic_xadd_seqcst(&raw mut x, 2 as std::ffi::c_int);
22+
::core::intrinsics::atomic_xsub_seqcst(&raw mut x, 1 as std::ffi::c_int);
23+
::core::intrinsics::atomic_and_seqcst(&raw mut x, 0xf as std::ffi::c_int);
24+
::core::intrinsics::atomic_or_seqcst(&raw mut x, 0x10 as std::ffi::c_int);
25+
::core::intrinsics::atomic_nand_seqcst(&raw mut x, 0xff as std::ffi::c_int);
26+
::core::intrinsics::atomic_xchg_seqcst(&raw mut x, 42 as std::ffi::c_int);
2727
let mut expected: std::ffi::c_int = 42 as std::ffi::c_int;
2828
let mut desired: std::ffi::c_int = 100 as std::ffi::c_int;
29-
let fresh0 = ::core::intrinsics::atomic_cxchg_seqcst_seqcst(&mut x, *&mut expected, desired);
30-
*&mut expected = fresh0.0;
29+
let fresh0 =
30+
::core::intrinsics::atomic_cxchg_seqcst_seqcst(&raw mut x, *&raw mut expected, desired);
31+
*&raw mut expected = fresh0.0;
3132
fresh0.1;
3233
expected = 100 as std::ffi::c_int;
3334
desired = 200 as std::ffi::c_int;
3435
let fresh1 =
35-
::core::intrinsics::atomic_cxchgweak_seqcst_seqcst(&mut x, *&mut expected, desired);
36-
*&mut expected = fresh1.0;
36+
::core::intrinsics::atomic_cxchgweak_seqcst_seqcst(&raw mut x, *&raw mut expected, desired);
37+
*&raw mut expected = fresh1.0;
3738
fresh1.1;
3839
return x;
3940
}

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ input_file: c2rust-transpile/tests/snapshots/exprs.c
1212
unused_assignments,
1313
unused_mut
1414
)]
15+
#![feature(raw_ref_op)]
1516
extern "C" {
1617
fn puts(str: *const std::ffi::c_char) -> std::ffi::c_int;
1718
}
@@ -30,7 +31,7 @@ pub unsafe extern "C" fn unary_without_side_effect() {
3031
i;
3132
!i;
3233
(i == 0) as std::ffi::c_int;
33-
&mut i;
34+
&raw mut i;
3435
i;
3536
i += 1;
3637
i -= 1;
@@ -44,10 +45,11 @@ pub unsafe extern "C" fn unary_with_side_effect() {
4445
side_effect();
4546
!side_effect();
4647
(side_effect() == 0) as std::ffi::c_int;
47-
&*(b"\0" as *const u8 as *const std::ffi::c_char).offset(::core::mem::transmute::<
48+
&raw const *(b"\0" as *const u8 as *const std::ffi::c_char).offset(::core::mem::transmute::<
4849
unsafe extern "C" fn() -> std::ffi::c_int,
4950
unsafe extern "C" fn() -> std::ffi::c_int,
50-
>(side_effect)() as isize) as *const std::ffi::c_char;
51+
>(side_effect)()
52+
as isize);
5153
*arr[side_effect() as usize];
5254
arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(1);
5355
arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(-1);

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ input_file: c2rust-transpile/tests/snapshots/macros.c
1212
unused_assignments,
1313
unused_mut
1414
)]
15+
#![feature(raw_ref_op)]
1516
extern "C" {
1617
fn extern_fn() -> std::ffi::c_int;
1718
}
@@ -62,8 +63,7 @@ pub const NESTED_STRUCT: S = unsafe {
6263
};
6364
pub const PARENS: std::ffi::c_int = unsafe { NESTED_INT * (LITERAL_CHAR + true_0) };
6465
pub const PTR_ARITHMETIC: *const std::ffi::c_char = unsafe {
65-
LITERAL_STR
66-
.as_ptr()
66+
(&raw const LITERAL_STR as *const std::ffi::c_char)
6767
.offset(5 as std::ffi::c_int as isize)
6868
.offset(-(3 as std::ffi::c_int as isize))
6969
};
@@ -92,7 +92,8 @@ pub unsafe extern "C" fn local_muts() {
9292
let mut literal_bool: bool = LITERAL_BOOL != 0;
9393
let mut literal_float: std::ffi::c_float = LITERAL_FLOAT as std::ffi::c_float;
9494
let mut literal_char: std::ffi::c_char = LITERAL_CHAR as std::ffi::c_char;
95-
let mut literal_str_ptr: *const std::ffi::c_char = LITERAL_STR.as_ptr();
95+
let mut literal_str_ptr: *const std::ffi::c_char =
96+
&raw const LITERAL_STR as *const std::ffi::c_char;
9697
let mut literal_str: [std::ffi::c_char; 6] = LITERAL_STR;
9798
let mut literal_array: [std::ffi::c_int; 3] = [
9899
1 as std::ffi::c_int,
@@ -104,7 +105,8 @@ pub unsafe extern "C" fn local_muts() {
104105
let mut nested_bool: bool = NESTED_BOOL != 0;
105106
let mut nested_float: std::ffi::c_float = NESTED_FLOAT as std::ffi::c_float;
106107
let mut nested_char: std::ffi::c_char = NESTED_CHAR as std::ffi::c_char;
107-
let mut nested_str_ptr: *const std::ffi::c_char = NESTED_STR.as_ptr();
108+
let mut nested_str_ptr: *const std::ffi::c_char =
109+
&raw const NESTED_STR as *const std::ffi::c_char;
108110
let mut nested_str: [std::ffi::c_char; 6] = NESTED_STR;
109111
let mut nested_array: [std::ffi::c_int; 3] = [
110112
1 as std::ffi::c_int,
@@ -129,10 +131,9 @@ pub unsafe extern "C" fn local_muts() {
129131
let mut str_concatenation: [std::ffi::c_char; 18] =
130132
*::core::mem::transmute::<&[u8; 18], &mut [std::ffi::c_char; 18]>(b"hello hello world\0");
131133
let mut builtin: std::ffi::c_int = (LITERAL_INT as std::ffi::c_uint).leading_zeros() as i32;
132-
let mut ref_indexing: *const std::ffi::c_char = &*NESTED_STR
133-
.as_ptr()
134-
.offset(LITERAL_FLOAT as std::ffi::c_int as isize)
135-
as *const std::ffi::c_char;
134+
let mut ref_indexing: *const std::ffi::c_char = &raw const *(&raw const NESTED_STR
135+
as *const std::ffi::c_char)
136+
.offset(LITERAL_FLOAT as std::ffi::c_int as isize);
136137
let mut ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
137138
let mut ternary: std::ffi::c_int = if LITERAL_BOOL != 0 {
138139
1 as std::ffi::c_int
@@ -148,7 +149,8 @@ pub unsafe extern "C" fn local_consts() {
148149
let literal_bool: bool = LITERAL_BOOL != 0;
149150
let literal_float: std::ffi::c_float = LITERAL_FLOAT as std::ffi::c_float;
150151
let literal_char: std::ffi::c_char = LITERAL_CHAR as std::ffi::c_char;
151-
let literal_str_ptr: *const std::ffi::c_char = LITERAL_STR.as_ptr();
152+
let literal_str_ptr: *const std::ffi::c_char =
153+
&raw const LITERAL_STR as *const std::ffi::c_char;
152154
let literal_str: [std::ffi::c_char; 6] = LITERAL_STR;
153155
let literal_array: [std::ffi::c_int; 3] = [
154156
1 as std::ffi::c_int,
@@ -160,7 +162,7 @@ pub unsafe extern "C" fn local_consts() {
160162
let nested_bool: bool = NESTED_BOOL != 0;
161163
let nested_float: std::ffi::c_float = NESTED_FLOAT as std::ffi::c_float;
162164
let nested_char: std::ffi::c_char = NESTED_CHAR as std::ffi::c_char;
163-
let nested_str_ptr: *const std::ffi::c_char = NESTED_STR.as_ptr();
165+
let nested_str_ptr: *const std::ffi::c_char = &raw const NESTED_STR as *const std::ffi::c_char;
164166
let nested_str: [std::ffi::c_char; 6] = NESTED_STR;
165167
let nested_array: [std::ffi::c_int; 3] = [
166168
1 as std::ffi::c_int,
@@ -185,10 +187,9 @@ pub unsafe extern "C" fn local_consts() {
185187
let str_concatenation: [std::ffi::c_char; 18] =
186188
*::core::mem::transmute::<&[u8; 18], &[std::ffi::c_char; 18]>(b"hello hello world\0");
187189
let builtin: std::ffi::c_int = (LITERAL_INT as std::ffi::c_uint).leading_zeros() as i32;
188-
let ref_indexing: *const std::ffi::c_char = &*NESTED_STR
189-
.as_ptr()
190-
.offset(LITERAL_FLOAT as std::ffi::c_int as isize)
191-
as *const std::ffi::c_char;
190+
let ref_indexing: *const std::ffi::c_char = &raw const *(&raw const NESTED_STR
191+
as *const std::ffi::c_char)
192+
.offset(LITERAL_FLOAT as std::ffi::c_int as isize);
192193
let ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
193194
let ternary: std::ffi::c_int = if LITERAL_BOOL != 0 {
194195
1 as std::ffi::c_int
@@ -203,7 +204,8 @@ static mut global_static_const_literal_bool: bool = LITERAL_BOOL != 0;
203204
static mut global_static_const_literal_float: std::ffi::c_float =
204205
LITERAL_FLOAT as std::ffi::c_float;
205206
static mut global_static_const_literal_char: std::ffi::c_char = LITERAL_CHAR as std::ffi::c_char;
206-
static mut global_static_const_literal_str_ptr: *const std::ffi::c_char = LITERAL_STR.as_ptr();
207+
static mut global_static_const_literal_str_ptr: *const std::ffi::c_char =
208+
&raw const LITERAL_STR as *const std::ffi::c_char;
207209
static mut global_static_const_literal_str: [std::ffi::c_char; 6] = LITERAL_STR;
208210
static mut global_static_const_literal_array: [std::ffi::c_int; 3] = [
209211
1 as std::ffi::c_int,
@@ -215,7 +217,8 @@ static mut global_static_const_nested_int: std::ffi::c_int = NESTED_INT;
215217
static mut global_static_const_nested_bool: bool = NESTED_BOOL != 0;
216218
static mut global_static_const_nested_float: std::ffi::c_float = NESTED_FLOAT as std::ffi::c_float;
217219
static mut global_static_const_nested_char: std::ffi::c_char = NESTED_CHAR as std::ffi::c_char;
218-
static mut global_static_const_nested_str_ptr: *const std::ffi::c_char = NESTED_STR.as_ptr();
220+
static mut global_static_const_nested_str_ptr: *const std::ffi::c_char =
221+
&raw const NESTED_STR as *const std::ffi::c_char;
219222
static mut global_static_const_nested_str: [std::ffi::c_char; 6] = NESTED_STR;
220223
static mut global_static_const_nested_array: [std::ffi::c_int; 3] = [
221224
1 as std::ffi::c_int,
@@ -245,7 +248,7 @@ static mut global_static_const_str_concatenation: [std::ffi::c_char; 18] = unsaf
245248
static mut global_static_const_builtin: std::ffi::c_int =
246249
(LITERAL_INT as std::ffi::c_uint).leading_zeros() as i32;
247250
static mut global_static_const_ref_indexing: *const std::ffi::c_char = 0 as *const std::ffi::c_char;
248-
static mut global_static_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S;
251+
static mut global_static_const_ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
249252
static mut global_static_const_ternary: std::ffi::c_int = 0;
250253
static mut global_static_const_member: std::ffi::c_int = 0;
251254
#[no_mangle]
@@ -259,7 +262,8 @@ pub static mut global_const_literal_float: std::ffi::c_float = LITERAL_FLOAT as
259262
#[no_mangle]
260263
pub static mut global_const_literal_char: std::ffi::c_char = LITERAL_CHAR as std::ffi::c_char;
261264
#[no_mangle]
262-
pub static mut global_const_literal_str_ptr: *const std::ffi::c_char = LITERAL_STR.as_ptr();
265+
pub static mut global_const_literal_str_ptr: *const std::ffi::c_char =
266+
&raw const LITERAL_STR as *const std::ffi::c_char;
263267
#[no_mangle]
264268
pub static mut global_const_literal_str: [std::ffi::c_char; 6] = LITERAL_STR;
265269
#[no_mangle]
@@ -279,7 +283,8 @@ pub static mut global_const_nested_float: std::ffi::c_float = NESTED_FLOAT as st
279283
#[no_mangle]
280284
pub static mut global_const_nested_char: std::ffi::c_char = NESTED_CHAR as std::ffi::c_char;
281285
#[no_mangle]
282-
pub static mut global_const_nested_str_ptr: *const std::ffi::c_char = NESTED_STR.as_ptr();
286+
pub static mut global_const_nested_str_ptr: *const std::ffi::c_char =
287+
&raw const NESTED_STR as *const std::ffi::c_char;
283288
#[no_mangle]
284289
pub static mut global_const_nested_str: [std::ffi::c_char; 6] = NESTED_STR;
285290
#[no_mangle]
@@ -324,7 +329,7 @@ pub static mut global_const_builtin: std::ffi::c_int =
324329
#[no_mangle]
325330
pub static mut global_const_ref_indexing: *const std::ffi::c_char = 0 as *const std::ffi::c_char;
326331
#[no_mangle]
327-
pub static mut global_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S;
332+
pub static mut global_const_ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
328333
#[no_mangle]
329334
pub static mut global_const_ternary: std::ffi::c_int = 0;
330335
#[no_mangle]
@@ -357,7 +362,7 @@ pub static mut fns: fn_ptrs = {
357362
init
358363
};
359364
#[no_mangle]
360-
pub static mut p: *const fn_ptrs = unsafe { &fns as *const fn_ptrs };
365+
pub static mut p: *const fn_ptrs = unsafe { &raw const fns };
361366
pub const ZSTD_WINDOWLOG_MAX_32: std::ffi::c_int = unsafe { 30 as std::ffi::c_int };
362367
pub const ZSTD_WINDOWLOG_MAX_64: std::ffi::c_int = unsafe { 31 as std::ffi::c_int };
363368
#[no_mangle]
@@ -371,7 +376,7 @@ pub unsafe extern "C" fn test_zstd() -> U64 {
371376
#[no_mangle]
372377
pub unsafe extern "C" fn stmt_expr_inc() -> std::ffi::c_int {
373378
let mut a: std::ffi::c_int = 0 as std::ffi::c_int;
374-
let mut b: *mut std::ffi::c_int = &mut a;
379+
let mut b: *mut std::ffi::c_int = &raw mut a;
375380
({
376381
*b += 1;
377382
*b;
@@ -423,10 +428,9 @@ unsafe extern "C" fn run_static_initializers() {
423428
global_static_const_indexing =
424429
(*::core::mem::transmute::<&[u8; 6], &[std::ffi::c_char; 6]>(b"hello\0"))
425430
[LITERAL_FLOAT as std::ffi::c_int as usize];
426-
global_static_const_ref_indexing = &*NESTED_STR
427-
.as_ptr()
428-
.offset(LITERAL_FLOAT as std::ffi::c_int as isize)
429-
as *const std::ffi::c_char;
431+
global_static_const_ref_indexing = &raw const *(&raw const NESTED_STR
432+
as *const std::ffi::c_char)
433+
.offset(LITERAL_FLOAT as std::ffi::c_int as isize);
430434
global_static_const_ternary = if LITERAL_BOOL != 0 {
431435
1 as std::ffi::c_int
432436
} else {
@@ -437,10 +441,8 @@ unsafe extern "C" fn run_static_initializers() {
437441
global_const_indexing =
438442
(*::core::mem::transmute::<&[u8; 6], &[std::ffi::c_char; 6]>(b"hello\0"))
439443
[LITERAL_FLOAT as std::ffi::c_int as usize];
440-
global_const_ref_indexing = &*NESTED_STR
441-
.as_ptr()
442-
.offset(LITERAL_FLOAT as std::ffi::c_int as isize)
443-
as *const std::ffi::c_char;
444+
global_const_ref_indexing = &raw const *(&raw const NESTED_STR as *const std::ffi::c_char)
445+
.offset(LITERAL_FLOAT as std::ffi::c_int as isize);
444446
global_const_ternary = if LITERAL_BOOL != 0 {
445447
1 as std::ffi::c_int
446448
} else {

tests/arrays/src/test_arrays.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! feature_raw_ref_op
2+
13
use crate::arrays::rust_entry;
24
use crate::incomplete_arrays::{rust_check_some_ints, rust_entry2, rust_test_sized_array};
35
use crate::variable_arrays::{rust_alloca_arrays, rust_variable_arrays};

tests/builtins/src/test_builtins.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! feature_core_intrinsics
1+
//! feature_core_intrinsics, feature_raw_ref_op
22
33
use crate::atomics::{rust_atomics_entry, rust_new_atomics};
44
use crate::math::{rust_ffs, rust_ffsl, rust_ffsll, rust_isfinite, rust_isinf_sign, rust_isnan};

tests/casts/src/test_casts.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! feature_raw_ref_op
2+
13
use crate::cast_funptr::{rust_entry, rust_get_identity, rust_identity};
24
use crate::casts::rust_cast_stuff;
35

0 commit comments

Comments
 (0)