Skip to content
Open
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
34 changes: 27 additions & 7 deletions c2rust-transpile/src/translator/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,9 @@ impl<'c> Translation<'c> {
))
}
"__builtin_signbit" | "__builtin_signbitf" | "__builtin_signbitl" => {
// Long doubles require the Float trait from num_traits to call this method
if builtin_name == "__builtin_signbitl" {
self.with_cur_file_item_store(|item_store| {
item_store.add_use(true, vec!["num_traits".into()], "Float");
});
}
self.import_num_traits(args[0])?;

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

Ok(val.map(|v| {
let val = mk().method_call_expr(v, "is_sign_negative", vec![]);

Expand Down Expand Up @@ -149,10 +143,14 @@ impl<'c> Translation<'c> {
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)?;
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 seg = match builtin_name {
Expand All @@ -166,6 +164,8 @@ impl<'c> Translation<'c> {
}))
}
"__builtin_isinf_sign" => {
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)?;
Ok(val.map(|x| {
Expand Down Expand Up @@ -723,6 +723,26 @@ impl<'c> Translation<'c> {
}
}

fn import_num_traits(&self, arg_id: CExprId) -> TranslationResult<()> {
let arg_type_id = self.ast_context[arg_id]
.kind
.get_qual_type()
.ok_or_else(|| format_err!("bad arg type"))?;
let arg_type_kind = &self.ast_context.resolve_type(arg_type_id.ctype).kind;

match arg_type_kind {
CTypeKind::LongDouble | CTypeKind::Float128 => {
self.use_crate(ExternCrate::NumTraits);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this not needed before because there's a cast after? Or how did this work before?

Copy link
Copy Markdown
Contributor Author

@Rua Rua Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it ever worked. These methods are not inherent methods of f128, they are provided by the Float trait. So without importing that, you just get a compile error.

self.with_cur_file_item_store(|item_store| {
item_store.add_use(true, vec!["num_traits".into()], "Float");
});
}
_ => {}
}

Ok(())
}

// This translation logic handles converting code that uses
// https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
fn convert_overflow_arith(
Expand Down
Loading