[BUG] Last use of an object resulting in `std::move` is incompatible with CTAD
bluetarpmedia opened this issue · comments
Neil Henderson commented
Describe the bug
Cppfront generates a std::move
for the last-use of an object, but this can cause problems if that last-use is an argument passed to a constructor which is relying on CTAD.
To Reproduce
Run Cppfront on this code:
main: () -> int = {
m: std::mutex = ();
_: std::scoped_lock = (m);
return 0;
}
It lowers to:
[[nodiscard]] auto main() -> int{
std::mutex m {};
std::scoped_lock auto_1 {std::move(m)};
return 0;
}
This results in a compilation error, e.g. with Clang:
main.cpp2:3:22: error: no viable constructor or deduction guide for deduction of template arguments of 'scoped_lock'
3 | std::scoped_lock auto_1 {std::move(m)};
|
(Similar errors with MSVC and GCC.)
See Godbolt
Neil Henderson commented
I found another example except this time it's not with CTAD:
main: () -> int = {
m: std::mutex = ();
_: std::unique_lock<std::mutex> = (m);
return 0;
}
(Skipping the lowering.)
GCC error:
unique_lock.h:66:16: note: conversion of argument 1 would be ill-formed:
<source>:5:51: error: cannot bind non-const lvalue reference of type 'std::unique_lock<std::mutex>::mutex_type&' {aka 'std::mutex&'} to an rvalue of type 'std::remove_reference<std::mutex&>::type' {aka 'std::mutex'}
5 | std::unique_lock<std::mutex> auto_1 (std::move(m));
| ~~~~~~~~~^~~
Herb Sutter commented
Thanks! See #1030, this should now be fixed in the above commit.
Both code examples above will now work.