diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index b63c7fcb3..89926f566 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -453,6 +453,10 @@ void Converter::ConvertFunctionBody(clang::FunctionDecl *decl) { bool Converter::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *decl) { for (auto *function_decl : decl->specializations()) { + if (function_decl->getTemplateSpecializationKind() == + clang::TSK_ExplicitSpecialization) { + continue; + } VisitFunctionDecl(function_decl); } return false; diff --git a/tests/unit/out/refcount/templates.rs b/tests/unit/out/refcount/templates.rs index 9f635cc3a..ffa1b0c10 100644 --- a/tests/unit/out/refcount/templates.rs +++ b/tests/unit/out/refcount/templates.rs @@ -12,26 +12,32 @@ pub fn foo_0(mut x: i32) -> i32 { pub fn foo_1(mut x: f64) -> f64 { return x; } -pub fn bar_2(mut p: Ptr, mut flag: bool) -> Ptr { +pub fn pick_2() -> i32 { + return 0; +} +pub fn pick_3() -> i32 { + return 1; +} +pub fn bar_4(mut p: Ptr, mut flag: bool) -> Ptr { return if flag { p } else { Ptr::::null() }; } -pub fn bar_3(mut p: Ptr, mut flag: bool) -> Ptr { +pub fn bar_5(mut p: Ptr, mut flag: bool) -> Ptr { return if flag { p } else { Ptr::::null() }; } -pub fn func_4(mut x1: i32, mut x2: i32, mut x3: i32) -> i32 { +pub fn func_6(mut x1: i32, mut x2: i32, mut x3: i32) -> i32 { return ((x1 + x2) + x3); } -pub fn func_5(mut x1: f64, mut x2: i32, mut x3: f64) -> i32 { +pub fn func_7(mut x1: f64, mut x2: i32, mut x3: f64) -> i32 { return (((x1 + (x2 as f64)) + x3) as i32); } thread_local!( - pub static half_6: Value = Rc::new(RefCell::new((1 / 2))); + pub static half_8: Value = Rc::new(RefCell::new((1 / 2))); ); thread_local!( - pub static half_7: Value = Rc::new(RefCell::new((1_f64 / 2_f64))); + pub static half_9: Value = Rc::new(RefCell::new((1_f64 / 2_f64))); ); thread_local!( - pub static half_8: Value> = Rc::new(RefCell::new(Ptr::::null())); + pub static half_10: Value> = Rc::new(RefCell::new(Ptr::::null())); ); pub fn main() { __cpp2rust_init_globals(); @@ -42,24 +48,26 @@ fn main_0() -> i32 { let y: Value = Rc::new(RefCell::new(((*x.borrow()) as f64))); assert!( (((((((({ foo_0((*x.borrow()),) }) as f64) + ({ foo_1((*y.borrow()),) })) - + ((({ bar_2((x.as_pointer()), true,) }).read()) as f64)) - + (({ bar_3((y.as_pointer()), true,) }).read())) - + (({ func_4(1, 2, 3,) }) as f64)) - + (({ func_5(2_f64, (*x.borrow()), (*y.borrow()),) }) as f64)) + + ((({ bar_4((x.as_pointer()), true,) }).read()) as f64)) + + (({ bar_5((y.as_pointer()), true,) }).read())) + + (({ func_6(1, 2, 3,) }) as f64)) + + (({ func_7(2_f64, (*x.borrow()), (*y.borrow()),) }) as f64)) == 68_f64) ); - assert!((half_6.with(|rc| *rc.borrow()) == 0)); - assert!((half_7.with(|rc| *rc.borrow()) == 0.5_f64)); - half_6.with(|rc| *rc.borrow_mut() = 7); - assert!((half_6.with(|rc| *rc.borrow()) == 7)); - assert!((half_7.with(|rc| *rc.borrow()) == 0.5_f64)); - assert!((*half_8.with(Value::clone).borrow()).is_null()); - half_8.with(|rc| *rc.borrow_mut() = (x.as_pointer())); - assert!((((*half_8.with(Value::clone).borrow()).read()) == 10)); + assert!((half_8.with(|rc| *rc.borrow()) == 0)); + assert!((half_9.with(|rc| *rc.borrow()) == 0.5_f64)); + half_8.with(|rc| *rc.borrow_mut() = 7); + assert!((half_8.with(|rc| *rc.borrow()) == 7)); + assert!((half_9.with(|rc| *rc.borrow()) == 0.5_f64)); + assert!((*half_10.with(Value::clone).borrow()).is_null()); + half_10.with(|rc| *rc.borrow_mut() = (x.as_pointer())); + assert!((((*half_10.with(Value::clone).borrow()).read()) == 10)); + assert!((({ pick_3() }) == 1)); + assert!((({ pick_2() }) == 0)); return 0; } pub fn __cpp2rust_init_globals() { - let _ = half_6.with(|_| ()); - let _ = half_7.with(|_| ()); let _ = half_8.with(|_| ()); + let _ = half_9.with(|_| ()); + let _ = half_10.with(|_| ()); } diff --git a/tests/unit/out/unsafe/templates.rs b/tests/unit/out/unsafe/templates.rs index b74e9818f..cbddf04b8 100644 --- a/tests/unit/out/unsafe/templates.rs +++ b/tests/unit/out/unsafe/templates.rs @@ -12,23 +12,29 @@ pub unsafe fn foo_0(mut x: i32) -> i32 { pub unsafe fn foo_1(mut x: f64) -> f64 { return x; } -pub unsafe fn bar_2(mut p: *mut i32, mut flag: bool) -> *mut i32 { +pub unsafe fn pick_2() -> i32 { + return 0; +} +pub unsafe fn pick_3() -> i32 { + return 1; +} +pub unsafe fn bar_4(mut p: *mut i32, mut flag: bool) -> *mut i32 { return if flag { p } else { std::ptr::null_mut() }; } -pub unsafe fn bar_3(mut p: *mut f64, mut flag: bool) -> *mut f64 { +pub unsafe fn bar_5(mut p: *mut f64, mut flag: bool) -> *mut f64 { return if flag { p } else { std::ptr::null_mut() }; } -pub unsafe fn func_4(mut x1: i32, mut x2: i32, mut x3: i32) -> i32 { +pub unsafe fn func_6(mut x1: i32, mut x2: i32, mut x3: i32) -> i32 { return (((x1) + (x2)) + (x3)); } -pub unsafe fn func_5(mut x1: f64, mut x2: i32, mut x3: f64) -> i32 { +pub unsafe fn func_7(mut x1: f64, mut x2: i32, mut x3: f64) -> i32 { return ((((x1) + (x2 as f64)) + (x3)) as i32); } -pub static mut half_6: std::cell::LazyCell = +pub static mut half_8: std::cell::LazyCell = std::cell::LazyCell::new(|| unsafe { ((1) / (2)) }); -pub static mut half_7: std::cell::LazyCell = +pub static mut half_9: std::cell::LazyCell = std::cell::LazyCell::new(|| unsafe { ((1_f64) / (2_f64)) }); -pub static mut half_8: std::cell::LazyCell<*mut i32> = +pub static mut half_10: std::cell::LazyCell<*mut i32> = std::cell::LazyCell::new(|| unsafe { std::ptr::null_mut() }); pub fn main() { unsafe { @@ -41,24 +47,26 @@ unsafe fn main_0() -> i32 { let mut y: f64 = (x as f64); assert!( ((((((((unsafe { foo_0(x,) }) as f64) + (unsafe { foo_1(y,) })) - + ((*(unsafe { bar_2((&mut x as *mut i32), true,) })) as f64)) - + (*(unsafe { bar_3((&mut y as *mut f64), true,) }))) - + ((unsafe { func_4(1, 2, 3,) }) as f64)) - + ((unsafe { func_5(2_f64, x, y,) }) as f64)) + + ((*(unsafe { bar_4((&mut x as *mut i32), true,) })) as f64)) + + (*(unsafe { bar_5((&mut y as *mut f64), true,) }))) + + ((unsafe { func_6(1, 2, 3,) }) as f64)) + + ((unsafe { func_7(2_f64, x, y,) }) as f64)) == (68_f64)) ); - assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_6)) == (0))); - assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_7)) == (0.5_f64))); - (*std::cell::LazyCell::force_mut(&mut *&raw mut half_6)) = 7; - assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_6)) == (7))); - assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_7)) == (0.5_f64))); - assert!((*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)).is_null()); - (*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)) = (&mut x as *mut i32); - assert!(((*(*std::cell::LazyCell::force_mut(&mut *&raw mut half_8))) == (10))); + assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)) == (0))); + assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_9)) == (0.5_f64))); + (*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)) = 7; + assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)) == (7))); + assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_9)) == (0.5_f64))); + assert!((*std::cell::LazyCell::force_mut(&mut *&raw mut half_10)).is_null()); + (*std::cell::LazyCell::force_mut(&mut *&raw mut half_10)) = (&mut x as *mut i32); + assert!(((*(*std::cell::LazyCell::force_mut(&mut *&raw mut half_10))) == (10))); + assert!(((unsafe { pick_3() }) == (1))); + assert!(((unsafe { pick_2() }) == (0))); return 0; } pub unsafe fn __cpp2rust_init_globals() { - std::cell::LazyCell::force(&*&raw const half_6); - std::cell::LazyCell::force(&*&raw const half_7); std::cell::LazyCell::force(&*&raw const half_8); + std::cell::LazyCell::force(&*&raw const half_9); + std::cell::LazyCell::force(&*&raw const half_10); } diff --git a/tests/unit/templates.cpp b/tests/unit/templates.cpp index 15a371b6a..8cad05f44 100644 --- a/tests/unit/templates.cpp +++ b/tests/unit/templates.cpp @@ -2,6 +2,10 @@ template T foo(T x) { return x; } +template int pick() { return 0; } + +template <> int pick() { return 1; } + template T *bar(T *p, bool flag) { return flag ? p : nullptr; } template int func(T1 x1, T2 x2, T3 x3) { @@ -26,5 +30,7 @@ int main() { assert(half == nullptr); half = &x; assert(*half == 10); + assert(pick() == 1); + assert(pick() == 0); return 0; }