Skip to content

Commit f9b507b

Browse files
authored
Skip explicit specializations of template functions (#517)
1 parent 648d1b9 commit f9b507b

4 files changed

Lines changed: 68 additions & 42 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,10 @@ void Converter::ConvertFunctionBody(clang::FunctionDecl *decl) {
457457

458458
bool Converter::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *decl) {
459459
for (auto *function_decl : decl->specializations()) {
460+
if (function_decl->getTemplateSpecializationKind() ==
461+
clang::TSK_ExplicitSpecialization) {
462+
continue;
463+
}
460464
VisitFunctionDecl(function_decl);
461465
}
462466
return false;

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

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,32 @@ pub fn foo_0(mut x: i32) -> i32 {
1212
pub fn foo_1(mut x: f64) -> f64 {
1313
return x;
1414
}
15-
pub fn bar_2(mut p: Ptr<i32>, mut flag: bool) -> Ptr<i32> {
15+
pub fn pick_2() -> i32 {
16+
return 0;
17+
}
18+
pub fn pick_3() -> i32 {
19+
return 1;
20+
}
21+
pub fn bar_4(mut p: Ptr<i32>, mut flag: bool) -> Ptr<i32> {
1622
return if flag { p } else { Ptr::<i32>::null() };
1723
}
18-
pub fn bar_3(mut p: Ptr<f64>, mut flag: bool) -> Ptr<f64> {
24+
pub fn bar_5(mut p: Ptr<f64>, mut flag: bool) -> Ptr<f64> {
1925
return if flag { p } else { Ptr::<f64>::null() };
2026
}
21-
pub fn func_4(mut x1: i32, mut x2: i32, mut x3: i32) -> i32 {
27+
pub fn func_6(mut x1: i32, mut x2: i32, mut x3: i32) -> i32 {
2228
return ((x1 + x2) + x3);
2329
}
24-
pub fn func_5(mut x1: f64, mut x2: i32, mut x3: f64) -> i32 {
30+
pub fn func_7(mut x1: f64, mut x2: i32, mut x3: f64) -> i32 {
2531
return (((x1 + (x2 as f64)) + x3) as i32);
2632
}
2733
thread_local!(
28-
pub static half_6: Value<i32> = Rc::new(RefCell::new((1 / 2)));
34+
pub static half_8: Value<i32> = Rc::new(RefCell::new((1 / 2)));
2935
);
3036
thread_local!(
31-
pub static half_7: Value<f64> = Rc::new(RefCell::new((1_f64 / 2_f64)));
37+
pub static half_9: Value<f64> = Rc::new(RefCell::new((1_f64 / 2_f64)));
3238
);
3339
thread_local!(
34-
pub static half_8: Value<Ptr<i32>> = Rc::new(RefCell::new(Ptr::<i32>::null()));
40+
pub static half_10: Value<Ptr<i32>> = Rc::new(RefCell::new(Ptr::<i32>::null()));
3541
);
3642
pub fn main() {
3743
__cpp2rust_init_globals();
@@ -42,24 +48,26 @@ fn main_0() -> i32 {
4248
let y: Value<f64> = Rc::new(RefCell::new(((*x.borrow()) as f64)));
4349
assert!(
4450
(((((((({ foo_0((*x.borrow()),) }) as f64) + ({ foo_1((*y.borrow()),) }))
45-
+ ((({ bar_2((x.as_pointer()), true,) }).read()) as f64))
46-
+ (({ bar_3((y.as_pointer()), true,) }).read()))
47-
+ (({ func_4(1, 2, 3,) }) as f64))
48-
+ (({ func_5(2_f64, (*x.borrow()), (*y.borrow()),) }) as f64))
51+
+ ((({ bar_4((x.as_pointer()), true,) }).read()) as f64))
52+
+ (({ bar_5((y.as_pointer()), true,) }).read()))
53+
+ (({ func_6(1, 2, 3,) }) as f64))
54+
+ (({ func_7(2_f64, (*x.borrow()), (*y.borrow()),) }) as f64))
4955
== 68_f64)
5056
);
51-
assert!((half_6.with(|rc| *rc.borrow()) == 0));
52-
assert!((half_7.with(|rc| *rc.borrow()) == 0.5_f64));
53-
half_6.with(|rc| *rc.borrow_mut() = 7);
54-
assert!((half_6.with(|rc| *rc.borrow()) == 7));
55-
assert!((half_7.with(|rc| *rc.borrow()) == 0.5_f64));
56-
assert!((*half_8.with(Value::clone).borrow()).is_null());
57-
half_8.with(|rc| *rc.borrow_mut() = (x.as_pointer()));
58-
assert!((((*half_8.with(Value::clone).borrow()).read()) == 10));
57+
assert!((half_8.with(|rc| *rc.borrow()) == 0));
58+
assert!((half_9.with(|rc| *rc.borrow()) == 0.5_f64));
59+
half_8.with(|rc| *rc.borrow_mut() = 7);
60+
assert!((half_8.with(|rc| *rc.borrow()) == 7));
61+
assert!((half_9.with(|rc| *rc.borrow()) == 0.5_f64));
62+
assert!((*half_10.with(Value::clone).borrow()).is_null());
63+
half_10.with(|rc| *rc.borrow_mut() = (x.as_pointer()));
64+
assert!((((*half_10.with(Value::clone).borrow()).read()) == 10));
65+
assert!((({ pick_3() }) == 1));
66+
assert!((({ pick_2() }) == 0));
5967
return 0;
6068
}
6169
pub fn __cpp2rust_init_globals() {
62-
let _ = half_6.with(|_| ());
63-
let _ = half_7.with(|_| ());
6470
let _ = half_8.with(|_| ());
71+
let _ = half_9.with(|_| ());
72+
let _ = half_10.with(|_| ());
6573
}

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

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,29 @@ pub unsafe fn foo_0(mut x: i32) -> i32 {
1212
pub unsafe fn foo_1(mut x: f64) -> f64 {
1313
return x;
1414
}
15-
pub unsafe fn bar_2(mut p: *mut i32, mut flag: bool) -> *mut i32 {
15+
pub unsafe fn pick_2() -> i32 {
16+
return 0;
17+
}
18+
pub unsafe fn pick_3() -> i32 {
19+
return 1;
20+
}
21+
pub unsafe fn bar_4(mut p: *mut i32, mut flag: bool) -> *mut i32 {
1622
return if flag { p } else { std::ptr::null_mut() };
1723
}
18-
pub unsafe fn bar_3(mut p: *mut f64, mut flag: bool) -> *mut f64 {
24+
pub unsafe fn bar_5(mut p: *mut f64, mut flag: bool) -> *mut f64 {
1925
return if flag { p } else { std::ptr::null_mut() };
2026
}
21-
pub unsafe fn func_4(mut x1: i32, mut x2: i32, mut x3: i32) -> i32 {
27+
pub unsafe fn func_6(mut x1: i32, mut x2: i32, mut x3: i32) -> i32 {
2228
return (((x1) + (x2)) + (x3));
2329
}
24-
pub unsafe fn func_5(mut x1: f64, mut x2: i32, mut x3: f64) -> i32 {
30+
pub unsafe fn func_7(mut x1: f64, mut x2: i32, mut x3: f64) -> i32 {
2531
return ((((x1) + (x2 as f64)) + (x3)) as i32);
2632
}
27-
pub static mut half_6: std::cell::LazyCell<i32> =
33+
pub static mut half_8: std::cell::LazyCell<i32> =
2834
std::cell::LazyCell::new(|| unsafe { ((1) / (2)) });
29-
pub static mut half_7: std::cell::LazyCell<f64> =
35+
pub static mut half_9: std::cell::LazyCell<f64> =
3036
std::cell::LazyCell::new(|| unsafe { ((1_f64) / (2_f64)) });
31-
pub static mut half_8: std::cell::LazyCell<*mut i32> =
37+
pub static mut half_10: std::cell::LazyCell<*mut i32> =
3238
std::cell::LazyCell::new(|| unsafe { std::ptr::null_mut() });
3339
pub fn main() {
3440
unsafe {
@@ -41,24 +47,26 @@ unsafe fn main_0() -> i32 {
4147
let mut y: f64 = (x as f64);
4248
assert!(
4349
((((((((unsafe { foo_0(x,) }) as f64) + (unsafe { foo_1(y,) }))
44-
+ ((*(unsafe { bar_2((&mut x as *mut i32), true,) })) as f64))
45-
+ (*(unsafe { bar_3((&mut y as *mut f64), true,) })))
46-
+ ((unsafe { func_4(1, 2, 3,) }) as f64))
47-
+ ((unsafe { func_5(2_f64, x, y,) }) as f64))
50+
+ ((*(unsafe { bar_4((&mut x as *mut i32), true,) })) as f64))
51+
+ (*(unsafe { bar_5((&mut y as *mut f64), true,) })))
52+
+ ((unsafe { func_6(1, 2, 3,) }) as f64))
53+
+ ((unsafe { func_7(2_f64, x, y,) }) as f64))
4854
== (68_f64))
4955
);
50-
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_6)) == (0)));
51-
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_7)) == (0.5_f64)));
52-
(*std::cell::LazyCell::force_mut(&mut *&raw mut half_6)) = 7;
53-
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_6)) == (7)));
54-
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_7)) == (0.5_f64)));
55-
assert!((*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)).is_null());
56-
(*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)) = (&mut x as *mut i32);
57-
assert!(((*(*std::cell::LazyCell::force_mut(&mut *&raw mut half_8))) == (10)));
56+
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)) == (0)));
57+
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_9)) == (0.5_f64)));
58+
(*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)) = 7;
59+
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_8)) == (7)));
60+
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_9)) == (0.5_f64)));
61+
assert!((*std::cell::LazyCell::force_mut(&mut *&raw mut half_10)).is_null());
62+
(*std::cell::LazyCell::force_mut(&mut *&raw mut half_10)) = (&mut x as *mut i32);
63+
assert!(((*(*std::cell::LazyCell::force_mut(&mut *&raw mut half_10))) == (10)));
64+
assert!(((unsafe { pick_3() }) == (1)));
65+
assert!(((unsafe { pick_2() }) == (0)));
5866
return 0;
5967
}
6068
pub unsafe fn __cpp2rust_init_globals() {
61-
std::cell::LazyCell::force(&*&raw const half_6);
62-
std::cell::LazyCell::force(&*&raw const half_7);
6369
std::cell::LazyCell::force(&*&raw const half_8);
70+
std::cell::LazyCell::force(&*&raw const half_9);
71+
std::cell::LazyCell::force(&*&raw const half_10);
6472
}

‎tests/unit/templates.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
template <typename T> T foo(T x) { return x; }
44

5+
template <bool B> int pick() { return 0; }
6+
7+
template <> int pick<true>() { return 1; }
8+
59
template <typename T> T *bar(T *p, bool flag) { return flag ? p : nullptr; }
610

711
template <typename T1, typename T2, typename T3> int func(T1 x1, T2 x2, T3 x3) {
@@ -26,5 +30,7 @@ int main() {
2630
assert(half<int *> == nullptr);
2731
half<int *> = &x;
2832
assert(*half<int *> == 10);
33+
assert(pick<true>() == 1);
34+
assert(pick<false>() == 0);
2935
return 0;
3036
}

0 commit comments

Comments
 (0)