-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
[clang] Fix behavior of __is_trivially_relocatable(volatile int)
#77092
[clang] Fix behavior of __is_trivially_relocatable(volatile int)
#77092
Conversation
@llvm/pr-subscribers-clang Author: Amirreza Ashouri (AMP999) ChangesConsistent with Fixes #77091 [clang] [test] New tests for __is_trivially_relocatable(cv-qualified type) Full diff: https://github.com/llvm/llvm-project/pull/77092.diff 2 Files Affected:
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 160a725939ccd4..96278370d9ff7e 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2651,6 +2651,8 @@ bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const {
return false;
} else if (!BaseElementType->isObjectType()) {
return false;
+ } else if (BaseElementType.isTriviallyCopyableType(Context)) {
+ return true;
} else if (const auto *RD = BaseElementType->getAsRecordDecl()) {
return RD->canPassInRegisters();
} else {
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index c5d196a2590f8d..36991fa2ca1dc8 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -3092,6 +3092,8 @@ namespace is_trivially_relocatable {
static_assert(!__is_trivially_relocatable(void), "");
static_assert(__is_trivially_relocatable(int), "");
static_assert(__is_trivially_relocatable(int[]), "");
+static_assert(__is_trivially_relocatable(const int), "");
+static_assert(__is_trivially_relocatable(volatile int), "");
enum Enum {};
static_assert(__is_trivially_relocatable(Enum), "");
@@ -3104,6 +3106,8 @@ static_assert(__is_trivially_relocatable(Union[]), "");
struct Trivial {};
static_assert(__is_trivially_relocatable(Trivial), "");
static_assert(__is_trivially_relocatable(Trivial[]), "");
+static_assert(__is_trivially_relocatable(const Trivial), "");
+static_assert(__is_trivially_relocatable(volatile Trivial), "");
struct Incomplete; // expected-note {{forward declaration of 'is_trivially_relocatable::Incomplete'}}
bool unused = __is_trivially_relocatable(Incomplete); // expected-error {{incomplete type}}
@@ -3113,6 +3117,8 @@ struct NontrivialDtor {
};
static_assert(!__is_trivially_relocatable(NontrivialDtor), "");
static_assert(!__is_trivially_relocatable(NontrivialDtor[]), "");
+static_assert(!__is_trivially_relocatable(const NontrivialDtor), "");
+static_assert(!__is_trivially_relocatable(volatile NontrivialDtor), "");
struct NontrivialCopyCtor {
NontrivialCopyCtor(const NontrivialCopyCtor&) {}
@@ -3131,12 +3137,16 @@ struct [[clang::trivial_abi]] TrivialAbiNontrivialDtor {
};
static_assert(__is_trivially_relocatable(TrivialAbiNontrivialDtor), "");
static_assert(__is_trivially_relocatable(TrivialAbiNontrivialDtor[]), "");
+static_assert(__is_trivially_relocatable(const TrivialAbiNontrivialDtor), "");
+static_assert(__is_trivially_relocatable(volatile TrivialAbiNontrivialDtor), "");
struct [[clang::trivial_abi]] TrivialAbiNontrivialCopyCtor {
TrivialAbiNontrivialCopyCtor(const TrivialAbiNontrivialCopyCtor&) {}
};
static_assert(__is_trivially_relocatable(TrivialAbiNontrivialCopyCtor), "");
static_assert(__is_trivially_relocatable(TrivialAbiNontrivialCopyCtor[]), "");
+static_assert(__is_trivially_relocatable(const TrivialAbiNontrivialCopyCtor), "");
+static_assert(__is_trivially_relocatable(volatile TrivialAbiNontrivialCopyCtor), "");
// A more complete set of tests for the behavior of trivial_abi can be found in
// clang/test/SemaCXX/attr-trivial-abi.cpp
@@ -3145,6 +3155,8 @@ struct [[clang::trivial_abi]] TrivialAbiNontrivialMoveCtor {
};
static_assert(__is_trivially_relocatable(TrivialAbiNontrivialMoveCtor), "");
static_assert(__is_trivially_relocatable(TrivialAbiNontrivialMoveCtor[]), "");
+static_assert(__is_trivially_relocatable(const TrivialAbiNontrivialMoveCtor), "");
+static_assert(__is_trivially_relocatable(volatile TrivialAbiNontrivialMoveCtor), "");
} // namespace is_trivially_relocatable
|
0562fd1
to
7f59014
Compare
We probably need a release note for that, don't we? |
Sure, I'll add a release note to Clang. |
e9339f0
to
fd01df8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I think I would like some more eyes on this, I don't know if it is obvious to me what it means to reallocate a volatile object. |
"Both active wg21.link/p1144 and wg21.link/p2786 proposals agree that if a type is trivially copyable then it is trivially relocatable; and that the trait ignores top-level cv-qualifiers. |
fd01df8
to
5d8204e
Compare
@@ -2669,6 +2669,8 @@ bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const { | |||
return false; | |||
} else if (const auto *RD = BaseElementType->getAsRecordDecl()) { | |||
return RD->canPassInRegisters(); | |||
} else if (BaseElementType.isTriviallyCopyableType(Context)) { | |||
return true; | |||
} else { | |||
switch (isNonTrivialToPrimitiveDestructiveMove()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why these are different functions, other than maybe having different preconditions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean why is isNonTrivialToPrimitiveDestructiveMove
different from isTriviallyRelocatable
? I don't know, but I think it has to do with Objective-C, so I left it alone.
@AaronBallman @erichkeane ping :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a good idea here... I don't really know what it means to 'relocate' a volatile.
This PR doesn't take a position on what it means to relocate a volatile; it just makes the type-trait return the correct value on cv-qualified types, for consistency with |
@AaronBallman, does this look okay to you? See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1144r9.html#abstract-opdef-trivially-relocatable and https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2786r3.pdf#subsection.12.4 which both agree on this point. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the changes make sense in as much as relocatable is supposed to be a subset of copyable (I continue to think volatile
-qualified objects should not be trivially copyable... because they aren't... but that's WG21's issue, not ours).
I'm adding in the libc++ reviewers because this trait is used by libc++ and there's a potential for this to be an ABI-breaking change. I hope we don't need to add any ABI tags for this, but I wanted to give them a chance to weigh in.
This isn't ABI breaking for us currently (at least in a non-benign way). We only use it to optimize |
Excellent, thank you for the confirmation! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Consistent with `__is_trivially_copyable(volatile int) == true` and `__is_trivially_relocatable(volatile Trivial) == true`, `__is_trivially_relocatable(volatile int)` should also be `true`. Fixes llvm#77091 [clang] [test] New tests for __is_trivially_relocatable(cv-qualified type)
5d8204e
to
ed94371
Compare
Thanks all for the review! @AaronBallman, Could you please land this patch for me? |
@AMP999 I wanted to merge this for you but there are merge conflicts. Can you resolve these? |
@mordante Thank you! I've resolved merge conflicts. I've also added an NFC commit to remove empty messages from |
clang/docs/ReleaseNotes.rst
Outdated
Fixes (`#64356 <https://github.com/llvm/llvm-project/issues/64356>`_). | ||
- ``__is_trivially_relocatable`` no longer returns ``true`` for non-object types | ||
such as references and functions, and no longer returns ``false`` for volatile-qualified types. | ||
Fixes (`#67498 <https://github.com/llvm/llvm-project/issues/67498>`_) and | ||
(`#77091 <https://github.com/llvm/llvm-project/issues/77091>`_) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should be moved after the next line (and you can use the same #GHXXXX
syntax )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's right! I've fixed it.
Consistent with
__is_trivially_copyable(volatile int) == true
and__is_trivially_relocatable(volatile Trivial) == true
,__is_trivially_relocatable(volatile int)
should also betrue
.Fixes #77091
[clang] [test] New tests for __is_trivially_relocatable(cv-qualified type)