Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion c2rust-transpile/src/translator/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl<'c> Translation<'c> {
variants.contains(&enum_constant_id)
}

fn enum_integral_type(&self, enum_id: CEnumId) -> CQualTypeId {
pub(crate) fn enum_integral_type(&self, enum_id: CEnumId) -> CQualTypeId {
match self.ast_context[enum_id].kind {
CDeclKind::Enum {
integral_type: Some(integral_type),
Expand Down
49 changes: 30 additions & 19 deletions c2rust-transpile/src/translator/operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,12 +624,21 @@ impl<'c> Translation<'c> {
_ => mk().lit_expr(mk().int_unsuffixed_lit(1)),
};

let one_type_id =
if let CTypeKind::Pointer(..) = self.ast_context.resolve_type(arg_type.ctype).kind {
CQualTypeId::new(self.ast_context.type_for_kind(&CTypeKind::Int))
} else {
arg_type
};
let mut one_type_id = arg_type;
let mut compute_lhs_type_id = arg_type;
let mut compute_res_type_id = ty;

match self.ast_context.resolve_type(arg_type.ctype).kind {
CTypeKind::Pointer(..) => {
one_type_id = CQualTypeId::new(self.ast_context.type_for_kind(&CTypeKind::Int));
}
CTypeKind::Enum(enum_id) => {
one_type_id = self.enum_integral_type(enum_id);
compute_lhs_type_id = one_type_id;
compute_res_type_id = one_type_id;
}
_ => {}
};

self.convert_assignment_operator_with_rhs(
ctx,
Expand All @@ -638,8 +647,8 @@ impl<'c> Translation<'c> {
arg,
one_type_id,
WithStmts::new_val(one),
Some(arg_type),
Some(ty),
Some(compute_lhs_type_id),
Some(compute_res_type_id),
)
}

Expand Down Expand Up @@ -697,9 +706,9 @@ impl<'c> Translation<'c> {
let mut is_unsafe = false; // Track unsafety if we call `pointer::offset`.

// *p + 1
let val = if let &CTypeKind::Pointer(pointee) =
&self.ast_context.resolve_type(ty.ctype).kind
{
let mut type_kind = &self.ast_context.resolve_type(ty.ctype).kind;

let val = if let &CTypeKind::Pointer(pointee) = type_kind {
if let Some(n) = self.compute_size_of_expr(pointee.ctype) {
one = n
}
Expand All @@ -711,15 +720,17 @@ impl<'c> Translation<'c> {
};
is_unsafe = true;
mk().method_call_expr(read, "offset", vec![n])
} else if self
.ast_context
.resolve_type(ty.ctype)
.kind
.is_unsigned_integral_type()
{
mk().method_call_expr(read, op.wrapping_method(), vec![one])
} else {
mk().binary_expr(BinOp::from(op), read, one)
if let &CTypeKind::Enum(enum_id) = type_kind {
let integral_type = self.enum_integral_type(enum_id);
type_kind = &self.ast_context.resolve_type(integral_type.ctype).kind;
}

if type_kind.is_unsigned_integral_type() {
mk().method_call_expr(read, op.wrapping_method(), vec![one])
} else {
mk().binary_expr(BinOp::from(op), read, one)
}
};

// *p = *p + rhs
Expand Down
6 changes: 6 additions & 0 deletions c2rust-transpile/tests/snapshots/enums.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ void test_enums(void) {
foo -= 2;
bar -= 2;

// Increment
++foo;
++bar;
bar = foo++;
foo = bar++;

Foo e = Foo1;

// Compare to same type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ pub unsafe extern "C" fn test_enums() {
bar = Bar3;
foo = (foo as ::core::ffi::c_uint).wrapping_sub(2 as ::core::ffi::c_uint) as Foo;
bar = (bar as ::core::ffi::c_int - 2 as ::core::ffi::c_int) as Bar;
foo = (foo as ::core::ffi::c_uint).wrapping_add(1) as Foo;
bar = (bar as ::core::ffi::c_int + 1) as Bar;
let c2rust_fresh0 = foo;
foo = foo.wrapping_add(1);
bar = c2rust_fresh0 as Bar;
let c2rust_fresh1 = bar;
bar = bar + 1;
foo = c2rust_fresh1 as Foo;
let mut e: Foo = Foo1;
let mut enum_enum: ::core::ffi::c_int =
(e as ::core::ffi::c_uint == foo as ::core::ffi::c_uint) as ::core::ffi::c_int;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ pub unsafe extern "C" fn test_enums() {
bar = Bar3;
foo = (foo as ::core::ffi::c_uint).wrapping_sub(2 as ::core::ffi::c_uint) as Foo;
bar = (bar as ::core::ffi::c_int - 2 as ::core::ffi::c_int) as Bar;
foo = (foo as ::core::ffi::c_uint).wrapping_add(1) as Foo;
bar = (bar as ::core::ffi::c_int + 1) as Bar;
let c2rust_fresh0 = foo;
foo = foo.wrapping_add(1);
bar = c2rust_fresh0 as Bar;
let c2rust_fresh1 = bar;
bar = bar + 1;
foo = c2rust_fresh1 as Foo;
let mut e: Foo = Foo1;
let mut enum_enum: ::core::ffi::c_int =
(e as ::core::ffi::c_uint == foo as ::core::ffi::c_uint) as ::core::ffi::c_int;
Expand Down
Loading