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
8 changes: 4 additions & 4 deletions c2rust-transpile/src/cfg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1491,7 +1491,7 @@ impl CfgBuilder {

// Condition
let (stmts, val) = translator
.convert_condition(ctx, true, scrutinee)?
.convert_condition(ctx.used(), true, scrutinee)?
.discard_unsafe();
wip.extend(stmts);

Expand Down Expand Up @@ -1564,7 +1564,7 @@ impl CfgBuilder {

// Condition
let (stmts, val) = translator
.convert_condition(ctx, true, condition)?
.convert_condition(ctx.used(), true, condition)?
.discard_unsafe();
let cond_val = translator
.ast_context
Expand Down Expand Up @@ -1643,7 +1643,7 @@ impl CfgBuilder {

// Condition
let (stmts, val) = translator
.convert_condition(ctx, true, condition)?
.convert_condition(ctx.used(), true, condition)?
.discard_unsafe();
let cond_val = translator
.ast_context
Expand Down Expand Up @@ -1698,7 +1698,7 @@ impl CfgBuilder {
// Condition
if let Some(cond) = condition {
let (stmts, val) = translator
.convert_condition(ctx, true, cond)?
.convert_condition(ctx.used(), true, cond)?
.discard_unsafe();
let cond_val = translator
.ast_context
Expand Down
51 changes: 26 additions & 25 deletions c2rust-transpile/src/translator/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,12 @@ impl<'c> Translation<'c> {
rotate_method_name: &'static str,
) -> TranslationResult<WithStmts<Box<Expr>>> {
// Emit `arg0.{method_name}(arg1)`
let arg0 = self.convert_expr(ctx.used(), args[0], None)?;
let arg1 = self.convert_expr(ctx.used(), args[1], None)?;
let arg0 = self.convert_expr(ctx, args[0], None)?;
let arg1 = self.convert_expr(ctx, args[1], None)?;
Ok(arg0.zip(arg1).and_then(|(arg0, arg1)| {
let arg1 = mk().cast_expr(arg1, mk().path_ty(vec!["u32"]));
let method_call_expr = mk().method_call_expr(arg0, rotate_method_name, vec![arg1]);
self.convert_side_effects_expr(
ctx,
WithStmts::new_val(method_call_expr),
"Builtin is not supposed to be used",
)
WithStmts::new_val(method_call_expr)
}))
}

Expand Down Expand Up @@ -116,15 +112,15 @@ impl<'c> Translation<'c> {
"__builtin_signbit" | "__builtin_signbitf" | "__builtin_signbitl" => {
self.import_num_traits(args[0])?;

let val = self.convert_expr(ctx.used(), args[0], None)?;
let val = self.convert_expr(ctx, args[0], None)?;
Ok(val.map(|v| {
let val = mk().method_call_expr(v, "is_sign_negative", vec![]);

mk().cast_expr(val, mk().abs_path_ty(vec!["core", "ffi", "c_int"]))
}))
}
"__builtin_ffs" | "__builtin_ffsl" | "__builtin_ffsll" => {
let val = self.convert_expr(ctx.used(), args[0], None)?;
let val = self.convert_expr(ctx, args[0], None)?;

Ok(val.map(|x| {
let add = BinOp::Add(Default::default());
Expand All @@ -141,33 +137,33 @@ impl<'c> Translation<'c> {
}))
}
"__builtin_clz" | "__builtin_clzl" | "__builtin_clzll" => {
let val = self.convert_expr(ctx.used(), args[0], None)?;
let val = self.convert_expr(ctx, args[0], None)?;
Ok(val.map(|x| {
let zeros = mk().method_call_expr(x, "leading_zeros", vec![]);
mk().cast_expr(zeros, mk().path_ty(vec!["i32"]))
}))
}
"__builtin_ctz" | "__builtin_ctzl" | "__builtin_ctzll" => {
let val = self.convert_expr(ctx.used(), args[0], None)?;
let val = self.convert_expr(ctx, args[0], None)?;
Ok(val.map(|x| {
let zeros = mk().method_call_expr(x, "trailing_zeros", vec![]);
mk().cast_expr(zeros, mk().path_ty(vec!["i32"]))
}))
}
"__builtin_bswap16" | "__builtin_bswap32" | "__builtin_bswap64" => {
let val = self.convert_expr(ctx.used(), args[0], None)?;
let val = self.convert_expr(ctx, args[0], None)?;
Ok(val.map(|x| mk().method_call_expr(x, "swap_bytes", vec![])))
}
"__builtin_fabs" | "__builtin_fabsf" | "__builtin_fabsl" => {
self.import_num_traits(args[0])?;

let val = self.convert_expr(ctx.used(), args[0], None)?;
let val = self.convert_expr(ctx, args[0], None)?;
Ok(val.map(|x| mk().method_call_expr(x, "abs", vec![])))
}
"__builtin_isfinite" | "__builtin_isnan" => {
self.import_num_traits(args[0])?;

let val = self.convert_expr(ctx.used(), args[0], None)?;
let val = self.convert_expr(ctx, args[0], None)?;

let seg = match builtin_name {
"__builtin_isfinite" => "is_finite",
Expand All @@ -183,7 +179,7 @@ impl<'c> Translation<'c> {
self.import_num_traits(args[0])?;

// isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0
let val = self.convert_expr(ctx.used(), args[0], None)?;
let val = self.convert_expr(ctx, args[0], None)?;
Ok(val.map(|x| {
let inner_cond = mk().method_call_expr(x.clone(), "is_sign_positive", vec![]);
let one = mk().lit_expr(mk().int_lit(1, ""));
Expand All @@ -202,10 +198,10 @@ impl<'c> Translation<'c> {
// https://github.com/llvm-mirror/llvm/blob/master/lib/CodeGen/IntrinsicLowering.cpp#L470
Ok(WithStmts::new_val(mk().lit_expr(mk().int_lit(1, "i32"))))
}
"__builtin_expect" => self.convert_expr(ctx.used(), args[0], None),
"__builtin_expect" => self.convert_expr(ctx, args[0], None),

"__builtin_popcount" | "__builtin_popcountl" | "__builtin_popcountll" => {
let val = self.convert_expr(ctx.used(), args[0], None)?;
let val = self.convert_expr(ctx, args[0], None)?;
Ok(val.map(|x| {
let zeros = mk().method_call_expr(x, "count_ones", vec![]);
mk().cast_expr(zeros, mk().path_ty(vec!["i32"]))
Expand All @@ -216,9 +212,14 @@ impl<'c> Translation<'c> {
let n_stmts = self.convert_expr(ctx.used(), args[1], None)?;
let write_bytes = mk().abs_path_expr(vec!["core", "ptr", "write_bytes"]);
let zero = mk().lit_expr(mk().int_lit(0, "u8"));
Ok(ptr_stmts.and_then(|ptr| {
let call = ptr_stmts.and_then(|ptr| {
n_stmts.map(|n| mk().call_expr(write_bytes, vec![ptr, zero, n]))
}))
});
Ok(self.convert_side_effects_expr(
ctx,
call,
"__builtin_bzero value is not supposed to be used",
))
}

// If the target does not support data prefetch, the address expression is evaluated if
Expand Down Expand Up @@ -302,8 +303,8 @@ impl<'c> Translation<'c> {
// We can't convert this to Rust, but it should be safe to always return -1/0
// (depending on the value of `type`), so we emit the following:
// `(if (type & 2) == 0 { -1isize } else { 0isize }) as libc::size_t`
let ptr_arg = self.convert_expr(ctx.unused(), args[0], None)?;
let type_arg = self.convert_expr(ctx.used(), args[1], None)?;
let ptr_arg = self.convert_expr(ctx, args[0], None)?;
let type_arg = self.convert_expr(ctx, args[1], None)?;
Ok(ptr_arg.and_then(|_| {
type_arg.map(|type_arg| {
let type_and_2 = mk().binary_expr(
Expand All @@ -330,7 +331,7 @@ impl<'c> Translation<'c> {
}

"__builtin_va_start" => {
if ctx.is_unused() && args.len() == 2 {
if !ctx.is_used && args.len() == 2 {
if let Some(va_id) = self.match_vastart(args[0]) {
if self.ast_context.get_decl(&va_id).is_some() {
let dst = self.convert_expr(ctx.used(), args[0], None)?;
Expand All @@ -352,7 +353,7 @@ impl<'c> Translation<'c> {
Err(TranslationError::generic("Unsupported va_start"))
}
"__builtin_va_copy" => {
if ctx.is_unused() && args.len() == 2 {
if !ctx.is_used && args.len() == 2 {
if let Some((_dst_va_id, _src_va_id)) = self.match_vacopy(args[0], args[1]) {
let dst = self.convert_expr(ctx.used(), args[0], None)?;
let src = self.convert_expr(ctx.used(), args[1], None)?;
Expand All @@ -370,7 +371,7 @@ impl<'c> Translation<'c> {
Err(TranslationError::generic("Unsupported va_copy"))
}
"__builtin_va_end" => {
if ctx.is_unused() && args.len() == 1 {
if !ctx.is_used && args.len() == 1 {
if let Some(_va_id) = self.match_vaend(args[0]) {
// nothing to do since the translated Rust `va_list` values get `Drop`'ed.
return Ok(WithStmts::new_val(self.panic("va_end stub")));
Expand Down Expand Up @@ -602,7 +603,7 @@ impl<'c> Translation<'c> {
}
// There's currently no way to replicate this functionality in Rust, so we just
// pass the ptr input param in its place.
"__builtin_assume_aligned" => Ok(self.convert_expr(ctx.used(), args[0], None)?),
"__builtin_assume_aligned" => self.convert_expr(ctx, args[0], None),
// Skip over, there's no way to implement it in Rust
"__builtin_unwind_init" => Ok(WithStmts::new_val(self.panic_or_err("no value"))),
"__builtin_unreachable" => Ok(WithStmts::new(
Expand Down
14 changes: 7 additions & 7 deletions c2rust-transpile/src/translator/literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ impl<'c> Translation<'c> {
) -> TranslationResult<WithStmts<Box<Expr>>> {
// C compound literals are lvalues, but equivalent Rust expressions generally are not.
// So if an address is needed, store it in an intermediate variable first.
if !ctx.needs_address || ctx.expanding_macro.is_some() {
return self.convert_expr(ctx, val, override_ty);
if !ctx.needs_address || !ctx.is_used || ctx.expanding_macro.is_some() {
return self.convert_expr(ctx.not_needs_address(), val, override_ty);
}

let fresh_name = self
Expand All @@ -211,7 +211,7 @@ impl<'c> Translation<'c> {

// Translate the expression to be assigned to the fresh variable.
// It will be assigned by value, so we don't need its address anymore.
let val = self.convert_expr(ctx.not_needs_address(), val, override_ty)?;
let val = self.convert_expr(ctx.used().not_needs_address(), val, override_ty)?;

// If we are translating a static variable,
// then the fresh variable should also be static.
Expand Down Expand Up @@ -258,7 +258,7 @@ impl<'c> Translation<'c> {

let to_array_element = |id: CExprId| -> TranslationResult<_> {
let val =
self.convert_expr(ctx.used(), id, Some(CQualTypeId::new(element_type_id)))?;
self.convert_expr(ctx, id, Some(CQualTypeId::new(element_type_id)))?;
val.try_map(|x| {
// Array literals require all of their elements to be
// the correct type; they will not use implicit casts to
Expand Down Expand Up @@ -325,7 +325,7 @@ impl<'c> Translation<'c> {
// * `ptr_extra_braces`
// * `array_of_ptrs`
// * `array_of_arrays`
self.convert_expr(ctx.used(), single, expected_type_id)
self.convert_expr(ctx, single, expected_type_id)
}
&[single] if is_zero_literal(single) && n > 1 => {
// This was likely a C array of the form `int x[16] = { 0 }`.
Expand Down Expand Up @@ -364,9 +364,9 @@ impl<'c> Translation<'c> {
}
ref kind if kind.is_scalar() => {
if let Some(&first) = ids.first() {
self.convert_expr(ctx.used(), first, expected_type_id)
self.convert_expr(ctx, first, expected_type_id)
} else {
self.implicit_default_expr(ctx.used(), result_type_id.ctype)
self.implicit_default_expr(ctx, result_type_id.ctype)
}
}
ref t => Err(format_err!("Init list not implemented for {:?}", t).into()),
Expand Down
2 changes: 1 addition & 1 deletion c2rust-transpile/src/translator/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl<'c> Translation<'c> {
.kind
.get_type()
.ok_or_else(|| format_err!("Invalid expression type"))?;
let expr = self.convert_expr(ctx, id, None)?;
let expr = self.convert_expr(ctx.used(), id, None)?;

// Join ty and cur_ty to the smaller of the two types. If the
// types are not cast-compatible, abort the fold.
Expand Down
Loading
Loading