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

Reply via email to