Issue |
120668
|
Summary |
Semantics of `std::move` and `std::forward` changed in D123345 and now allow invalid code to compile
|
Labels |
|
Assignees |
|
Reporter |
graphitemaster
|
GCC and clang both treat `std::move` and `std::forward` specially in their frontend now as a result of
https://reviews.llvm.org/D123345
and (for GCC) https://gcc.gnu.org/bugzilla/attachment.cgi?id=51732
This change has now enabled `std::move` and `std::forward` to work on incomplete types when they wouldn't usually and allows invalid code to compile on both gcc and clang.
Consider this trivial example
```cpp
template<class T1, class T2> struct pair { T1 first; T2 second; };
template<class T> struct array {};
struct incomplete; // incomplete type
struct test {
test(test&& t) : data{std::move(t.data)} {} // This compiles but shouldn't
array<pair<int, incomplete>> data; // T1 is complete, T2 is incomplete
};
```
If you implement your own `std::move` as can be seen here
```cpp
template<typename T>
constexpr std::remove_reference_t<T>&& move(T&& t) noexcept {
return static_cast<std::remove_reference_t<T>&&>(t);
}
struct test {
test(test&& t) : data{move(t.data)} {}
array<pair<int, incomplete>> data;
};
```
When compiled this will produce the correct error
```
<source>: In instantiation of 'struct pair<int, incomplete>':
<source>:14:44: required from here
14 | test(test&& other) : data{move(other.data)} {}
| ^
<source>:3:26: error: 'pair<T1, T2>::second' has incomplete type
3 | struct pair { T1 first; T2 second; };
| ^~~~~~~~~
<source>:12:8: note: forward declaration of 'struct incomplete'
12 | struct incomplete;
| ^~~~~~~~~~
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs