From f9f633fbb2ed3aaca0a33896230bb1171cbe16f1 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 12:43:22 +0100 Subject: [PATCH 1/3] Fix Default for floating type --- cpp2rust/converter/converter.cpp | 2 +- tests/unit/expr_as_bool_cpp.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index b63c7fcb3..ce3cd07c1 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2604,7 +2604,7 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) { PushParen paren(*this); Convert(sub_expr); StrCat(token::kDiff); - StrCat(token::kZero); + StrCat(sub_expr->getType()->isFloatingType() ? "0.0" : "0"); computed_expr_type_ = ComputedExprType::FreshValue; } diff --git a/tests/unit/expr_as_bool_cpp.cpp b/tests/unit/expr_as_bool_cpp.cpp index 21a91413b..b5f759509 100644 --- a/tests/unit/expr_as_bool_cpp.cpp +++ b/tests/unit/expr_as_bool_cpp.cpp @@ -55,5 +55,16 @@ int main() { assert(both_null(nullptr, nullptr) == 1); assert(both_null(p1, nullptr) == 0); + double d = 0.5; + int taken = 0; + if (d) { + taken = 1; + } + assert(taken == 1); + while (d) { + d = 0.0; + } + assert(d == 0.0); + return 0; } From 01e8de66897e9bb0fc5fdc1121aa4070ae1f6819 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 12:44:08 +0100 Subject: [PATCH 2/3] Handle floating to boolean cast --- cpp2rust/converter/converter.cpp | 1 + cpp2rust/converter/converter_lib.cpp | 2 ++ tests/unit/expr_as_bool_cpp.cpp | 9 +++++++++ 3 files changed, 12 insertions(+) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index ce3cd07c1..e46eb8e6c 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2710,6 +2710,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { Convert(sub_expr); break; case clang::CastKind::CK_IntegralToBoolean: + case clang::CastKind::CK_FloatingToBoolean: ConvertIntegralToBooleanCast(expr); break; case clang::CastKind::CK_PointerToBoolean: diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 1aa18fea3..275d22f95 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -2131,6 +2131,8 @@ clang::Expr *NormalizeToBool(clang::Expr *expr, clang::ASTContext &ctx) { clang::CastKind cast_kind; if (expr->getType()->isPointerType()) { cast_kind = clang::CK_PointerToBoolean; + } else if (expr->getType()->isFloatingType()) { + cast_kind = clang::CK_FloatingToBoolean; } else /* expr->getType()->isIntegerType() */ { cast_kind = clang::CK_IntegralToBoolean; } diff --git a/tests/unit/expr_as_bool_cpp.cpp b/tests/unit/expr_as_bool_cpp.cpp index b5f759509..c0e6f6767 100644 --- a/tests/unit/expr_as_bool_cpp.cpp +++ b/tests/unit/expr_as_bool_cpp.cpp @@ -66,5 +66,14 @@ int main() { } assert(d == 0.0); + float f = 2.0f; + bool fb = f; + bool nf = !f; + assert(fb); + assert(!nf); + assert(!0.0); + int fi = (bool)f; + assert(fi == 1); + return 0; } From 6d255ae179a82a233bde1594d145be2ca66d8016 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 18:30:48 +0100 Subject: [PATCH 3/3] Update tests --- tests/unit/out/refcount/expr_as_bool_cpp.rs | 18 ++++++++++++++++++ tests/unit/out/unsafe/expr_as_bool_cpp.rs | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/tests/unit/out/refcount/expr_as_bool_cpp.rs b/tests/unit/out/refcount/expr_as_bool_cpp.rs index 6052881b0..297de44fc 100644 --- a/tests/unit/out/refcount/expr_as_bool_cpp.rs +++ b/tests/unit/out/refcount/expr_as_bool_cpp.rs @@ -74,6 +74,24 @@ fn main_0() -> i32 { assert!((({ cmp_or_ptr_1(Ptr::::null(), Ptr::::null(),) }) == 0)); assert!((({ both_null_2(Ptr::::null(), Ptr::::null(),) }) == 1)); assert!((({ both_null_2((p1).clone(), Ptr::::null(),) }) == 0)); + let mut d: f64 = 0.5_f64; + let mut taken: i32 = 0; + if (d != 0.0) { + taken = 1; + } + assert!((taken == 1)); + 'loop_: while (d != 0.0) { + d = 0_f64; + } + assert!((d == 0_f64)); + let mut f: f32 = 2_f32; + let mut fb: bool = (f != 0.0); + let mut nf: bool = !(f != 0.0); + assert!(fb); + assert!(!(nf)); + assert!(!(0_f64 != 0.0)); + let mut fi: i32 = ((f != 0.0) as i32); + assert!((fi == 1)); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/expr_as_bool_cpp.rs b/tests/unit/out/unsafe/expr_as_bool_cpp.rs index b65495ef1..740af06ef 100644 --- a/tests/unit/out/unsafe/expr_as_bool_cpp.rs +++ b/tests/unit/out/unsafe/expr_as_bool_cpp.rs @@ -76,6 +76,24 @@ unsafe fn main_0() -> i32 { assert!(((unsafe { cmp_or_ptr_1(std::ptr::null(), std::ptr::null(),) }) == (0))); assert!(((unsafe { both_null_2(std::ptr::null(), std::ptr::null(),) }) == (1))); assert!(((unsafe { both_null_2(p1, std::ptr::null(),) }) == (0))); + let mut d: f64 = 0.5_f64; + let mut taken: i32 = 0; + if (d != 0.0) { + taken = 1; + } + assert!(((taken) == (1))); + 'loop_: while (d != 0.0) { + d = 0_f64; + } + assert!(((d) == (0_f64))); + let mut f: f32 = 2_f32; + let mut fb: bool = (f != 0.0); + let mut nf: bool = !(f != 0.0); + assert!(fb); + assert!(!(nf)); + assert!(!(0_f64 != 0.0)); + let mut fi: i32 = ((f != 0.0) as i32); + assert!(((fi) == (1))); return 0; } pub unsafe fn __cpp2rust_init_globals() {}