Skip to content

Commit 7eb17e8

Browse files
committed
[unsage] Fix missing transmute in function pointer cast
Fixes test fn_ptr_typedef_cast.c
1 parent bfa3d56 commit 7eb17e8

5 files changed

Lines changed: 27 additions & 9 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,12 +2039,29 @@ void Converter::ConvertParamTy(clang::QualType param_type, clang::Expr *expr) {
20392039
if (param_type->isReferenceType()) {
20402040
PushExprKind push(*this, ExprKind::AddrOf);
20412041
ConvertVarInit(param_type, expr);
2042+
} else if (FunctionPointerCastNeedsTransmute() &&
2043+
param_type->isFunctionPointerType() &&
2044+
expr->getType()->isFunctionPointerType() &&
2045+
!IsCastRedundantInRust(expr, param_type)) {
2046+
ConvertFunctionPointerTransmute(expr, param_type);
2047+
return;
20422048
} else {
20432049
ConvertVarInit(param_type, expr);
20442050
}
20452051
ConvertParamTyPointerCastIfNeeded(param_type, expr);
20462052
}
20472053

2054+
void Converter::ConvertFunctionPointerTransmute(clang::Expr *expr,
2055+
clang::QualType type) {
2056+
StrCat("std::mem::transmute::<");
2057+
Convert(expr->getType());
2058+
StrCat(',');
2059+
Convert(type);
2060+
StrCat(">(");
2061+
Convert(expr);
2062+
StrCat(')');
2063+
}
2064+
20482065
void Converter::ConvertParamTyPointerCastIfNeeded(clang::QualType param_type,
20492066
clang::Expr *expr) {
20502067
if (!param_type->isPointerType() || !expr->getType()->isPointerType() ||
@@ -2625,13 +2642,7 @@ bool Converter::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
26252642
}
26262643
if (type->isFunctionPointerType() ||
26272644
sub_expr->getType()->isFunctionPointerType()) {
2628-
StrCat("std::mem::transmute::<");
2629-
Convert(sub_expr->getType());
2630-
StrCat(',');
2631-
Convert(type);
2632-
StrCat(">(");
2633-
Convert(sub_expr);
2634-
StrCat(')');
2645+
ConvertFunctionPointerTransmute(sub_expr, type);
26352646
return false;
26362647
}
26372648
if (type->isEnumeralType() && !sub_expr->getType()->isEnumeralType()) {

‎cpp2rust/converter/converter.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
318318
virtual void ConvertParamTyPointerCastIfNeeded(clang::QualType param_type,
319319
clang::Expr *expr);
320320

321+
virtual bool FunctionPointerCastNeedsTransmute() const { return true; }
322+
323+
void ConvertFunctionPointerTransmute(clang::Expr *expr, clang::QualType type);
324+
321325
void EmitHoistedArgs(CallInfo &info);
322326

323327
void EmitArgList(const CallInfo &info);

‎cpp2rust/converter/models/converter_refcount.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class ConverterRefCount final : public Converter {
114114

115115
// FnPtr does not implement Copy
116116
bool FunctionPointerImplementsCopy() const override { return false; }
117+
bool FunctionPointerCastNeedsTransmute() const override { return false; }
117118

118119
bool VisitCallExpr(clang::CallExpr *expr) override;
119120

‎tests/unit/fn_ptr_typedef_cast.c‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// XFAIL: unsafe
21
#include <assert.h>
32
#include <stddef.h>
43

‎tests/unit/out/unsafe/fn_ptr_typedef_cast.rs‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ unsafe fn main_0() -> i32 {
2828
assert!(((((unsafe { call_with_ulong_0(Some(same_type_1),) }) == (4_u64)) as i32) != 0));
2929
assert!(
3030
((((unsafe {
31-
call_with_ulong_0(Some(via_size_t_param_2) as Option<unsafe fn(u64) -> u64>)
31+
call_with_ulong_0(std::mem::transmute::<
32+
Option<unsafe fn(usize) -> u64>,
33+
Option<unsafe fn(u64) -> u64>,
34+
>(Some(via_size_t_param_2)))
3235
}) == (4_u64)) as i32)
3336
!= 0)
3437
);

0 commit comments

Comments
 (0)