-
Notifications
You must be signed in to change notification settings - Fork 12.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc++] Extension: Make
move and forward constexpr in C++11.
Summary:
`std::move` and `std::forward` were not marked constexpr in C++11. This can be very damaging because it makes otherwise constant expressions non-constant. For example:
```
#include <utility>
template <class T>
struct Foo {
constexpr Foo(T&& tx) : t(std::move(tx)) {}
T t;
};
[[clang::require_constant_initialization]] Foo<int> f(42); // Foo should be constant initialized but C++11 move is not constexpr. As a result `f` is an unsafe global.
```
This patch applies `constexpr` to `move` and `forward` as an extension in C++11. Normally the library is not allowed to add `constexpr` because it may be observable to the user. In particular adding constexpr may cause valid code to stop compiling. However these problems only happen in more complex situations, like making `__invoke(...)` constexpr. `forward` and `move` are simply enough that applying `constexpr` is safe.
Note that libstdc++ has offered this extension since at least 4.8.1.
Most of the changes in this patch are simply test cleanups or additions. The main changes in the tests are:
* Fold all `forward_N.fail.cpp` tests into a single `forward.fail.cpp` test using -verify.
* Delete most `move_only_N.fail.cpp` tests because they weren't actually testing anything.
* Fold `move_copy.pass.cpp` and `move_only.pass.cpp` into a single `move.pass.cpp` test.
* Add return type and noexcept tests for `forward` and `move`.
Reviewers: rsmith, mclow.lists, EricWF
Subscribers: K-ballo, loladiro
Differential Revision: https://reviews.llvm.org/D24637
llvm-svn: 282439- Loading branch information
Showing
17 changed files
with
305 additions
and
481 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
libcxx/test/std/utilities/utility/forward/forward.fail.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is dual licensed under the MIT and the University of Illinois Open | ||
| // Source Licenses. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| // test forward | ||
|
|
||
| #include <utility> | ||
|
|
||
| #include "test_macros.h" | ||
|
|
||
| struct A | ||
| { | ||
| }; | ||
|
|
||
| A source() {return A();} | ||
| const A csource() {return A();} | ||
|
|
||
| int main() | ||
| { | ||
| #if TEST_STD_VER >= 11 | ||
| { | ||
| std::forward<A&>(source()); // expected-note {{requested here}} | ||
| // expected-error@type_traits:* 1 {{static_assert failed "can not forward an rvalue as an lvalue"}} | ||
| } | ||
| #else | ||
| { | ||
| std::forward<A&>(source()); // expected-error {{no matching function for call to 'forward'}} | ||
| } | ||
| #endif | ||
| { | ||
| const A ca = A(); | ||
| std::forward<A&>(ca); // expected-error {{no matching function for call to 'forward'}} | ||
| } | ||
| { | ||
| std::forward<A&>(csource()); // expected-error {{no matching function for call to 'forward'}} | ||
| } | ||
| { | ||
| const A ca = A(); | ||
| std::forward<A>(ca); // expected-error {{no matching function for call to 'forward'}} | ||
| } | ||
| { | ||
| std::forward<A>(csource()); // expected-error {{no matching function for call to 'forward'}} | ||
| } | ||
| { | ||
| A a; | ||
| std::forward(a); // expected-error {{no matching function for call to 'forward'}} | ||
| } | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 0 additions & 24 deletions
24
libcxx/test/std/utilities/utility/forward/forward1.fail.cpp
This file was deleted.
Oops, something went wrong.
25 changes: 0 additions & 25 deletions
25
libcxx/test/std/utilities/utility/forward/forward2.fail.cpp
This file was deleted.
Oops, something went wrong.
24 changes: 0 additions & 24 deletions
24
libcxx/test/std/utilities/utility/forward/forward3.fail.cpp
This file was deleted.
Oops, something went wrong.
25 changes: 0 additions & 25 deletions
25
libcxx/test/std/utilities/utility/forward/forward4.fail.cpp
This file was deleted.
Oops, something went wrong.
25 changes: 0 additions & 25 deletions
25
libcxx/test/std/utilities/utility/forward/forward5.fail.cpp
This file was deleted.
Oops, something went wrong.
22 changes: 0 additions & 22 deletions
22
libcxx/test/std/utilities/utility/forward/forward6.fail.cpp
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.