Implement constexpr std::addressof for C++17
authorJonathan Wakely <jwakely@redhat.com>
Mon, 10 Oct 2016 15:34:28 +0000 (16:34 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 10 Oct 2016 15:34:28 +0000 (16:34 +0100)
* doc/xml/manual/intro.xml: Document DR 2296 status.
* doc/xml/manual/status_cxx2017.xml: Update status.
* include/bits/move.h (__addressof): Add _GLIBCXX_CONSTEXPR and
call __builtin_addressof.
(addressof): Add _GLIBCXX17_CONSTEXPR.
* testsuite/20_util/addressof/requirements/constexpr.cc: New test.
* testsuite/20_util/forward/c_neg.cc: Adjust dg-error lineno.
* testsuite/20_util/forward/f_neg.cc: Likewise.

From-SVN: r240929

libstdc++-v3/ChangeLog
libstdc++-v3/doc/xml/manual/intro.xml
libstdc++-v3/doc/xml/manual/status_cxx2017.xml
libstdc++-v3/include/bits/move.h
libstdc++-v3/testsuite/20_util/addressof/requirements/constexpr.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/forward/c_neg.cc
libstdc++-v3/testsuite/20_util/forward/f_neg.cc

index d1e2bc37523349d0f1587a9e530850b6eca05e7a..34b7d05f3b469495cf6402ff44a2a6e9a6ba2e71 100644 (file)
@@ -1,5 +1,14 @@
 2016-10-10  Jonathan Wakely  <jwakely@redhat.com>
 
+       * doc/xml/manual/intro.xml: Document DR 2296 status.
+       * doc/xml/manual/status_cxx2017.xml: Update status.
+       * include/bits/move.h (__addressof): Add _GLIBCXX_CONSTEXPR and
+       call __builtin_addressof.
+       (addressof): Add _GLIBCXX17_CONSTEXPR.
+       * testsuite/20_util/addressof/requirements/constexpr.cc: New test.
+       * testsuite/20_util/forward/c_neg.cc: Adjust dg-error lineno.
+       * testsuite/20_util/forward/f_neg.cc: Likewise.
+
        * include/bits/allocator.h (allocator<T>::is_always_equal): Define.
        * testsuite/20_util/allocator/requirements/typedefs.cc: Test for
        is_always_equal.
index 47478513666c05a9be17635e4e5c97ebf7e499a7..265ef67aaaee0aee2e1c2d4a3f48a7733bbe0ef6 100644 (file)
@@ -961,6 +961,13 @@ requirements of the license of GCC.
     is included by <code>&lt;array&gt;</code>.
     </para></listitem></varlistentry>
 
+    <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2296">2296</link>:
+       <emphasis><code>std::addressof</code> should be constexpr</emphasis>
+    </term>
+    <listitem><para>Use <code>__builtin_addressof</code> and add
+    <code>constexpr</code> to <code>addressof</code> for C++17 and later.
+    </para></listitem></varlistentry>
+
     <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2313">2313</link>:
        <emphasis><code>tuple_size</code> should always derive from <code>integral_constant&lt;size_t, N&gt;</code></emphasis>
     </term>
index c03978e5e1fcfbb89e7f983fcceafdef761ba795..c6b84409f68277fa73b6d25d00d96afb5c39b464 100644 (file)
@@ -253,14 +253,13 @@ Feature-testing recommendations for C++</link>.
     </row>
 
     <row>
-      <?dbhtml bgcolor="#C8B0B0" ?>
       <entry> <code>std::addressof</code> should be constexpr </entry>
       <entry>
        <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0304r0.html#2296">
        LWG2296
        </link>
       </entry>
-      <entry align="center"> No </entry>
+      <entry align="center"> 7 </entry>
       <entry><code> __cpp_lib_addressof_constexpr >= 201603 </code></entry>
     </row>
 
index 9deec427e24e3045c33fb1a639d6804768ba0ee9..a5002fca422cf7cb8ae94d1a913666cf8b1d9aee 100644 (file)
@@ -43,12 +43,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *  @ingroup utilities
    */
   template<typename _Tp>
-    inline _Tp*
+    inline _GLIBCXX_CONSTEXPR _Tp*
     __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
-    {
-      return reinterpret_cast<_Tp*>
-       (&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
-    }
+    { return __builtin_addressof(__r); }
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
@@ -123,6 +120,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // declval, from type_traits.
 
+#if __cplusplus > 201402L
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2296. std::addressof should be constexpr
+# define __cpp_lib_addressof_constexpr 201603
+#endif
   /**
    *  @brief Returns the actual address of the object or function
    *         referenced by r, even in the presence of an overloaded
@@ -131,7 +133,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *  @return   The actual address.
   */
   template<typename _Tp>
-    inline _Tp*
+    inline _GLIBCXX17_CONSTEXPR _Tp*
     addressof(_Tp& __r) noexcept
     { return std::__addressof(__r); }
 
diff --git a/libstdc++-v3/testsuite/20_util/addressof/requirements/constexpr.cc b/libstdc++-v3/testsuite/20_util/addressof/requirements/constexpr.cc
new file mode 100644 (file)
index 0000000..998d087
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++1z" }
+// { dg-do compile { target c++1z } }
+
+#include <utility>
+
+// LWG 2296 std::addressof should be constexpr
+
+#ifndef __cpp_lib_addressof_constexpr
+# error "Feature-test macro for constexpr addressof missing"
+#elif __cpp_lib_addressof_constexpr != 201603
+# error "Feature-test macro for constexpr addressof has wrong value"
+#endif
+
+int i;
+constexpr int* pi = std::addressof(i);
+static_assert( pi == &i, "&i" );
+
+struct X {
+  void operator&();
+  constexpr X* addr() { return this; }
+  constexpr const X* addr() const { return this; }
+};
+X x;
+constexpr X* px = std::addressof(x);
+static_assert( px == x.addr(), "x.addr()" );
+const X cx;
+constexpr const X* pcx = std::addressof(cx);
+static_assert( pcx == cx.addr(), "cx.addr()" );
+
+void
+test01()
+{
+  static int i2;
+  static_assert( std::addressof(i2) == &i2, "&i2" );
+
+  static X x2;
+  static_assert( std::addressof(x2) == x2.addr(), "x2.addr()" );
+}
index 0b23625e47ca1e8a16319f0f1d7868c18f21b03a..784e23c31e77f3dd6c6fd77f04edee013fb35739 100644 (file)
@@ -17,7 +17,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-error "static assertion failed" "" { target *-*-* } 89 }
+// { dg-error "static assertion failed" "" { target *-*-* } 86 }
 
 #include <list>
 
index 9796ef4399bcf2baf552310066fd3e3c063a97f3..3f4c175bc6b69f25d5893d15b986b9b6f702b7f6 100644 (file)
@@ -17,7 +17,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-error "static assertion failed" "" { target *-*-* } 89 }
+// { dg-error "static assertion failed" "" { target *-*-* } 86 }
 
 #include <utility>