[PATCH] Implement std::launder for C++17
Jonathan Wakely
jwakely@redhat.com
Fri Oct 28 14:09:00 GMT 2016
This implements std::launder, using Jakub's new __builtin_launder.
In order to allow our headers to be used with Clang (which doesn't
implement all our new built-ins yet) I've added a couple of checks
using Clang's __has_builtin.
My initial version of std::launder used
static_assert(!is_funcion_v<_Tp> && !is_void_v<_Tp>) which required
including <type_traits>, and that uses the new built-in
__has_unique_object_representations, so I guarded that too. In the end
I decided not to include <type_traits> in <new> and dealt with the
function and void cases using deleted overloads of std::launder
instead.
* doc/xml/manual/status_cxx2017.xml: Update status.
* doc/html/*: Regenerate.
* include/std/type_traits (has_unique_object_representations): Guard
with __has_builtin check.
* libsupc++/new (launder): Define for C++17.
* testsuite/18_support/launder/1.cc: New test.
* testsuite/18_support/launder/requirements.cc: New test.
* testsuite/18_support/launder/requirements_neg.cc: New test.
Tested powerpc64le-linux, committed to trunk.
-------------- next part --------------
commit 802f00ede1c4ade0bfa0d6f8a3f4d212296e75bd
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Oct 20 21:52:39 2016 +0100
Implement std::launder for C++17
* doc/xml/manual/status_cxx2017.xml: Update status.
* doc/html/*: Regenerate.
* include/std/type_traits (has_unique_object_representations): Guard
with __has_builtin check.
* libsupc++/new (launder): Define for C++17.
* testsuite/18_support/launder/1.cc: New test.
* testsuite/18_support/launder/requirements.cc: New test.
* testsuite/18_support/launder/requirements_neg.cc: New test.
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
index a1190bc..d008bd9e 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
@@ -69,14 +69,13 @@ Feature-testing recommendations for C++</link>.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Core Issue 1776: Replacement of class objects containing reference members</entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0137r1.html">
P0137R1
</link>
</entry>
- <entry align="center"> No </entry>
+ <entry align="center"> 7 </entry>
<entry> <code>__cpp_lib_launder >= 201606</code> </entry>
</row>
@@ -281,7 +280,7 @@ Feature-testing recommendations for C++</link>.
N4089
</link>
</entry>
- <entry align="center"> 5 ? </entry>
+ <entry align="center"> 6 </entry>
<entry/>
</row>
@@ -292,7 +291,7 @@ Feature-testing recommendations for C++</link>.
N4366
</link>
</entry>
- <entry align="center"> 5 ? </entry>
+ <entry align="center"> 6 </entry>
<entry/>
</row>
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index d402b5b..6824c9e 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3041,6 +3041,14 @@ template <typename _Base, typename _Derived>
template <typename _From, typename _To>
constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
+#ifdef __has_builtin
+# if !__has_builtin(__has_unique_object_representations)
+// Try not to break non-GNU compilers that don't support the built-in:
+# define _GLIBCXX_NO_BUILTIN_HAS_UNIQ_OBJ_REP 1
+# endif
+#endif
+
+#ifndef _GLIBCXX_NO_BUILTIN_HAS_UNIQ_OBJ_REP
# define __cpp_lib_has_unique_object_representations 201606
/// has_unique_object_representations
template<typename _Tp>
@@ -3049,6 +3057,8 @@ template <typename _From, typename _To>
remove_cv_t<remove_all_extents_t<_Tp>>
)>
{ };
+#endif
+#undef _GLIBCXX_NO_BUILTIN_HAS_UNIQ_OBJ_REP
#endif // C++17
diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new
index 477fadc..6bc6c00 100644
--- a/libstdc++-v3/libsupc++/new
+++ b/libstdc++-v3/libsupc++/new
@@ -176,6 +176,41 @@ inline void operator delete[](void*, void*) _GLIBCXX_USE_NOEXCEPT { }
//@}
} // extern "C++"
+#if __cplusplus > 201402L
+#ifdef __has_builtin
+# if !__has_builtin(__builtin_launder)
+// Try not to break non-GNU compilers that don't support the built-in:
+# define _GLIBCXX_NO_BUILTIN_LAUNDER 1
+# endif
+#endif
+
+#ifndef _GLIBCXX_NO_BUILTIN_LAUNDER
+namespace std
+{
+#define __cpp_lib_launder 201606
+ /// Pointer optimization barrier [ptr.launder]
+ template<typename _Tp>
+ constexpr _Tp*
+ launder(_Tp* __p) noexcept
+ { return __builtin_launder(__p); }
+
+ // The program is ill-formed if T is a function type or
+ // (possibly cv-qualified) void.
+
+ template<typename _Ret, typename... _Args>
+ void launder(_Ret (*)(_Args...)) = delete;
+ template<typename _Ret, typename... _Args>
+ void launder(_Ret (*)(_Args......)) = delete;
+
+ void launder(void*) = delete;
+ void launder(const void*) = delete;
+ void launder(volatile void*) = delete;
+ void launder(const volatile void*) = delete;
+}
+#endif // _GLIBCXX_NO_BUILTIN_LAUNDER
+#undef _GLIBCXX_NO_BUILTIN_LAUNDER
+#endif // C++17
+
#pragma GCC visibility pop
#endif
diff --git a/libstdc++-v3/testsuite/18_support/launder/1.cc b/libstdc++-v3/testsuite/18_support/launder/1.cc
new file mode 100644
index 0000000..51096a3
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/launder/1.cc
@@ -0,0 +1,56 @@
+// 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++17" }
+// { dg-do run { target c++1z } }
+
+#include <new>
+#include <testsuite_hooks.h>
+#include <testsuite_tr1.h>
+
+void
+test01()
+{
+ struct S {
+ int i;
+ } s;
+ auto p = std::launder( &s.i );
+ VERIFY( p == &s.i );
+}
+
+
+void
+test02()
+{
+ // C++1z 1.8 [intro.object]
+ struct X { const int n; };
+ union U { X x; float f; };
+
+ U u = {{ 1 }};
+ u.f = 5.f; // OK, creates new subobject of u (9.3)
+ X *p = new (&u.x) X {2}; // OK, creates new subobject of u
+ VERIFY(p->n == 2); // OK
+ VERIFY(*std::launder(&u.x.n) == 2); // OK
+ // assert(u.x.n == 2); undefined behavior, u.x does not name new subobject
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/18_support/launder/requirements.cc b/libstdc++-v3/testsuite/18_support/launder/requirements.cc
new file mode 100644
index 0000000..c1bf5ad
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/launder/requirements.cc
@@ -0,0 +1,27 @@
+// 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++17" }
+// { dg-do compile { target c++1z } }
+
+// NB: This file is for testing new with NO OTHER INCLUDES.
+#include <new>
+
+namespace std {
+ template <class T>
+ constexpr T* launder(T* p) noexcept;
+}
diff --git a/libstdc++-v3/testsuite/18_support/launder/requirements_neg.cc b/libstdc++-v3/testsuite/18_support/launder/requirements_neg.cc
new file mode 100644
index 0000000..87180ea
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/launder/requirements_neg.cc
@@ -0,0 +1,39 @@
+// 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++17" }
+// { dg-do compile { target c++1z } }
+
+#include <new>
+
+void f1(int) noexcept;
+int f2(const char*, ...);
+
+void
+test01()
+{
+ std::launder( &f1 ); // { dg-error "deleted function" }
+ std::launder( &f2 ); // { dg-error "deleted function" }
+ void* p = nullptr;
+ std::launder( p ); // { dg-error "deleted function" }
+ const void* cp = nullptr;
+ std::launder( cp ); // { dg-error "deleted function" }
+ volatile void* vp = nullptr;
+ std::launder( vp ); // { dg-error "deleted function" }
+ const volatile void* cvp = nullptr;
+ std::launder( cvp ); // { dg-error "deleted function" }
+}
More information about the Libstdc++
mailing list