Skip to content

Commit 3d2ee33

Browse files
committed
Keep untaken branches on if-constexpr in non-template context
1 parent 1d0db12 commit 3d2ee33

4 files changed

Lines changed: 48 additions & 14 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,15 +1356,6 @@ void Converter::ConvertCondition(clang::Expr *cond) {
13561356
}
13571357

13581358
bool Converter::VisitIfStmt(clang::IfStmt *stmt) {
1359-
if (stmt->isConstexpr()) {
1360-
if (auto taken = stmt->getNondiscardedCase(ctx_)) {
1361-
if (*taken) {
1362-
Convert(*taken);
1363-
}
1364-
return false;
1365-
}
1366-
}
1367-
13681359
if (auto *init = stmt->getInit()) {
13691360
PushBrace scope(*this);
13701361
Convert(init);
@@ -1374,7 +1365,12 @@ bool Converter::VisitIfStmt(clang::IfStmt *stmt) {
13741365
return false;
13751366
}
13761367
StrCat(keyword::kIf);
1377-
ConvertCondition(stmt->getCond());
1368+
if (auto *cond = clang::dyn_cast<clang::ConstantExpr>(stmt->getCond());
1369+
cond && stmt->isConstexpr()) {
1370+
StrCat(cond->getResultAsAPSInt() != 0 ? keyword::kTrue : keyword::kFalse);
1371+
} else {
1372+
ConvertCondition(stmt->getCond());
1373+
}
13781374
ConvertBody(stmt->getThen());
13791375
if (stmt->hasElseStorage()) {
13801376
StrCat(keyword::kElse);

‎tests/unit/if_constexpr.cpp‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,19 @@ template <typename T> int classify(T x) {
1010
return 1;
1111
}
1212

13+
int keep_both(int x) {
14+
if constexpr (sizeof(int) > 2) {
15+
return x + 1;
16+
} else {
17+
return x - 1;
18+
}
19+
}
20+
1321
int main() {
1422
int v = 7;
1523
assert(classify(&v) == 7);
1624
assert(classify(1L) == 2);
1725
assert(classify(1) == 1);
26+
assert(keep_both(1) == 2);
1827
return 0;
1928
}

‎tests/unit/out/refcount/if_constexpr.rs‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,36 @@ use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
99
pub fn classify_0(x: Ptr<i32>) -> i32 {
1010
let x: Value<Ptr<i32>> = Rc::new(RefCell::new(x));
11-
{
11+
if true {
1212
return ((*x.borrow()).read());
13+
} else {
1314
}
1415
return 1;
1516
}
1617
pub fn classify_1(x: i64) -> i32 {
1718
let x: Value<i64> = Rc::new(RefCell::new(x));
18-
{
19+
if false {
20+
} else if true {
1921
return 2;
2022
}
2123
return 1;
2224
}
2325
pub fn classify_2(x: i32) -> i32 {
2426
let x: Value<i32> = Rc::new(RefCell::new(x));
27+
if false {
28+
} else if false {
29+
}
2530
return 1;
2631
}
32+
pub fn keep_both_3(x: i32) -> i32 {
33+
let x: Value<i32> = Rc::new(RefCell::new(x));
34+
if true {
35+
return ((*x.borrow()) + 1);
36+
} else {
37+
return ((*x.borrow()) - 1);
38+
}
39+
panic!("ub: non-void function does not return a value")
40+
}
2741
pub fn main() {
2842
__cpp2rust_init_globals();
2943
std::process::exit(main_0());
@@ -33,6 +47,7 @@ fn main_0() -> i32 {
3347
assert!((({ classify_0((v.as_pointer()),) }) == 7));
3448
assert!((({ classify_1(1_i64,) }) == 2));
3549
assert!((({ classify_2(1,) }) == 1));
50+
assert!((({ keep_both_3(1,) }) == 2));
3651
return 0;
3752
}
3853
pub fn __cpp2rust_init_globals() {}

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,33 @@ use std::io::{Read, Seek, Write};
77
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
99
pub unsafe fn classify_0(mut x: *mut i32) -> i32 {
10-
{
10+
if true {
1111
return (*x);
12+
} else {
1213
}
1314
return 1;
1415
}
1516
pub unsafe fn classify_1(mut x: i64) -> i32 {
16-
{
17+
if false {
18+
} else if true {
1719
return 2;
1820
}
1921
return 1;
2022
}
2123
pub unsafe fn classify_2(mut x: i32) -> i32 {
24+
if false {
25+
} else if false {
26+
}
2227
return 1;
2328
}
29+
pub unsafe fn keep_both_3(mut x: i32) -> i32 {
30+
if true {
31+
return ((x) + (1));
32+
} else {
33+
return ((x) - (1));
34+
}
35+
panic!("ub: non-void function does not return a value")
36+
}
2437
pub fn main() {
2538
unsafe {
2639
__cpp2rust_init_globals();
@@ -32,6 +45,7 @@ unsafe fn main_0() -> i32 {
3245
assert!(((unsafe { classify_0((&mut v as *mut i32),) }) == (7)));
3346
assert!(((unsafe { classify_1(1_i64,) }) == (2)));
3447
assert!(((unsafe { classify_2(1,) }) == (1)));
48+
assert!(((unsafe { keep_both_3(1,) }) == (2)));
3549
return 0;
3650
}
3751
pub unsafe fn __cpp2rust_init_globals() {}

0 commit comments

Comments
 (0)