From c0cde79e9e3b3c5bb54c55b0eabe8142674028a4 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Mon, 6 Mar 2023 15:43:26 -0500 Subject: [PATCH] [libc++] Remove C++03 extensions for std::allocator_arg & friends As explained in the release note, libc++ used to provide various global variables as an extension in C++03 mode. Unfortunately, that made our definition non-conforming in all standard modes. This was never a big problem until recently, since we are trying to support C++20 Modules in libc++, and that requires cleaning up the definition of these variables. This change is the first in a series of changes to achieve our end goal. This patch removes the ability for users to rely on the (incorrect) definition of those global variables inside the shared library. The plan is to then remove those definitions from the shared library (which is an ABI break but I don't think it will have impact), and finally to make our definition of those variables conforming in all standard modes. Differential Revision: https://reviews.llvm.org/D145422 --- libcxx/docs/ReleaseNotes.rst | 9 +++++++++ libcxx/include/__memory/allocator_arg_t.h | 4 ++-- libcxx/include/__mutex_base | 18 +++++++----------- libcxx/include/__utility/piecewise_construct.h | 7 ++++--- libcxx/include/condition_variable | 4 ++-- libcxx/include/experimental/__memory | 2 +- libcxx/include/future | 8 ++++---- libcxx/include/mutex | 2 +- .../thread_safety_annotations_not_enabled.pass.cpp | 1 + .../thread.lock/thread.lock.guard/adopt_lock.pass.cpp | 1 + .../thread.lock.unique.cons/mutex_adopt_lock.pass.cpp | 1 + .../thread.lock.unique.cons/mutex_defer_lock.pass.cpp | 1 + .../thread.lock.unique.cons/mutex_try_to_lock.pass.cpp | 1 + .../thread.lock.unique.locking/lock.pass.cpp | 1 + .../thread.lock.unique.locking/try_lock.pass.cpp | 2 +- .../thread.lock.unique.locking/try_lock_for.pass.cpp | 1 + .../thread.lock.unique.locking/try_lock_until.pass.cpp | 1 + .../std/thread/thread.mutex/thread.lock/types.pass.cpp | 1 + .../memory/allocator.tag/allocator_arg.pass.cpp | 2 ++ 19 files changed, 42 insertions(+), 25 deletions(-) diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst index 386ecc9..aa14e6b 100644 --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -73,6 +73,15 @@ Deprecations and Removals from the Standard since it was never used, the proper specialization to use instead is ``template struct formatter``. +- Libc++ used to provide some C++11 tag type global variables in C++03 as an extension, which are removed in + this release. Those variables were ``std::allocator_arg``, ``std::defer_lock``, ``std::try_to_lock``, + ``std::adopt_lock``, and ``std::piecewise_construct``. Note that the types associated to those variables are + still provided in C++03 as an extension (e.g. ``std::piecewise_construct_t``). Providing those variables in + C++03 mode made it impossible to define them properly -- C++11 mandated that they be ``constexpr`` variables, + which is impossible in C++03 mode. Furthermore, C++17 mandated that they be ``inline constexpr`` variables, + which led to ODR violations when mixed with the C++03 definition. Cleaning this up is required for libc++ to + make progress on support for C++20 modules. + Upcoming Deprecations and Removals ---------------------------------- diff --git a/libcxx/include/__memory/allocator_arg_t.h b/libcxx/include/__memory/allocator_arg_t.h index 15f8c98..9e2d8c6 100644 --- a/libcxx/include/__memory/allocator_arg_t.h +++ b/libcxx/include/__memory/allocator_arg_t.h @@ -25,9 +25,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; }; -#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) +#if defined(_LIBCPP_BUILDING_LIBRARY) extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg; -#else +#elif !defined(_LIBCPP_CXX03_LANG) /* inline */ constexpr allocator_arg_t allocator_arg = allocator_arg_t(); #endif diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base index 80621c8..1919553 100644 --- a/libcxx/include/__mutex_base +++ b/libcxx/include/__mutex_base @@ -66,19 +66,15 @@ struct _LIBCPP_TYPE_VIS defer_lock_t { explicit defer_lock_t() = default; }; struct _LIBCPP_TYPE_VIS try_to_lock_t { explicit try_to_lock_t() = default; }; struct _LIBCPP_TYPE_VIS adopt_lock_t { explicit adopt_lock_t() = default; }; -#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) - -extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock; +# if defined(_LIBCPP_BUILDING_LIBRARY) +extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock; extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock; -extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock; - -#else - -/* inline */ constexpr defer_lock_t defer_lock = defer_lock_t(); +extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock; +# elif !defined(_LIBCPP_CXX03_LANG) +/* inline */ constexpr defer_lock_t defer_lock = defer_lock_t(); /* inline */ constexpr try_to_lock_t try_to_lock = try_to_lock_t(); -/* inline */ constexpr adopt_lock_t adopt_lock = adopt_lock_t(); - -#endif +/* inline */ constexpr adopt_lock_t adopt_lock = adopt_lock_t(); +# endif template class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) diff --git a/libcxx/include/__utility/piecewise_construct.h b/libcxx/include/__utility/piecewise_construct.h index 3cc86fe..071e207b 100644 --- a/libcxx/include/__utility/piecewise_construct.h +++ b/libcxx/include/__utility/piecewise_construct.h @@ -18,9 +18,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; }; -#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) -extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t(); -#else + +#if defined(_LIBCPP_BUILDING_LIBRARY) +extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct; +#elif !defined(_LIBCPP_CXX03_LANG) /* inline */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); #endif diff --git a/libcxx/include/condition_variable b/libcxx/include/condition_variable index 85050dd..bb7b13c 100644 --- a/libcxx/include/condition_variable +++ b/libcxx/include/condition_variable @@ -202,7 +202,7 @@ condition_variable_any::wait(_Lock& __lock) unique_lock __lk(*__mut); __lock.unlock(); unique_ptr<_Lock, __lock_external> __lxx(&__lock); - lock_guard > __lx(__lk, adopt_lock); + lock_guard > __lx(__lk, adopt_lock_t()); __cv_.wait(__lk); } // __mut_.unlock(), __lock.lock() @@ -224,7 +224,7 @@ condition_variable_any::wait_until(_Lock& __lock, unique_lock __lk(*__mut); __lock.unlock(); unique_ptr<_Lock, __lock_external> __lxx(&__lock); - lock_guard > __lx(__lk, adopt_lock); + lock_guard > __lx(__lk, adopt_lock_t()); return __cv_.wait_until(__lk, __t); } // __mut_.unlock(), __lock.lock() diff --git a/libcxx/include/experimental/__memory b/libcxx/include/experimental/__memory index d7b031d..b1136963 100644 --- a/libcxx/include/experimental/__memory +++ b/libcxx/include/experimental/__memory @@ -93,7 +93,7 @@ template inline _LIBCPP_INLINE_VISIBILITY void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) { - new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); + new (__storage) _Tp (allocator_arg_t(), __a, _VSTD::forward<_Args>(__args)...); } // FIXME: This should have a version which takes a non-const alloc. diff --git a/libcxx/include/future b/libcxx/include/future index cc7d1f9..6f1eeff 100644 --- a/libcxx/include/future +++ b/libcxx/include/future @@ -1906,8 +1906,8 @@ public: class = __enable_if_t, packaged_task>::value> > _LIBCPP_INLINE_VISIBILITY packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) - : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), - __p_(allocator_arg, __a) {} + : __f_(allocator_arg_t(), __a, _VSTD::forward<_Fp>(__f)), + __p_(allocator_arg_t(), __a) {} // ~packaged_task() = default; // no copy @@ -2021,8 +2021,8 @@ public: class = __enable_if_t, packaged_task>::value> > _LIBCPP_INLINE_VISIBILITY packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) - : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), - __p_(allocator_arg, __a) {} + : __f_(allocator_arg_t(), __a, _VSTD::forward<_Fp>(__f)), + __p_(allocator_arg_t(), __a) {} // ~packaged_task() = default; // no copy diff --git a/libcxx/include/mutex b/libcxx/include/mutex index 54104d5..9d24768 100644 --- a/libcxx/include/mutex +++ b/libcxx/include/mutex @@ -328,7 +328,7 @@ template _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) { - unique_lock<_L0> __u0(__l0, try_to_lock); + unique_lock<_L0> __u0(__l0, try_to_lock_t()); if (__u0.owns_lock()) { if (__l1.try_lock()) diff --git a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp index 02072f5..5d40fa7 100644 --- a/libcxx/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: no-threads +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp index cb105f2..4d11674 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: no-threads +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp index b2e8065..4adbe26 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: no-threads +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp index fa00da6..06ef204 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: no-threads +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp index 39d3bde..f4f344e 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: no-threads +// UNSUPPORTED: c++03 // ALLOW_RETRIES: 2 // diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp index b1b5af0..fa43f5d 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: no-threads +// UNSUPPORTED: c++03 // ALLOW_RETRIES: 2 // diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp index 83e1d7e..9249959 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: no-threads -// +// UNSUPPORTED: c++03 // ALLOW_RETRIES: 2 // diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp index 1a0fba6..fe29d16 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: no-threads +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp index 3f6f213..a1e8553 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: no-threads +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/types.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/types.pass.cpp index 2776e00..bb4e9b4 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/types.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/types.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: no-threads +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/utilities/memory/allocator.tag/allocator_arg.pass.cpp b/libcxx/test/std/utilities/memory/allocator.tag/allocator_arg.pass.cpp index e22bec1..c117744 100644 --- a/libcxx/test/std/utilities/memory/allocator.tag/allocator_arg.pass.cpp +++ b/libcxx/test/std/utilities/memory/allocator.tag/allocator_arg.pass.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03 + // // struct allocator_arg_t { explicit allocator_arg_t() = default; }; -- 2.7.4