Skip to content

[libc++][NFC] Use __construct_at and __destroy_at instead of using preprocessor conditionals #70866

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 26, 2023

Conversation

philnik777
Copy link
Contributor

No description provided.

@philnik777 philnik777 added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. code-cleanup labels Oct 31, 2023
@philnik777 philnik777 requested a review from a team as a code owner October 31, 2023 22:18
Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM % CI.

@philnik777 philnik777 force-pushed the use___construct_at branch 3 times, most recently from 3b8e283 to c0735fe Compare November 20, 2023 13:04
@@ -16,5 +16,5 @@

void f() {
std::vector<MoveOnly> v;
std::vector<MoveOnly> copy = v; // expected-error-re@* {{{{(no matching function for call to 'construct_at')|(call to implicitly-deleted copy constructor of 'MoveOnly')|(call to deleted constructor of 'MoveOnly')}}}}
std::vector<MoveOnly> copy = v; // expected-error-re@* {{{{(no matching function for call to '__construct_at')|(call to implicitly-deleted copy constructor of 'MoveOnly')}}}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unfortunate that __construct_at appears here, but I think that suggests we're testing too much of the compiler message.

A test should only fail when the behavior under test no longer holds. Is the name part of the behavior under test?

@@ -319,11 +315,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
__enable_if_t<!__has_destroy<allocator_type, _Tp*>::value> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
static void destroy(allocator_type&, _Tp* __p) {
#if _LIBCPP_STD_VER >= 20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is using destroy_at better than simply invoking the destructor? One costs a lot less to instantiate.
It's not a customization point, right?

@@ -300,11 +300,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
__enable_if_t<!__has_construct<allocator_type, _Tp*, _Args...>::value> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
static void construct(allocator_type&, _Tp* __p, _Args&&... __args) {
#if _LIBCPP_STD_VER >= 20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question as below.

Are we required to use construct_at here? If not, it seems to be more expensive, and causes arguably poorer diagnostic messages.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for constexpr-friendliness IIRC.

Copy link

github-actions bot commented Nov 23, 2023

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 6bdeb53ed9ad85fc16f495120b4e2382c4bdaafa 18e2a699569190d4c360090d310dd4be7b02b770 -- libcxx/include/__memory/allocator_traits.h libcxx/include/optional libcxx/test/std/containers/sequences/vector/vector.cons/copy.move_only.verify.cpp libcxx/test/std/containers/sequences/vector/vector.modifiers/resize_not_move_insertable.verify.cpp
View the diff from clang-format here.
diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index eea5ee973d..a2ce48b3fb 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -300,7 +300,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
         __enable_if_t<!__has_construct<allocator_type, _Tp*, _Args...>::value> >
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     static void construct(allocator_type&, _Tp* __p, _Args&&... __args) {
-        std::__construct_at(__p, std::forward<_Args>(__args)...);
+      std::__construct_at(__p, std::forward<_Args>(__args)...);
     }
 
     template <class _Tp, class =
@@ -315,7 +315,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
         __enable_if_t<!__has_destroy<allocator_type, _Tp*>::value> >
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     static void destroy(allocator_type&, _Tp* __p) {
-        std::__destroy_at(__p);
+      std::__destroy_at(__p);
     }
 
     template <class _Ap = _Alloc, class =
diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/copy.move_only.verify.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/copy.move_only.verify.cpp
index af8ca01370..1179fde3f1 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.cons/copy.move_only.verify.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.cons/copy.move_only.verify.cpp
@@ -16,5 +16,6 @@
 
 void f() {
     std::vector<MoveOnly> v;
-    std::vector<MoveOnly> copy = v; // expected-error-re@* {{{{(no matching function for call to '__construct_at')|(call to deleted constructor of 'MoveOnly')}}}}
+    std::vector<MoveOnly> copy =
+        v; // expected-error-re@* {{{{(no matching function for call to '__construct_at')|(call to deleted constructor of 'MoveOnly')}}}}
 }

@ldionne ldionne changed the title [libc++][NFC] Use __construct_at and __destroy_at insted of using preprocessor conditionals [libc++][NFC] Use __construct_at and __destroy_at instead of using preprocessor conditionals Nov 23, 2023
@ldionne
Copy link
Member

ldionne commented Nov 23, 2023

@EricWF This is essentially a small simplification of the code -- we have to use construct_at and destroy_at for constexpr-friendliness, and we also like to do it for consistency everywhere. So this really just trades #if for an unconditional call to something that does the right thing under the hood, so I'd go ahead with this change.

@philnik777 philnik777 merged commit cd9829c into llvm:main Nov 26, 2023
@philnik777 philnik777 deleted the use___construct_at branch November 26, 2023 19:47
@EricWF
Copy link
Member

EricWF commented Nov 27, 2023

What does "constexpr friendlyness" mean?
Is there magic in construct_at?

Because it's just placement new.

If this adds constexpr friendlyness then doesn't in need more tests?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code-cleanup libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants