Skip to content

Commit 30c92b1

Browse files
committed
Make sure __is_trivially_relocatable is false for polymorphic types
1 parent d982c6f commit 30c92b1

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
@@ -5322,15 +5322,21 @@ bool Sema::IsCXXReplaceableType(QualType Type) {
53225322
static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {
53235323
QualType BaseElementType = SemaRef.getASTContext().getBaseElementType(T);
53245324

5325-
if (SemaRef.IsCXXTriviallyRelocatableType(T))
5326-
return true;
5327-
5328-
if (BaseElementType->isIncompleteType() || !BaseElementType->isObjectType())
5325+
if (BaseElementType->isIncompleteType())
5326+
return false;
5327+
if (!BaseElementType->isObjectType())
53295328
return false;
53305329

5330+
if (const auto *RD = BaseElementType->getAsCXXRecordDecl();
5331+
RD && !RD->isPolymorphic() && IsCXXTriviallyRelocatableType(SemaRef, RD))
5332+
return true;
5333+
53315334
if (const auto *RD = BaseElementType->getAsRecordDecl())
53325335
return RD->canPassInRegisters();
53335336

5337+
if (BaseElementType.isTriviallyCopyableType(SemaRef.getASTContext()))
5338+
return true;
5339+
53345340
switch (T.isNonTrivialToPrimitiveDestructiveMove()) {
53355341
case QualType::PCK_Trivial:
53365342
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)