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
12 changes: 10 additions & 2 deletions c2rust-transpile/src/translator/literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,21 @@ impl<'c> Translation<'c> {
ty: CQualTypeId,
val: u64,
base: IntBase,
negative: bool,
) -> TranslationResult<Box<Expr>> {
let lit = match base {
IntBase::Dec => mk().int_unsuffixed_lit(val),
IntBase::Hex => mk().float_unsuffixed_lit(&format!("0x{:x}", val)),
IntBase::Oct => mk().float_unsuffixed_lit(&format!("0o{:o}", val)),
};
let mut expr = mk().lit_expr(lit);

if negative {
expr = mk().unary_expr(UnOp::Neg(Default::default()), expr);
}

let target_ty = self.convert_type(ty.ctype)?;
Ok(mk().cast_expr(mk().lit_expr(lit), target_ty))
Ok(mk().cast_expr(expr, target_ty))
}

/// Return whether the literal can be directly translated as this type.
Expand All @@ -49,7 +55,9 @@ impl<'c> Translation<'c> {
lit: &CLiteral,
) -> TranslationResult<WithStmts<Box<Expr>>> {
match *lit {
CLiteral::Integer(val, base) => Ok(WithStmts::new_val(self.mk_int_lit(ty, val, base)?)),
CLiteral::Integer(val, base) => {
Ok(WithStmts::new_val(self.mk_int_lit(ty, val, base, false)?))
}

CLiteral::Character(val) => {
let val = val as u32;
Expand Down
1 change: 1 addition & 0 deletions c2rust-transpile/src/translator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3648,6 +3648,7 @@ impl<'c> Translation<'c> {
override_ty.unwrap_or(ty),
*val,
IntBase::Dec,
false,
)?)),
OffsetOfKind::Variable(qty, field_id, expr_id) => {
self.use_crate(ExternCrate::Memoffset);
Expand Down
55 changes: 35 additions & 20 deletions c2rust-transpile/src/translator/operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@

use super::*;

fn neg_expr(arg: Box<Expr>) -> Box<Expr> {
mk().unary_expr(UnOp::Neg(Default::default()), arg)
}

fn wrapping_neg_expr(arg: Box<Expr>) -> Box<Expr> {
mk().method_call_expr(arg, "wrapping_neg", vec![])
}

impl From<c_ast::BinOp> for BinOp {
fn from(op: c_ast::BinOp) -> Self {
match op {
Expand Down Expand Up @@ -875,9 +867,6 @@ impl<'c> Translation<'c> {
arg: CExprId,
lrvalue: LRValue,
) -> TranslationResult<WithStmts<Box<Expr>>> {
let CQualTypeId { ctype, .. } = cqual_type;
let resolved_ctype = self.ast_context.resolve_type(ctype);

let mut unary = match name {
c_ast::UnOp::AddressOf => self.convert_address_of(ctx, cqual_type, arg),
c_ast::UnOp::PreIncrement => self.convert_pre_increment(ctx, cqual_type, true, arg),
Expand All @@ -887,15 +876,7 @@ impl<'c> Translation<'c> {
c_ast::UnOp::Deref => self.convert_deref(ctx, cqual_type, arg, lrvalue),
c_ast::UnOp::Plus => self.convert_expr(ctx.used(), arg, Some(cqual_type)), // promotion is explicit in the clang AST

c_ast::UnOp::Negate => {
let val = self.convert_expr(ctx.used(), arg, Some(cqual_type))?;

if resolved_ctype.kind.is_unsigned_integral_type() {
Ok(val.map(wrapping_neg_expr))
} else {
Ok(val.map(neg_expr))
}
}
c_ast::UnOp::Negate => self.convert_negate(ctx, cqual_type, arg),
c_ast::UnOp::Complement => Ok(self
.convert_expr(ctx.used(), arg, Some(cqual_type))?
.map(|a| mk().unary_expr(UnOp::Not(Default::default()), a))),
Expand Down Expand Up @@ -934,4 +915,38 @@ impl<'c> Translation<'c> {
}
Ok(unary)
}

fn convert_negate(
&self,
ctx: ExprContext,
cqual_type: CQualTypeId,
arg: CExprId,
) -> TranslationResult<WithStmts<Box<Expr>>> {
let is_unsigned_integral_type = self
.ast_context
.resolve_type(cqual_type.ctype)
.kind
.is_unsigned_integral_type();

if let (&CExprKind::Literal(_, CLiteral::Integer(val, base)), false) =
(&self.ast_context[arg].kind, is_unsigned_integral_type)
{
// If we are negating a literal, generate a negated literal directly.
// This will create an expression like `-1 as ty` without parentheses,
// rather than `-(1 as ty)`.
Ok(WithStmts::new_val(
self.mk_int_lit(cqual_type, val, base, true)?,
))
} else {
let val = self.convert_expr(ctx.used(), arg, Some(cqual_type))?;

Ok(val.map(|val| {
if is_unsigned_integral_type {
mk().method_call_expr(val, "wrapping_neg", vec![])
} else {
mk().unary_expr(UnOp::Neg(Default::default()), val)
}
}))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub unsafe extern "C" fn VM_CallCompiled(
*(image.offset((programStack + 4 as ::core::ffi::c_int) as isize) as *mut byte
as *mut ::core::ffi::c_int) = 0 as ::core::ffi::c_int;
*(image.offset(programStack as isize) as *mut byte as *mut ::core::ffi::c_int) =
-(1 as ::core::ffi::c_int);
-1 as ::core::ffi::c_int;
entryPoint = (*vm).codeBase.offset((*vm).entryOfs as isize);
opStack = (&raw mut stack as *mut byte as *mut ::core::ffi::c_int)
.offset(16 as ::core::ffi::c_int as isize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub unsafe extern "C" fn VM_CallCompiled(
*(image.offset((programStack + 4 as ::core::ffi::c_int) as isize) as *mut byte
as *mut ::core::ffi::c_int) = 0 as ::core::ffi::c_int;
*(image.offset(programStack as isize) as *mut byte as *mut ::core::ffi::c_int) =
-(1 as ::core::ffi::c_int);
-1 as ::core::ffi::c_int;
entryPoint = (*vm).codeBase.offset((*vm).entryOfs as isize);
opStack = (&raw mut stack as *mut byte as *mut ::core::ffi::c_int)
.offset(16 as ::core::ffi::c_int as isize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub unsafe extern "C" fn VM_CallCompiled(
*(image.offset((programStack + 4 as ::core::ffi::c_int) as isize) as *mut byte
as *mut ::core::ffi::c_int) = 0 as ::core::ffi::c_int;
*(image.offset(programStack as isize) as *mut byte as *mut ::core::ffi::c_int) =
-(1 as ::core::ffi::c_int);
-1 as ::core::ffi::c_int;
entryPoint = (*vm).codeBase.offset((*vm).entryOfs as isize);
opStack = (&raw mut stack as *mut byte as *mut ::core::ffi::c_int)
.offset(16 as ::core::ffi::c_int as isize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub unsafe extern "C" fn VM_CallCompiled(
*(image.offset((programStack + 4 as ::core::ffi::c_int) as isize) as *mut byte
as *mut ::core::ffi::c_int) = 0 as ::core::ffi::c_int;
*(image.offset(programStack as isize) as *mut byte as *mut ::core::ffi::c_int) =
-(1 as ::core::ffi::c_int);
-1 as ::core::ffi::c_int;
entryPoint = (*vm).codeBase.offset((*vm).entryOfs as isize);
opStack = (&raw mut stack as *mut byte as *mut ::core::ffi::c_int)
.offset(16 as ::core::ffi::c_int as isize);
Expand Down
Loading