Skip to content

Commit 0f1aa03

Browse files
committed
Make sure __is_trivially_relocatable is false for polymorphic types
1 parent a473deb commit 0f1aa03

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5649,15 +5649,21 @@ bool Sema::IsCXXReplaceableType(QualType Type) {
56495649
static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {
56505650
QualType BaseElementType = SemaRef.getASTContext().getBaseElementType(T);
56515651

5652-
if (SemaRef.IsCXXTriviallyRelocatableType(T))
5653-
return true;
5654-
5655-
if (BaseElementType->isIncompleteType() || !BaseElementType->isObjectType())
5652+
if (BaseElementType->isIncompleteType())
5653+
return false;
5654+
if (!BaseElementType->isObjectType())
56565655
return false;
56575656

5657+
if (const auto *RD = BaseElementType->getAsCXXRecordDecl();
5658+
RD && !RD->isPolymorphic() && IsCXXTriviallyRelocatableType(SemaRef, RD))
5659+
return true;
5660+
56585661
if (const auto *RD = BaseElementType->getAsRecordDecl())
56595662
return RD->canPassInRegisters();
56605663

5664+
if (BaseElementType.isTriviallyCopyableType(SemaRef.getASTContext()))
5665+
return true;
5666+
56615667
switch (T.isNonTrivialToPrimitiveDestructiveMove()) {
56625668
case QualType::PCK_Trivial:
56635669
return !T.isDestructedType();

clang/test/SemaCXX/attr-trivial-abi.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,25 @@ static_assert(__is_trivially_relocatable(S1), "");
2828
struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}}
2929
virtual void m();
3030
};
31-
static_assert(__is_trivially_relocatable(S3), "");
31+
static_assert(!__is_trivially_relocatable(S3), "");
3232

3333
struct S3_2 {
3434
virtual void m();
3535
} __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}}
36-
static_assert(__is_trivially_relocatable(S3_2), "");
36+
static_assert(!__is_trivially_relocatable(S3_2), "");
3737

3838
struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_3'}} expected-note {{has a field of a non-trivial class type}}
3939
S3_3(S3_3 &&);
4040
S3_2 s32;
4141
};
42+
#ifdef __ORBIS__
43+
// The ClangABI4OrPS4 calling convention kind passes classes in registers if the
44+
// copy constructor is trivial for calls *or deleted*, while other platforms do
45+
// not accept deleted constructors.
46+
static_assert(__is_trivially_relocatable(S3_3), "");
47+
#else
4248
static_assert(!__is_trivially_relocatable(S3_3), "");
49+
#endif
4350

4451
// Diagnose invalid trivial_abi even when the type is templated because it has a non-trivial field.
4552
template <class T>
@@ -111,7 +118,11 @@ struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'tri
111118
CopyMoveDeleted(const CopyMoveDeleted &) = delete;
112119
CopyMoveDeleted(CopyMoveDeleted &&) = delete;
113120
};
121+
#ifdef __ORBIS__
122+
static_assert(__is_trivially_relocatable(CopyMoveDeleted), "");
123+
#else
114124
static_assert(!__is_trivially_relocatable(CopyMoveDeleted), "");
125+
#endif
115126

116127
struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}}
117128
CopyMoveDeleted a;

0 commit comments

Comments
 (0)