[libc++] Extension: Make `move` and `forward` constexpr in C++11.


[libc++] Extension: Make move and forward constexpr in C++11.

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


EricWFSep 26 2016, 1:55 PM
Differential Revision
D24637: [libc++] Extension: Make `move` and `forward` constexpr in C++11.
rL282438: Fix test on windows