Skip to content

Commit b69a268

Browse files
committed
transpile: save override_tys in fn convert_expr in a map and use them for const macros
1 parent dc8b924 commit b69a268

File tree

2 files changed

+58
-33
lines changed

2 files changed

+58
-33
lines changed

c2rust-transpile/src/translator/mod.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use std::path::{self, PathBuf};
77
use std::result::Result; // To override syn::Result from glob import
88

99
use dtoa;
10-
1110
use failure::{err_msg, format_err, Fail};
1211
use indexmap::indexmap;
1312
use indexmap::{IndexMap, IndexSet};
@@ -261,6 +260,15 @@ pub struct Translation<'c> {
261260
potential_flexible_array_members: RefCell<IndexSet<CDeclId>>,
262261
macro_expansions: RefCell<IndexMap<CDeclId, Option<MacroExpansion>>>,
263262

263+
/// For every call to [`Self::convert_expr`],
264+
/// we record the `override_ty` that is used for that expression.
265+
///
266+
/// This is needed [`Self::recreate_const_macro_from_expansions`]
267+
/// when we call [`Self::convert_expr`] for each of the macro expansions,
268+
/// as unlike normal [`Self::convert_expr`]s, there is no surrounding context
269+
/// higher in the call stack calculating the `override_ty`.
270+
expr_override_tys: RefCell<HashMap<CExprId, CQualTypeId>>,
271+
264272
// Comment support
265273
pub comment_context: CommentContext, // Incoming comments
266274
pub comment_store: RefCell<CommentStore>, // Outgoing comments
@@ -1212,6 +1220,7 @@ impl<'c> Translation<'c> {
12121220
function_context: RefCell::new(FuncContext::new()),
12131221
potential_flexible_array_members: RefCell::new(IndexSet::new()),
12141222
macro_expansions: RefCell::new(IndexMap::new()),
1223+
expr_override_tys: Default::default(),
12151224
comment_context,
12161225
comment_store: RefCell::new(CommentStore::new()),
12171226
spans: HashMap::new(),
@@ -2193,7 +2202,9 @@ impl<'c> Translation<'c> {
21932202
.kind
21942203
.get_type()
21952204
.ok_or_else(|| format_err!("Invalid expression type"))?;
2196-
let expr = self.convert_expr(ctx, id, None)?;
2205+
let override_ty = self.expr_override_tys.borrow().get(&id).copied();
2206+
let expr = self.convert_expr(ctx, id, override_ty)?;
2207+
let ty = override_ty.map(|ty| ty.ctype).unwrap_or(ty);
21972208

21982209
// Join ty and cur_ty to the smaller of the two types. If the
21992210
// types are not cast-compatible, abort the fold.
@@ -3284,6 +3295,12 @@ impl<'c> Translation<'c> {
32843295
expr_id: CExprId,
32853296
override_ty: Option<CQualTypeId>,
32863297
) -> TranslationResult<WithStmts<Box<Expr>>> {
3298+
if let Some(override_ty) = override_ty {
3299+
self.expr_override_tys
3300+
.borrow_mut()
3301+
.insert(expr_id, override_ty);
3302+
}
3303+
32873304
let Located {
32883305
loc: src_loc,
32893306
kind: expr_kind,

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

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ pub struct fn_ptrs {
2929
pub fn2: Option<unsafe extern "C" fn(std::ffi::c_int) -> std::ffi::c_int>,
3030
}
3131
pub type zstd_platform_dependent_type = std::ffi::c_long;
32-
pub const UINTPTR_MAX: std::ffi::c_ulong = 18446744073709551615 as std::ffi::c_ulong;
32+
pub const UINTPTR_MAX: uintptr_t = 18446744073709551615 as uintptr_t;
3333
pub const true_0: std::ffi::c_int = 1 as std::ffi::c_int;
3434
pub const LITERAL_INT: std::ffi::c_int = 0xffff as std::ffi::c_int;
3535
pub const LITERAL_BOOL: std::ffi::c_int = true_0;
36-
pub const LITERAL_FLOAT: std::ffi::c_double = 3.14f64;
36+
pub const LITERAL_FLOAT: std::ffi::c_float = 3.14f32;
3737
pub const LITERAL_CHAR: std::ffi::c_int = 'x' as i32;
3838
pub const LITERAL_STR: [std::ffi::c_char; 6] =
3939
unsafe { ::core::mem::transmute::<[u8; 6], [std::ffi::c_char; 6]>(*b"hello\0") };
@@ -45,7 +45,7 @@ pub const LITERAL_STRUCT: S = {
4545
};
4646
pub const NESTED_INT: std::ffi::c_int = LITERAL_INT;
4747
pub const NESTED_BOOL: std::ffi::c_int = LITERAL_BOOL;
48-
pub const NESTED_FLOAT: std::ffi::c_double = LITERAL_FLOAT;
48+
pub const NESTED_FLOAT: std::ffi::c_float = LITERAL_FLOAT;
4949
pub const NESTED_CHAR: std::ffi::c_int = LITERAL_CHAR;
5050
pub const NESTED_STR: [std::ffi::c_char; 6] = LITERAL_STR;
5151
pub const NESTED_STRUCT: S = LITERAL_STRUCT;
@@ -60,9 +60,10 @@ pub const WIDENING_CAST: std::ffi::c_ulonglong = LITERAL_INT as std::ffi::c_ulon
6060
pub const CONVERSION_CAST: std::ffi::c_double = LITERAL_INT as std::ffi::c_double;
6161
pub const STMT_EXPR: std::ffi::c_float = ({
6262
let mut builtin: std::ffi::c_int = (LITERAL_INT as std::ffi::c_uint).leading_zeros() as i32;
63-
let mut indexing: std::ffi::c_char = NESTED_STR[LITERAL_FLOAT as std::ffi::c_int as usize];
63+
let mut indexing: std::ffi::c_char =
64+
NESTED_STR[LITERAL_FLOAT as std::ffi::c_double as std::ffi::c_int as usize];
6465
let mut mixed: std::ffi::c_float = (LITERAL_INT as std::ffi::c_double
65-
+ NESTED_FLOAT * LITERAL_CHAR as std::ffi::c_double
66+
+ NESTED_FLOAT as std::ffi::c_double * LITERAL_CHAR as std::ffi::c_double
6667
- true_0 as std::ffi::c_double) as std::ffi::c_float;
6768
let mut i: std::ffi::c_int = 0 as std::ffi::c_int;
6869
while i < builtin {
@@ -75,7 +76,7 @@ pub const STMT_EXPR: std::ffi::c_float = ({
7576
pub unsafe extern "C" fn local_muts() {
7677
let mut literal_int: std::ffi::c_int = LITERAL_INT;
7778
let mut literal_bool: bool = LITERAL_BOOL != 0;
78-
let mut literal_float: std::ffi::c_float = LITERAL_FLOAT as std::ffi::c_float;
79+
let mut literal_float: std::ffi::c_float = LITERAL_FLOAT;
7980
let mut literal_char: std::ffi::c_char = LITERAL_CHAR as std::ffi::c_char;
8081
let mut literal_str_ptr: *const std::ffi::c_char = LITERAL_STR.as_ptr();
8182
let mut literal_str: [std::ffi::c_char; 6] = LITERAL_STR;
@@ -87,7 +88,7 @@ pub unsafe extern "C" fn local_muts() {
8788
let mut literal_struct: S = LITERAL_STRUCT;
8889
let mut nested_int: std::ffi::c_int = NESTED_INT;
8990
let mut nested_bool: bool = NESTED_BOOL != 0;
90-
let mut nested_float: std::ffi::c_float = NESTED_FLOAT as std::ffi::c_float;
91+
let mut nested_float: std::ffi::c_float = NESTED_FLOAT;
9192
let mut nested_char: std::ffi::c_char = NESTED_CHAR as std::ffi::c_char;
9293
let mut nested_str_ptr: *const std::ffi::c_char = NESTED_STR.as_ptr();
9394
let mut nested_str: [std::ffi::c_char; 6] = NESTED_STR;
@@ -98,23 +99,25 @@ pub unsafe extern "C" fn local_muts() {
9899
];
99100
let mut nested_struct: S = NESTED_STRUCT;
100101
let mut int_arithmetic: std::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as std::ffi::c_int;
101-
let mut mixed_arithmetic: std::ffi::c_float =
102-
(LITERAL_INT as std::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as std::ffi::c_double
103-
- true_0 as std::ffi::c_double) as std::ffi::c_float;
102+
let mut mixed_arithmetic: std::ffi::c_float = (LITERAL_INT as std::ffi::c_double
103+
+ NESTED_FLOAT as std::ffi::c_double * LITERAL_CHAR as std::ffi::c_double
104+
- true_0 as std::ffi::c_double)
105+
as std::ffi::c_float;
104106
let mut parens: std::ffi::c_int = PARENS;
105107
let mut ptr_arithmetic: *const std::ffi::c_char = PTR_ARITHMETIC;
106108
let mut widening_cast: std::ffi::c_ulonglong = WIDENING_CAST;
107109
let mut narrowing_cast: std::ffi::c_char = LITERAL_INT as std::ffi::c_char;
108110
let mut conversion_cast: std::ffi::c_double = CONVERSION_CAST;
109-
let mut indexing: std::ffi::c_char = NESTED_STR[LITERAL_FLOAT as std::ffi::c_int as usize];
111+
let mut indexing: std::ffi::c_char =
112+
NESTED_STR[LITERAL_FLOAT as std::ffi::c_double as std::ffi::c_int as usize];
110113
let mut str_concatenation_ptr: *const std::ffi::c_char =
111114
b"hello hello world\0" as *const u8 as *const std::ffi::c_char;
112115
let mut str_concatenation: [std::ffi::c_char; 18] =
113116
::core::mem::transmute::<[u8; 18], [std::ffi::c_char; 18]>(*b"hello hello world\0");
114117
let mut builtin: std::ffi::c_int = (LITERAL_INT as std::ffi::c_uint).leading_zeros() as i32;
115118
let mut ref_indexing: *const std::ffi::c_char = &*NESTED_STR
116119
.as_ptr()
117-
.offset(LITERAL_FLOAT as std::ffi::c_int as isize)
120+
.offset(LITERAL_FLOAT as std::ffi::c_double as std::ffi::c_int as isize)
118121
as *const std::ffi::c_char;
119122
let mut ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
120123
let mut ternary: std::ffi::c_int = if LITERAL_BOOL != 0 {
@@ -129,7 +132,7 @@ pub unsafe extern "C" fn local_muts() {
129132
pub unsafe extern "C" fn local_consts() {
130133
let literal_int: std::ffi::c_int = LITERAL_INT;
131134
let literal_bool: bool = LITERAL_BOOL != 0;
132-
let literal_float: std::ffi::c_float = LITERAL_FLOAT as std::ffi::c_float;
135+
let literal_float: std::ffi::c_float = LITERAL_FLOAT;
133136
let literal_char: std::ffi::c_char = LITERAL_CHAR as std::ffi::c_char;
134137
let literal_str_ptr: *const std::ffi::c_char = LITERAL_STR.as_ptr();
135138
let literal_str: [std::ffi::c_char; 6] = LITERAL_STR;
@@ -141,7 +144,7 @@ pub unsafe extern "C" fn local_consts() {
141144
let literal_struct: S = LITERAL_STRUCT;
142145
let nested_int: std::ffi::c_int = NESTED_INT;
143146
let nested_bool: bool = NESTED_BOOL != 0;
144-
let nested_float: std::ffi::c_float = NESTED_FLOAT as std::ffi::c_float;
147+
let nested_float: std::ffi::c_float = NESTED_FLOAT;
145148
let nested_char: std::ffi::c_char = NESTED_CHAR as std::ffi::c_char;
146149
let nested_str_ptr: *const std::ffi::c_char = NESTED_STR.as_ptr();
147150
let nested_str: [std::ffi::c_char; 6] = NESTED_STR;
@@ -152,23 +155,25 @@ pub unsafe extern "C" fn local_consts() {
152155
];
153156
let nested_struct: S = NESTED_STRUCT;
154157
let int_arithmetic: std::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as std::ffi::c_int;
155-
let mixed_arithmetic: std::ffi::c_float =
156-
(LITERAL_INT as std::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as std::ffi::c_double
157-
- true_0 as std::ffi::c_double) as std::ffi::c_float;
158+
let mixed_arithmetic: std::ffi::c_float = (LITERAL_INT as std::ffi::c_double
159+
+ NESTED_FLOAT as std::ffi::c_double * LITERAL_CHAR as std::ffi::c_double
160+
- true_0 as std::ffi::c_double)
161+
as std::ffi::c_float;
158162
let parens: std::ffi::c_int = PARENS;
159163
let ptr_arithmetic: *const std::ffi::c_char = PTR_ARITHMETIC;
160164
let widening_cast: std::ffi::c_ulonglong = WIDENING_CAST;
161165
let narrowing_cast: std::ffi::c_char = LITERAL_INT as std::ffi::c_char;
162166
let conversion_cast: std::ffi::c_double = CONVERSION_CAST;
163-
let indexing: std::ffi::c_char = NESTED_STR[LITERAL_FLOAT as std::ffi::c_int as usize];
167+
let indexing: std::ffi::c_char =
168+
NESTED_STR[LITERAL_FLOAT as std::ffi::c_double as std::ffi::c_int as usize];
164169
let str_concatenation_ptr: *const std::ffi::c_char =
165170
b"hello hello world\0" as *const u8 as *const std::ffi::c_char;
166171
let str_concatenation: [std::ffi::c_char; 18] =
167172
::core::mem::transmute::<[u8; 18], [std::ffi::c_char; 18]>(*b"hello hello world\0");
168173
let builtin: std::ffi::c_int = (LITERAL_INT as std::ffi::c_uint).leading_zeros() as i32;
169174
let ref_indexing: *const std::ffi::c_char = &*NESTED_STR
170175
.as_ptr()
171-
.offset(LITERAL_FLOAT as std::ffi::c_int as isize)
176+
.offset(LITERAL_FLOAT as std::ffi::c_double as std::ffi::c_int as isize)
172177
as *const std::ffi::c_char;
173178
let ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
174179
let ternary: std::ffi::c_int = if LITERAL_BOOL != 0 {
@@ -181,8 +186,7 @@ pub unsafe extern "C" fn local_consts() {
181186
}
182187
static mut global_static_const_literal_int: std::ffi::c_int = LITERAL_INT;
183188
static mut global_static_const_literal_bool: bool = LITERAL_BOOL != 0;
184-
static mut global_static_const_literal_float: std::ffi::c_float =
185-
LITERAL_FLOAT as std::ffi::c_float;
189+
static mut global_static_const_literal_float: std::ffi::c_float = LITERAL_FLOAT;
186190
static mut global_static_const_literal_char: std::ffi::c_char = LITERAL_CHAR as std::ffi::c_char;
187191
static mut global_static_const_literal_str_ptr: *const std::ffi::c_char = LITERAL_STR.as_ptr();
188192
static mut global_static_const_literal_str: [std::ffi::c_char; 6] = LITERAL_STR;
@@ -194,7 +198,7 @@ static mut global_static_const_literal_array: [std::ffi::c_int; 3] = [
194198
static mut global_static_const_literal_struct: S = LITERAL_STRUCT;
195199
static mut global_static_const_nested_int: std::ffi::c_int = NESTED_INT;
196200
static mut global_static_const_nested_bool: bool = NESTED_BOOL != 0;
197-
static mut global_static_const_nested_float: std::ffi::c_float = NESTED_FLOAT as std::ffi::c_float;
201+
static mut global_static_const_nested_float: std::ffi::c_float = NESTED_FLOAT;
198202
static mut global_static_const_nested_char: std::ffi::c_char = NESTED_CHAR as std::ffi::c_char;
199203
static mut global_static_const_nested_str_ptr: *const std::ffi::c_char = NESTED_STR.as_ptr();
200204
static mut global_static_const_nested_str: [std::ffi::c_char; 6] = NESTED_STR;
@@ -207,7 +211,8 @@ static mut global_static_const_nested_struct: S = NESTED_STRUCT;
207211
static mut global_static_const_int_arithmetic: std::ffi::c_int =
208212
NESTED_INT + LITERAL_INT + 1 as std::ffi::c_int;
209213
static mut global_static_const_mixed_arithmetic: std::ffi::c_float =
210-
(LITERAL_INT as std::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as std::ffi::c_double
214+
(LITERAL_INT as std::ffi::c_double
215+
+ NESTED_FLOAT as std::ffi::c_double * LITERAL_CHAR as std::ffi::c_double
211216
- true_0 as std::ffi::c_double) as std::ffi::c_float;
212217
static mut global_static_const_parens: std::ffi::c_int = PARENS;
213218
static mut global_static_const_ptr_arithmetic: *const std::ffi::c_char =
@@ -233,7 +238,7 @@ pub static mut global_const_literal_int: std::ffi::c_int = LITERAL_INT;
233238
#[no_mangle]
234239
pub static mut global_const_literal_bool: bool = LITERAL_BOOL != 0;
235240
#[no_mangle]
236-
pub static mut global_const_literal_float: std::ffi::c_float = LITERAL_FLOAT as std::ffi::c_float;
241+
pub static mut global_const_literal_float: std::ffi::c_float = LITERAL_FLOAT;
237242
#[no_mangle]
238243
pub static mut global_const_literal_char: std::ffi::c_char = LITERAL_CHAR as std::ffi::c_char;
239244
#[no_mangle]
@@ -253,7 +258,7 @@ pub static mut global_const_nested_int: std::ffi::c_int = NESTED_INT;
253258
#[no_mangle]
254259
pub static mut global_const_nested_bool: bool = NESTED_BOOL != 0;
255260
#[no_mangle]
256-
pub static mut global_const_nested_float: std::ffi::c_float = NESTED_FLOAT as std::ffi::c_float;
261+
pub static mut global_const_nested_float: std::ffi::c_float = NESTED_FLOAT;
257262
#[no_mangle]
258263
pub static mut global_const_nested_char: std::ffi::c_char = NESTED_CHAR as std::ffi::c_char;
259264
#[no_mangle]
@@ -273,7 +278,8 @@ pub static mut global_const_int_arithmetic: std::ffi::c_int =
273278
NESTED_INT + LITERAL_INT + 1 as std::ffi::c_int;
274279
#[no_mangle]
275280
pub static mut global_const_mixed_arithmetic: std::ffi::c_float =
276-
(LITERAL_INT as std::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as std::ffi::c_double
281+
(LITERAL_INT as std::ffi::c_double
282+
+ NESTED_FLOAT as std::ffi::c_double * LITERAL_CHAR as std::ffi::c_double
277283
- true_0 as std::ffi::c_double) as std::ffi::c_float;
278284
#[no_mangle]
279285
pub static mut global_const_parens: std::ffi::c_int = PARENS;
@@ -388,14 +394,15 @@ pub unsafe extern "C" fn use_local_value() -> std::ffi::c_int {
388394
}
389395
#[no_mangle]
390396
pub unsafe extern "C" fn use_portable_type(mut len: uintptr_t) -> bool {
391-
return len <= (UINTPTR_MAX as uintptr_t).wrapping_div(2 as uintptr_t);
397+
return len <= UINTPTR_MAX.wrapping_div(2 as uintptr_t);
392398
}
393399
unsafe extern "C" fn run_static_initializers() {
394400
global_static_const_ptr_arithmetic = PTR_ARITHMETIC;
395-
global_static_const_indexing = NESTED_STR[LITERAL_FLOAT as std::ffi::c_int as usize];
401+
global_static_const_indexing =
402+
NESTED_STR[LITERAL_FLOAT as std::ffi::c_double as std::ffi::c_int as usize];
396403
global_static_const_ref_indexing = &*NESTED_STR
397404
.as_ptr()
398-
.offset(LITERAL_FLOAT as std::ffi::c_int as isize)
405+
.offset(LITERAL_FLOAT as std::ffi::c_double as std::ffi::c_int as isize)
399406
as *const std::ffi::c_char;
400407
global_static_const_ternary = if LITERAL_BOOL != 0 {
401408
1 as std::ffi::c_int
@@ -404,10 +411,11 @@ unsafe extern "C" fn run_static_initializers() {
404411
};
405412
global_static_const_member = LITERAL_STRUCT.i;
406413
global_const_ptr_arithmetic = PTR_ARITHMETIC;
407-
global_const_indexing = NESTED_STR[LITERAL_FLOAT as std::ffi::c_int as usize];
414+
global_const_indexing =
415+
NESTED_STR[LITERAL_FLOAT as std::ffi::c_double as std::ffi::c_int as usize];
408416
global_const_ref_indexing = &*NESTED_STR
409417
.as_ptr()
410-
.offset(LITERAL_FLOAT as std::ffi::c_int as isize)
418+
.offset(LITERAL_FLOAT as std::ffi::c_double as std::ffi::c_int as isize)
411419
as *const std::ffi::c_char;
412420
global_const_ternary = if LITERAL_BOOL != 0 {
413421
1 as std::ffi::c_int

0 commit comments

Comments
 (0)