[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / attr-trivial-abi.cpp
blobc215f90eb124ce404f7316e55dad45060c9af40d
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}}
5 // Should not crash.
6 template <class>
7 class __attribute__((trivial_abi)) a { a(a &&); };
8 #if defined(_WIN64) && !defined(__MINGW32__)
9 // On Windows/MSVC, 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 #if defined(_WIN64) && !defined(__MINGW32__)
13 static_assert(!__is_trivially_relocatable(a<int>), "");
14 #else
15 static_assert(__is_trivially_relocatable(a<int>), "");
16 #endif
18 struct [[clang::trivial_abi]] S0 {
19 int a;
21 static_assert(__is_trivially_relocatable(S0), "");
23 struct __attribute__((trivial_abi)) S1 {
24 int a;
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}}
29 virtual void m();
31 static_assert(!__is_trivially_relocatable(S3), "");
33 struct S3_2 {
34 virtual void m();
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}}
39 S3_3(S3_3 &&);
40 S3_2 s32;
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
48 static_assert(!__is_trivially_relocatable(S3_3), "");
49 #endif
51 // Diagnose invalid trivial_abi even when the type is templated because it has a non-trivial field.
52 template <class T>
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}}
54 S3_4(S3_4 &&);
55 S3_2 s32;
57 static_assert(!__is_trivially_relocatable(S3_4<int>), "");
59 struct S4 {
60 int a;
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}}
73 int a;
76 // Do not warn about deleted ctors when 'trivial_abi' is used to annotate a template class.
77 template <class T>
78 struct __attribute__((trivial_abi)) S10 {
79 T p;
82 S10<int *> p1;
83 static_assert(__is_trivially_relocatable(S10<int>), "");
84 static_assert(!__is_trivially_relocatable(S10<S3>), "");
86 template <class T>
87 struct S14 {
88 T a;
91 template <class T>
92 struct __attribute__((trivial_abi)) S15 : S14<T> {
95 S15<int> s15;
96 static_assert(__is_trivially_relocatable(S15<int>), "");
97 static_assert(!__is_trivially_relocatable(S15<S3>), "");
99 template <class T>
100 struct __attribute__((trivial_abi)) S16 {
101 S14<T> a;
103 static_assert(__is_trivially_relocatable(S16<int>), "");
104 static_assert(!__is_trivially_relocatable(S16<S3>), "");
106 S16<int> s16;
108 template <class T>
109 struct __attribute__((trivial_abi)) S17 {
112 S17<int> 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;
121 #ifdef __ORBIS__
122 static_assert(__is_trivially_relocatable(CopyMoveDeleted), "");
123 #else
124 static_assert(!__is_trivially_relocatable(CopyMoveDeleted), "");
125 #endif
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}}
128 CopyMoveDeleted a;
130 #ifdef __ORBIS__
131 static_assert(__is_trivially_relocatable(S18), "");
132 #else
133 static_assert(!__is_trivially_relocatable(S18), "");
134 #endif
136 struct __attribute__((trivial_abi)) CopyDeleted {
137 CopyDeleted(const CopyDeleted &) = delete;
138 CopyDeleted(CopyDeleted &&) = default;
140 #if defined(_WIN64) && !defined(__MINGW32__)
141 static_assert(!__is_trivially_relocatable(CopyDeleted), "");
142 #else
143 static_assert(__is_trivially_relocatable(CopyDeleted), "");
144 #endif
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}}
153 CopyDeleted a;
154 MoveDeleted b;
156 #ifdef __ORBIS__
157 static_assert(__is_trivially_relocatable(S19), "");
158 #else
159 static_assert(!__is_trivially_relocatable(S19), "");
160 #endif
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.
166 #if defined(_WIN64) && !defined(__MINGW32__)
167 static_assert(!__is_trivially_relocatable(S20), "");
168 #else
169 static_assert(__is_trivially_relocatable(S20), "");
170 #endif
171 } // namespace deletedCopyMoveConstructor