ConvertIRFragment uses Mapper::GetParamType to set PlaceholderCtx::param_type. This field is then used to emit casts when needed, e.g.:
|
if (ph_ctx.declared_in_rule_as_rust_ptr && arg->getType()->isArrayType()) { |
|
return std::format("({} as {})", ConvertFreshPointer(arg), |
|
ph_ctx.param_type); |
|
} |
Consider a function template <typename T> T foo(T (&)[4]); and the following rules:
// src.cpp
template <typename T1> T1 f1(T1 (&a0)[4]) { return foo(a0); }
// tgt_refcount.rs
fn f1<T1: ByteRepr + Default + Clone>(a0: Ptr<T1>) -> T1 {
a0.write(Default::default());
a0.with(|t| t.clone())
}
The following translation is generated:
int main() {
size_t arr1[] = {1, 2, 3, 4};
foo(arr1);
return 0;
}
fn main_0() -> i32 {
let arr1: Value<Box<[usize]>> =
Rc::new(RefCell::new(Box::new([1_usize, 2_usize, 3_usize, 4_usize])));
{
(arr1.as_pointer() as Ptr<u64>).write(Default::default()); // should be ... as Ptr<usize>
(arr1.as_pointer() as Ptr<u64>).with(|t| t.clone()) // should be ... as Ptr<usize>
};
return 0;
}
This example exercises the branch shown at the beginning. The issue is that Mapper::GetParamType looks up the argument type on the callee's declaration. When Clang instantiates a function template, template arguments are canonicalized before the specialization is looked up or created. As a result, our callee (foo) has an argument of type unsigned long (&)[4] rather than size_t (&)[4]. Consequently, Mapper::GetParamType returns the mapping for the canonical type (Ptr<u64>) instead of the mapping for the sugared type (Ptr<usize>).
This will affect any sugared type whose translation differs from that of its canonical counterpart.
ConvertIRFragmentusesMapper::GetParamTypeto setPlaceholderCtx::param_type. This field is then used to emit casts when needed, e.g.:cpp2rust/cpp2rust/converter/converter.cpp
Lines 4190 to 4193 in 2cfd406
Consider a function
template <typename T> T foo(T (&)[4]);and the following rules:The following translation is generated:
This example exercises the branch shown at the beginning. The issue is that
Mapper::GetParamTypelooks up the argument type on the callee's declaration. When Clang instantiates a function template, template arguments are canonicalized before the specialization is looked up or created. As a result, our callee (foo) has an argument of typeunsigned long (&)[4]rather thansize_t (&)[4]. Consequently,Mapper::GetParamTypereturns the mapping for the canonical type (Ptr<u64>) instead of the mapping for the sugared type (Ptr<usize>).This will affect any sugared type whose translation differs from that of its canonical counterpart.