Closed
Description
In the current implementation of cppfront, we can use a forward return passing style to return a reference from a function or use decltype(auto)
to return an exact cv-qualified type.
Unfortunately, in some cases, it produces the wrong cpp1 code. E.g., in the following code:
fun4: (i : int) -> forward int = {
return i;
}
fun4_in: (in i : int) -> forward int = {
return i;
}
fun4_copy: (copy i : int) -> forward int = {
return i;
}
fun4_move: (move i : int) -> forward int = {
return i;
}
fun4_forward: (forward i : int) -> forward int = {
return i;
}
Generates (skipping boilerplate):
[[nodiscard]] auto fun4(cpp2::in<int> i) -> int&{ // should be `const int&`
return i;
}
[[nodiscard]] auto fun4_in(cpp2::in<int> i) -> int&{ // should be `const int&`
return i;
}
[[nodiscard]] auto fun4_copy(int i) -> int&{ // non-const reference bind to temporary (maybe decltype(auto)?)
return std::move(i);
}
[[nodiscard]] auto fun4_move(int&& i) -> int&{ // non-const reference bind to temporary (maybe decltype(auto)?)
return std::move(i);
}
[[nodiscard]] auto fun4_forward(auto&& i) -> int& // should be decltype(auto) to forward type
requires std::is_same_v<CPP2_TYPEOF(i), int>
#line 18 "tests/bug_forward_return.cpp2"
{ return CPP2_FORWARD(i);
}