diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 779cfdc0b..62f511db5 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1382,13 +1382,15 @@ bool Converter::VisitIfStmt(clang::IfStmt *stmt) { stmt->setInit(init); return false; } - StrCat(keyword::kIf); - if (auto *cond = clang::dyn_cast(stmt->getCond()); - cond && stmt->isConstexpr()) { - StrCat(cond->getResultAsAPSInt() != 0 ? keyword::kTrue : keyword::kFalse); - } else { - ConvertCondition(stmt->getCond()); + if (bool taken = false; + !stmt->getConditionVariable() && !stmt->isConsteval() && + !stmt->getCond()->isValueDependent() && + stmt->getCond()->EvaluateAsBooleanCondition(taken, ctx_)) { + ConvertBody(taken ? stmt->getThen() : stmt->getElse()); + return false; } + StrCat(keyword::kIf); + ConvertCondition(stmt->getCond()); ConvertBody(stmt->getThen()); if (stmt->hasElseStorage()) { StrCat(keyword::kElse); diff --git a/tests/unit/if_constexpr.cpp b/tests/unit/if_constexpr.cpp index aadcbb666..54879dd2a 100644 --- a/tests/unit/if_constexpr.cpp +++ b/tests/unit/if_constexpr.cpp @@ -18,11 +18,22 @@ int keep_both(int x) { } } +template unsigned long long widen(T v) { + if (sizeof(T) > 4) { + T hi = v; + hi <<= 32; + return hi; + } + return v; +} + int main() { int v = 7; assert(classify(&v) == 7); assert(classify(1L) == 2); assert(classify(1) == 1); assert(keep_both(1) == 2); + assert(widen(1u) == 1); + assert(widen(1ull) == 4294967296ull); return 0; } diff --git a/tests/unit/out/refcount/concepts.rs b/tests/unit/out/refcount/concepts.rs index 2ab6dc0c3..b91ee787d 100644 --- a/tests/unit/out/refcount/concepts.rs +++ b/tests/unit/out/refcount/concepts.rs @@ -27,21 +27,17 @@ pub fn has_size_3() -> bool { return false; } pub fn pick_4(mut x: i32) -> i32 { - if (true) && (true) { + { return 1; } return 2; } pub fn pick_5(mut x: i64) -> i32 { - if (true) && (false) { - return 1; - } + {} return 2; } pub fn pick_6(mut x: f32) -> i32 { - if (false) && (true) { - return 1; - } + {} return 2; } pub fn main() { diff --git a/tests/unit/out/refcount/constexpr_function.rs b/tests/unit/out/refcount/constexpr_function.rs index 28f315cb8..1b3f7f644 100644 --- a/tests/unit/out/refcount/constexpr_function.rs +++ b/tests/unit/out/refcount/constexpr_function.rs @@ -37,9 +37,7 @@ pub fn checked_5(mut x: i32) -> i32 { return (x + 1); } pub fn in_constant_context_6() -> bool { - if false { - return true; - } + {} return (({ runtime_only_0(1) }) == 0); } const _: () = assert!(true, "in_constant_context()"); diff --git a/tests/unit/out/refcount/if_constexpr.rs b/tests/unit/out/refcount/if_constexpr.rs index 71b8073fe..6b8593941 100644 --- a/tests/unit/out/refcount/if_constexpr.rs +++ b/tests/unit/out/refcount/if_constexpr.rs @@ -7,33 +7,43 @@ use std::io::{Read, Seek, Write}; use std::os::fd::AsFd; use std::rc::{Rc, Weak}; pub fn classify_0(mut x: Ptr) -> i32 { - if true { + { return (x.read()); - } else { } return 1; } pub fn classify_1(mut x: i64) -> i32 { - if false { - } else if true { - return 2; + { + { + return 2; + } } return 1; } pub fn classify_2(mut x: i32) -> i32 { - if false { - } else if false { + { + {} } return 1; } pub fn keep_both_3(mut x: i32) -> i32 { - if true { + { return (x + 1); - } else { - return (x - 1); } panic!("ub: non-void function does not return a value") } +pub fn widen_4(mut v: u32) -> u64 { + {} + return (v as u64); +} +pub fn widen_5(mut v: u64) -> u64 { + { + let mut hi: u64 = v; + hi <<= 32; + return hi; + } + return v; +} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -44,6 +54,8 @@ fn main_0() -> i32 { assert!((({ classify_1(1_i64,) }) == 2)); assert!((({ classify_2(1,) }) == 1)); assert!((({ keep_both_3(1,) }) == 2)); + assert!((({ widen_4(1_u32,) }) == 1_u64)); + assert!((({ widen_5(1_u64,) }) == 4294967296_u64)); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/concepts.rs b/tests/unit/out/unsafe/concepts.rs index b946625ef..0af8c5033 100644 --- a/tests/unit/out/unsafe/concepts.rs +++ b/tests/unit/out/unsafe/concepts.rs @@ -32,21 +32,17 @@ pub unsafe fn has_size_3() -> bool { return false; } pub unsafe fn pick_4(mut x: i32) -> i32 { - if (true) && (true) { + { return 1; } return 2; } pub unsafe fn pick_5(mut x: i64) -> i32 { - if (true) && (false) { - return 1; - } + {} return 2; } pub unsafe fn pick_6(mut x: f32) -> i32 { - if (false) && (true) { - return 1; - } + {} return 2; } pub fn main() { diff --git a/tests/unit/out/unsafe/constexpr_function.rs b/tests/unit/out/unsafe/constexpr_function.rs index c2d784e5c..7541e2805 100644 --- a/tests/unit/out/unsafe/constexpr_function.rs +++ b/tests/unit/out/unsafe/constexpr_function.rs @@ -40,9 +40,7 @@ pub unsafe fn checked_5(mut x: i32) -> i32 { return ((x) + (1)); } pub unsafe fn in_constant_context_6() -> bool { - if false { - return true; - } + {} return ((unsafe { runtime_only_0(1) }) == (0)); } const _: () = assert!(true, "in_constant_context()"); diff --git a/tests/unit/out/unsafe/if_constexpr.rs b/tests/unit/out/unsafe/if_constexpr.rs index f4ff0e72f..3de552e90 100644 --- a/tests/unit/out/unsafe/if_constexpr.rs +++ b/tests/unit/out/unsafe/if_constexpr.rs @@ -7,33 +7,43 @@ use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; pub unsafe fn classify_0(mut x: *mut i32) -> i32 { - if true { + { return (*x); - } else { } return 1; } pub unsafe fn classify_1(mut x: i64) -> i32 { - if false { - } else if true { - return 2; + { + { + return 2; + } } return 1; } pub unsafe fn classify_2(mut x: i32) -> i32 { - if false { - } else if false { + { + {} } return 1; } pub unsafe fn keep_both_3(mut x: i32) -> i32 { - if true { + { return ((x) + (1)); - } else { - return ((x) - (1)); } panic!("ub: non-void function does not return a value") } +pub unsafe fn widen_4(mut v: u32) -> u64 { + {} + return (v as u64); +} +pub unsafe fn widen_5(mut v: u64) -> u64 { + { + let mut hi: u64 = v; + hi <<= 32; + return hi; + } + return v; +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -46,6 +56,8 @@ unsafe fn main_0() -> i32 { assert!(((unsafe { classify_1(1_i64,) }) == (2))); assert!(((unsafe { classify_2(1,) }) == (1))); assert!(((unsafe { keep_both_3(1,) }) == (2))); + assert!(((unsafe { widen_4(1_u32,) }) == (1_u64))); + assert!(((unsafe { widen_5(1_u64,) }) == (4294967296_u64))); return 0; } pub unsafe fn __cpp2rust_init_globals() {}