1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
3 void __attribute__((trivial_abi
)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
7 class __attribute__((trivial_abi
)) a
{ a(a
&&); };
9 // On Windows, to be trivial-for-calls, an object must be trivially copyable.
10 // (And it is only trivially relocatable, currently, if it is trivial for calls.)
11 // In this case, it is suppressed by an explicitly defined move constructor.
12 // Similar concerns apply to later tests that have #ifdef _WIN64.
13 static_assert(!__is_trivially_relocatable(a
<int>), "");
15 static_assert(__is_trivially_relocatable(a
<int>), "");
18 struct [[clang::trivial_abi
]] S0
{
21 static_assert(__is_trivially_relocatable(S0
), "");
23 struct __attribute__((trivial_abi
)) S1
{
26 static_assert(__is_trivially_relocatable(S1
), "");
28 struct __attribute__((trivial_abi
)) S3
{ // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}}
31 static_assert(!__is_trivially_relocatable(S3
), "");
35 } __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
), "");
38 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}}
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
), "");
48 static_assert(!__is_trivially_relocatable(S3_3
), "");
51 // Diagnose invalid trivial_abi even when the type is templated because it has a non-trivial field.
53 struct __attribute__((trivial_abi
)) S3_4
{ // expected-warning {{'trivial_abi' cannot be applied to 'S3_4'}} expected-note {{has a field of a non-trivial class type}}
57 static_assert(!__is_trivially_relocatable(S3_4
<int>), "");
62 static_assert(__is_trivially_relocatable(S4
), "");
64 struct __attribute__((trivial_abi
)) S5
: public virtual S4
{ // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}}
66 static_assert(!__is_trivially_relocatable(S5
), "");
68 struct __attribute__((trivial_abi
)) S9
: public S4
{
70 static_assert(__is_trivially_relocatable(S9
), "");
72 struct __attribute__((trivial_abi(1))) S8
{ // expected-error {{'trivial_abi' attribute takes no arguments}}
76 // Do not warn about deleted ctors when 'trivial_abi' is used to annotate a template class.
78 struct __attribute__((trivial_abi
)) S10
{
83 static_assert(__is_trivially_relocatable(S10
<int>), "");
84 static_assert(!__is_trivially_relocatable(S10
<S3
>), "");
92 struct __attribute__((trivial_abi
)) S15
: S14
<T
> {
96 static_assert(__is_trivially_relocatable(S15
<int>), "");
97 static_assert(!__is_trivially_relocatable(S15
<S3
>), "");
100 struct __attribute__((trivial_abi
)) S16
{
103 static_assert(__is_trivially_relocatable(S16
<int>), "");
104 static_assert(!__is_trivially_relocatable(S16
<S3
>), "");
109 struct __attribute__((trivial_abi
)) S17
{
113 static_assert(__is_trivially_relocatable(S17
<int>), "");
114 static_assert(__is_trivially_relocatable(S17
<S3
>), "");
116 namespace deletedCopyMoveConstructor
{
117 struct __attribute__((trivial_abi
)) CopyMoveDeleted
{ // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}}
118 CopyMoveDeleted(const CopyMoveDeleted
&) = delete;
119 CopyMoveDeleted(CopyMoveDeleted
&&) = delete;
122 static_assert(__is_trivially_relocatable(CopyMoveDeleted
), "");
124 static_assert(!__is_trivially_relocatable(CopyMoveDeleted
), "");
127 struct __attribute__((trivial_abi
)) S18
{ // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}}
131 static_assert(__is_trivially_relocatable(S18
), "");
133 static_assert(!__is_trivially_relocatable(S18
), "");
136 struct __attribute__((trivial_abi
)) CopyDeleted
{
137 CopyDeleted(const CopyDeleted
&) = delete;
138 CopyDeleted(CopyDeleted
&&) = default;
141 static_assert(!__is_trivially_relocatable(CopyDeleted
), "");
143 static_assert(__is_trivially_relocatable(CopyDeleted
), "");
146 struct __attribute__((trivial_abi
)) MoveDeleted
{
147 MoveDeleted(const MoveDeleted
&) = default;
148 MoveDeleted(MoveDeleted
&&) = delete;
150 static_assert(__is_trivially_relocatable(MoveDeleted
), "");
152 struct __attribute__((trivial_abi
)) S19
{ // expected-warning {{'trivial_abi' cannot be applied to 'S19'}} expected-note {{copy constructors and move constructors are all deleted}}
157 static_assert(__is_trivially_relocatable(S19
), "");
159 static_assert(!__is_trivially_relocatable(S19
), "");
162 // This is fine since the move constructor isn't deleted.
163 struct __attribute__((trivial_abi
)) S20
{
164 int &&a
; // a member of rvalue reference type deletes the copy constructor.
167 static_assert(!__is_trivially_relocatable(S20
), "");
169 static_assert(__is_trivially_relocatable(S20
), "");
171 } // namespace deletedCopyMoveConstructor