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
39 changes: 32 additions & 7 deletions c2rust-transpile/src/c_ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1306,17 +1306,18 @@ impl TypedAstContext {
}
}

/// Bubble types of unary and binary operators up from their args into the expression type.
///
/// In Clang 15 and below, the Clang AST resolves typedefs in the expression type of unary and
/// binary expressions. For example, a BinaryExpr node adding two `size_t` expressions will be
/// given an `unsigned long` type rather than the `size_t` typedef type. This behavior changed
/// in Clang 16. This method adjusts AST node types to match those produced by Clang 16 and
/// newer; on these later Clang versions, it should have no effect.
/// Overrides the result types of certain expressions to one of the `PULLBACK_KINDS` where
/// appropriate. Then bubbles those types up to the parent expressions.
///
/// This pass is necessary because we reify some typedef types (such as `size_t`) into their own
/// distinct Rust types. As such, we need to make sure we know the exact type to generate when
/// we translate an expr, not just its resolved type (looking through typedefs).
///
/// Additionally, in Clang 15 and below, the Clang AST resolves typedefs in the expression type
/// of unary and binary expressions. For example, a BinaryExpr node adding two `size_t`
/// expressions will be given an `unsigned long` type rather than the `size_t` typedef type.
/// This behavior changed in Clang 16. This method adjusts AST node types to match those
/// produced by Clang 16 and newer.
pub fn bubble_expr_types(&mut self) {
struct BubbleExprTypes<'a> {
ast_context: &'a mut TypedAstContext,
Expand Down Expand Up @@ -1379,6 +1380,30 @@ impl TypedAstContext {
self.ast_context,
self.ast_context.c_exprs[&e].kind.get_qual_type().unwrap(),
),
CExprKind::Call(result_type_id, callee_id, _) => {
let CExprKind::ImplicitCast(_, callee_id, CastKind::BuiltinFnToFnPtr, _, _) =
self.ast_context.index_unwrap_parens(callee_id).kind
else {
return;
};
let CExprKind::DeclRef(_, decl_id, _) =
self.ast_context.index_unwrap_parens(callee_id).kind
else {
return;
};
let CDeclKind::Function { ref name, .. } = self.ast_context[decl_id].kind
else {
return;
};

match name.as_str() {
"__builtin_object_size" => {
let type_id = self.ast_context.type_for_kind(&CTypeKind::Size);
Some(result_type_id.with_ctype(type_id))
}
_ => None,
}
}
Comment thread
Rua marked this conversation as resolved.
CExprKind::Paren(_ty, e) => self.ast_context.c_exprs[&e].kind.get_qual_type(),
CExprKind::UnaryType(_, op, _, _) => {
// All of these `CUnTypeOp`s should return `size_t`.
Expand Down
418 changes: 220 additions & 198 deletions c2rust-transpile/src/translator/builtins.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion c2rust-transpile/src/translator/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ impl<'c> Translation<'c> {

// Builtin function call
CExprKind::ImplicitCast(_, fexp, CastKind::BuiltinFnToFnPtr, _, _) => {
return self.convert_builtin(ctx, fexp, args);
return self.convert_builtin(ctx, override_ty, call_expr_ty, fexp, args);
}

// Function pointer call
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ pub unsafe extern "C" fn long_double_test() {
let mut cast_from_float: ::f128::f128 = ::f128::f128::new(f);
let mut is_inf: bool = if huge.is_infinite() {
if huge.is_sign_positive() {
1
1 as ::core::ffi::c_int
} else {
-1
-1 as ::core::ffi::c_int
}
} else {
0
0 as ::core::ffi::c_int
} != 0;
if one != ::f128::f128::ZERO {
let mut dummy: ::core::ffi::c_int = 0;
Expand All @@ -48,12 +48,12 @@ pub unsafe extern "C" fn float128_test() {
let mut ld_from_float128: ::f128::f128 = one;
let mut is_inf: bool = if huge.is_infinite() {
if huge.is_sign_positive() {
1
1 as ::core::ffi::c_int
} else {
-1
-1 as ::core::ffi::c_int
}
} else {
0
0 as ::core::ffi::c_int
} != 0;
if one != ::f128::f128::ZERO {
let mut dummy: ::core::ffi::c_int = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ pub unsafe extern "C" fn long_double_test() {
let mut cast_from_int: ::f128::f128 = ::f128::f128::new(i);
let mut cast_from_float: ::f128::f128 = ::f128::f128::new(f);
let mut is_inf: bool = if huge.is_infinite() {
if huge.is_sign_positive() { 1 } else { -1 }
if huge.is_sign_positive() {
1 as ::core::ffi::c_int
} else {
-1 as ::core::ffi::c_int
}
} else {
0
0 as ::core::ffi::c_int
} != 0;
if one != ::f128::f128::ZERO {
let mut dummy: ::core::ffi::c_int = 0;
Expand All @@ -44,9 +48,13 @@ pub unsafe extern "C" fn float128_test() {
let mut cast_from_float: ::f128::f128 = ::f128::f128::new(f);
let mut ld_from_float128: ::f128::f128 = one;
let mut is_inf: bool = if huge.is_infinite() {
if huge.is_sign_positive() { 1 } else { -1 }
if huge.is_sign_positive() {
1 as ::core::ffi::c_int
} else {
-1 as ::core::ffi::c_int
}
} else {
0
0 as ::core::ffi::c_int
} != 0;
if one != ::f128::f128::ZERO {
let mut dummy: ::core::ffi::c_int = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,14 @@ pub unsafe extern "C" fn local_muts() {
let mut str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr();
let mut str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
let mut builtin: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
let mut ref_indexing: *const ::core::ffi::c_char = REF_MACRO;
let mut ref_struct: *const S = REF_LITERAL;
let mut ternary: ::core::ffi::c_int = TERNARY;
let mut member: ::core::ffi::c_int = MEMBER;
let mut stmt_expr: ::core::ffi::c_float = ({
let mut builtin_0: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
let mut indexing_0: ::core::ffi::c_char = INDEXING;
let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float;
let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
Expand Down Expand Up @@ -166,14 +166,15 @@ pub unsafe extern "C" fn local_consts() {
let indexing: ::core::ffi::c_char = INDEXING;
let str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr();
let str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
let builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
let builtin: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
let ref_indexing: *const ::core::ffi::c_char = REF_MACRO;
let ref_struct: *const S = REF_LITERAL;
let ternary: ::core::ffi::c_int = TERNARY;
let member: ::core::ffi::c_int = MEMBER;
let stmt_expr: ::core::ffi::c_float = ({
let mut builtin_0: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
let mut indexing_0: ::core::ffi::c_char = INDEXING;
let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float;
let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
Expand Down Expand Up @@ -219,7 +220,7 @@ static mut global_static_const_str_concatenation_ptr: *const ::core::ffi::c_char
STR_CONCATENATION.as_ptr();
static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
static mut global_static_const_builtin: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
static mut global_static_const_ref_indexing: *const ::core::ffi::c_char =
::core::ptr::null::<::core::ffi::c_char>();
static mut global_static_const_ref_struct: *const S = REF_LITERAL;
Expand Down Expand Up @@ -288,7 +289,7 @@ pub static mut global_const_str_concatenation_ptr: *const ::core::ffi::c_char =
pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
#[no_mangle]
pub static mut global_const_builtin: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
#[no_mangle]
pub static mut global_const_ref_indexing: *const ::core::ffi::c_char =
::core::ptr::null::<::core::ffi::c_char>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,14 @@ pub unsafe extern "C" fn local_muts() {
let mut str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr();
let mut str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
let mut builtin: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
let mut ref_indexing: *const ::core::ffi::c_char = REF_MACRO;
let mut ref_struct: *const S = REF_LITERAL;
let mut ternary: ::core::ffi::c_int = TERNARY;
let mut member: ::core::ffi::c_int = MEMBER;
let mut stmt_expr: ::core::ffi::c_float = ({
let mut builtin_0: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
let mut indexing_0: ::core::ffi::c_char = INDEXING;
let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float;
let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
Expand Down Expand Up @@ -166,14 +166,15 @@ pub unsafe extern "C" fn local_consts() {
let indexing: ::core::ffi::c_char = INDEXING;
let str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr();
let str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
let builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
let builtin: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
let ref_indexing: *const ::core::ffi::c_char = REF_MACRO;
let ref_struct: *const S = REF_LITERAL;
let ternary: ::core::ffi::c_int = TERNARY;
let member: ::core::ffi::c_int = MEMBER;
let stmt_expr: ::core::ffi::c_float = ({
let mut builtin_0: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
let mut indexing_0: ::core::ffi::c_char = INDEXING;
let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float;
let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
Expand Down Expand Up @@ -219,7 +220,7 @@ static mut global_static_const_str_concatenation_ptr: *const ::core::ffi::c_char
STR_CONCATENATION.as_ptr();
static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
static mut global_static_const_builtin: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
static mut global_static_const_ref_indexing: *const ::core::ffi::c_char =
::core::ptr::null::<::core::ffi::c_char>();
static mut global_static_const_ref_struct: *const S = REF_LITERAL;
Expand Down Expand Up @@ -288,7 +289,7 @@ pub static mut global_const_str_concatenation_ptr: *const ::core::ffi::c_char =
pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
#[unsafe(no_mangle)]
pub static mut global_const_builtin: ::core::ffi::c_int =
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as ::core::ffi::c_int;
#[unsafe(no_mangle)]
pub static mut global_const_ref_indexing: *const ::core::ffi::c_char =
::core::ptr::null::<::core::ffi::c_char>();
Expand Down
Loading