diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index b63c7fcb3..e46eb8e6c 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; } @@ -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 21a91413b..c0e6f6767 100644 --- a/tests/unit/expr_as_bool_cpp.cpp +++ b/tests/unit/expr_as_bool_cpp.cpp @@ -55,5 +55,25 @@ 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); + + 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; } 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() {}