1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 2 3 void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}} 4 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 17 18 struct [[clang::trivial_abi]] S0 { 19 int a; 20 }; 21 static_assert(__is_trivially_relocatable(S0), ""); 22 23 struct __attribute__((trivial_abi)) S1 { 24 int a; 25 }; 26 static_assert(__is_trivially_relocatable(S1), ""); 27 28 struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}} 29 virtual void m(); 30 }; 31 static_assert(!__is_trivially_relocatable(S3), ""); 32 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), ""); 37 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; 41 }; 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 50 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; 56 }; 57 static_assert(!__is_trivially_relocatable(S3_4<int>), ""); 58 59 struct S4 { 60 int a; 61 }; 62 static_assert(__is_trivially_relocatable(S4), ""); 63 64 struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}} 65 }; 66 static_assert(!__is_trivially_relocatable(S5), ""); 67 68 struct __attribute__((trivial_abi)) S9 : public S4 { 69 }; 70 static_assert(__is_trivially_relocatable(S9), ""); 71 72 struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}} 73 int a; 74 }; 75 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; 80 }; 81 82 S10<int *> p1; 83 static_assert(__is_trivially_relocatable(S10<int>), ""); 84 static_assert(!__is_trivially_relocatable(S10<S3>), ""); 85 86 template <class T> 87 struct S14 { 88 T a; 89 }; 90 91 template <class T> 92 struct __attribute__((trivial_abi)) S15 : S14<T> { 93 }; 94 95 S15<int> s15; 96 static_assert(__is_trivially_relocatable(S15<int>), ""); 97 static_assert(!__is_trivially_relocatable(S15<S3>), ""); 98 99 template <class T> 100 struct __attribute__((trivial_abi)) S16 { 101 S14<T> a; 102 }; 103 static_assert(__is_trivially_relocatable(S16<int>), ""); 104 static_assert(!__is_trivially_relocatable(S16<S3>), ""); 105 106 S16<int> s16; 107 108 template <class T> 109 struct __attribute__((trivial_abi)) S17 { 110 }; 111 112 S17<int> s17; 113 static_assert(__is_trivially_relocatable(S17<int>), ""); 114 static_assert(__is_trivially_relocatable(S17<S3>), ""); 115 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; 120 }; 121 #ifdef __ORBIS__ 122 static_assert(__is_trivially_relocatable(CopyMoveDeleted), ""); 123 #else 124 static_assert(!__is_trivially_relocatable(CopyMoveDeleted), ""); 125 #endif 126 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; 129 }; 130 #ifdef __ORBIS__ 131 static_assert(__is_trivially_relocatable(S18), ""); 132 #else 133 static_assert(!__is_trivially_relocatable(S18), ""); 134 #endif 135 136 struct __attribute__((trivial_abi)) CopyDeleted { 137 CopyDeleted(const CopyDeleted &) = delete; 138 CopyDeleted(CopyDeleted &&) = default; 139 }; 140 #if defined(_WIN64) && !defined(__MINGW32__) 141 static_assert(!__is_trivially_relocatable(CopyDeleted), ""); 142 #else 143 static_assert(__is_trivially_relocatable(CopyDeleted), ""); 144 #endif 145 146 struct __attribute__((trivial_abi)) MoveDeleted { 147 MoveDeleted(const MoveDeleted &) = default; 148 MoveDeleted(MoveDeleted &&) = delete; 149 }; 150 static_assert(__is_trivially_relocatable(MoveDeleted), ""); 151 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; 155 }; 156 #ifdef __ORBIS__ 157 static_assert(__is_trivially_relocatable(S19), ""); 158 #else 159 static_assert(!__is_trivially_relocatable(S19), ""); 160 #endif 161 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. 165 }; 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 172