Skip to content

Commit dd14242

Browse files
committed
transpile: Propagate cast of EnumConstant to its own integral type
1 parent d833b33 commit dd14242

4 files changed

Lines changed: 21 additions & 12 deletions

File tree

c2rust-transpile/src/translator/enums.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl<'c> Translation<'c> {
142142
type_enum_id == constant_enum_id
143143
}
144144

145-
fn enum_integral_type(&self, enum_id: CEnumId) -> CQualTypeId {
145+
pub fn enum_integral_type(&self, enum_id: CEnumId) -> CQualTypeId {
146146
match self.ast_context[enum_id].kind {
147147
CDeclKind::Enum {
148148
integral_type: Some(integral_type),

c2rust-transpile/src/translator/mod.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3053,11 +3053,10 @@ impl<'c> Translation<'c> {
30533053
CDeclKind::EnumConstant { .. } => {
30543054
// If the variable is actually an `EnumConstant`, we need to add a cast to
30553055
// the expected integral type.
3056-
if !self.enum_constant_matches_type(
3057-
override_ty.unwrap_or(qual_ty).ctype,
3058-
decl_id,
3059-
) {
3060-
val = self.convert_cast_from_enum(qual_ty.ctype, val)?;
3056+
let target_type_id = override_ty.unwrap_or(qual_ty);
3057+
3058+
if !self.enum_constant_matches_type(target_type_id.ctype, decl_id) {
3059+
val = self.convert_cast_from_enum(target_type_id.ctype, val)?;
30613060
}
30623061

30633062
return Ok(WithStmts::new_val(val));
@@ -3597,6 +3596,18 @@ impl<'c> Translation<'c> {
35973596
if self.enum_constant_matches_type(target_type_id.ctype, decl_id) {
35983597
return true;
35993598
}
3599+
3600+
let source_enum_id = self.ast_context.parents[&decl_id];
3601+
let source_integral_type_id = self.enum_integral_type(source_enum_id);
3602+
let target_type_resolved_id = self
3603+
.ast_context
3604+
.resolve_type_id_no_typedef(target_type_id.ctype);
3605+
3606+
// Likewise, if we are casting to the inner integral type of the enum, then
3607+
// translate the enum constant directly as that.
3608+
if target_type_resolved_id == source_integral_type_id.ctype {
3609+
return true;
3610+
}
36003611
}
36013612
}
36023613

c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2021.clang15.snap

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ pub unsafe extern "C" fn test_enums() {
4141
let mut e: Foo = Foo1;
4242
let mut enum_enum: ::core::ffi::c_int =
4343
(e as ::core::ffi::c_uint == foo as ::core::ffi::c_uint) as ::core::ffi::c_int;
44-
let mut enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint
45-
== Foo0 as ::core::ffi::c_int as ::core::ffi::c_uint)
46-
as ::core::ffi::c_int;
44+
let mut enum_constant: ::core::ffi::c_int =
45+
(e as ::core::ffi::c_uint == Foo0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
4746
let mut wrong_enum_enum: ::core::ffi::c_int =
4847
(e as ::core::ffi::c_uint == bar as ::core::ffi::c_uint) as ::core::ffi::c_int;
4948
let mut wrong_enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint

c2rust-transpile/tests/snapshots/snapshots__transpile@enums.c.2024.clang15.snap

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ pub unsafe extern "C" fn test_enums() {
4242
let mut e: Foo = Foo1;
4343
let mut enum_enum: ::core::ffi::c_int =
4444
(e as ::core::ffi::c_uint == foo as ::core::ffi::c_uint) as ::core::ffi::c_int;
45-
let mut enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint
46-
== Foo0 as ::core::ffi::c_int as ::core::ffi::c_uint)
47-
as ::core::ffi::c_int;
45+
let mut enum_constant: ::core::ffi::c_int =
46+
(e as ::core::ffi::c_uint == Foo0 as ::core::ffi::c_uint) as ::core::ffi::c_int;
4847
let mut wrong_enum_enum: ::core::ffi::c_int =
4948
(e as ::core::ffi::c_uint == bar as ::core::ffi::c_uint) as ::core::ffi::c_int;
5049
let mut wrong_enum_constant: ::core::ffi::c_int = (e as ::core::ffi::c_uint

0 commit comments

Comments
 (0)