From d7054bcaff57e1a0ce168e65fba31a0d197bec45 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 3 Sep 2026 11:09:41 +0100 Subject: [PATCH 1/2] Translate if constexpr --- cpp2rust/converter/converter.cpp | 8 ++++++++ cpp2rust/converter/converter.h | 1 + 2 files changed, 9 insertions(+) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 038c2cb9..1d76f297 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1254,6 +1254,14 @@ void Converter::ConvertCondition(clang::Expr *cond) { } bool Converter::VisitIfStmt(clang::IfStmt *stmt) { + if (stmt->isConstexpr()) { + if (auto taken = stmt->getNondiscardedCase(ctx_)) { + if (*taken) { + Convert(*taken); + } + return false; + } + } StrCat(keyword::kIf); ConvertCondition(stmt->getCond()); ConvertBody(stmt->getThen()); diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index a06830fe..e046e835 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -405,6 +405,7 @@ class Converter : public clang::RecursiveASTVisitor { VisitUnaryExprOrTypeTraitExpr(clang::UnaryExprOrTypeTraitExpr *expr); virtual bool VisitTypeTraitExpr(clang::TypeTraitExpr *expr); + virtual bool VisitSizeOfPackExpr(clang::SizeOfPackExpr *expr); virtual bool VisitOffsetOfExpr(clang::OffsetOfExpr *expr); From 44693a174f8b11b5f082b051bd8a345265043e13 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 9 Sep 2026 22:17:05 +0100 Subject: [PATCH 2/2] Add if constexpr test --- tests/unit/if_constexpr.cpp | 19 +++++++++++++ tests/unit/out/refcount/if_constexpr.rs | 36 +++++++++++++++++++++++++ tests/unit/out/unsafe/if_constexpr.rs | 35 ++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 tests/unit/if_constexpr.cpp create mode 100644 tests/unit/out/refcount/if_constexpr.rs create mode 100644 tests/unit/out/unsafe/if_constexpr.rs diff --git a/tests/unit/if_constexpr.cpp b/tests/unit/if_constexpr.cpp new file mode 100644 index 00000000..53fba5cb --- /dev/null +++ b/tests/unit/if_constexpr.cpp @@ -0,0 +1,19 @@ +#include +#include + +template int classify(T x) { + if constexpr (std::is_pointer_v) { + return *x; + } else if constexpr (sizeof(T) > 4) { + return 2; + } + return 1; +} + +int main() { + int v = 7; + assert(classify(&v) == 7); + assert(classify(1L) == 2); + assert(classify(1) == 1); + return 0; +} diff --git a/tests/unit/out/refcount/if_constexpr.rs b/tests/unit/out/refcount/if_constexpr.rs new file mode 100644 index 00000000..b6e3d828 --- /dev/null +++ b/tests/unit/out/refcount/if_constexpr.rs @@ -0,0 +1,36 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn classify_0(x: Ptr) -> i32 { + let x: Value> = Rc::new(RefCell::new(x)); + { + return ((*x.borrow()).read()); + } + return 1; +} +pub fn classify_1(x: i64) -> i32 { + let x: Value = Rc::new(RefCell::new(x)); + { + return 2; + } + return 1; +} +pub fn classify_2(x: i32) -> i32 { + let x: Value = Rc::new(RefCell::new(x)); + return 1; +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let v: Value = Rc::new(RefCell::new(7)); + assert!((({ classify_0((v.as_pointer()),) }) == 7)); + assert!((({ classify_1(1_i64,) }) == 2)); + assert!((({ classify_2(1,) }) == 1)); + return 0; +} diff --git a/tests/unit/out/unsafe/if_constexpr.rs b/tests/unit/out/unsafe/if_constexpr.rs new file mode 100644 index 00000000..b44df521 --- /dev/null +++ b/tests/unit/out/unsafe/if_constexpr.rs @@ -0,0 +1,35 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +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 { + { + return (*x); + } + return 1; +} +pub unsafe fn classify_1(mut x: i64) -> i32 { + { + return 2; + } + return 1; +} +pub unsafe fn classify_2(mut x: i32) -> i32 { + return 1; +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut v: i32 = 7; + assert!(((unsafe { classify_0((&mut v as *mut i32),) }) == (7))); + assert!(((unsafe { classify_1(1_i64,) }) == (2))); + assert!(((unsafe { classify_2(1,) }) == (1))); + return 0; +}