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 9 struct [[clang::trivial_abi]] S0 { 10 int a; 11 }; 12 13 struct __attribute__((trivial_abi)) S1 { 14 int a; 15 }; 16 17 struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}} 18 virtual void m(); 19 }; 20 21 struct S3_2 { 22 virtual void m(); 23 } __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}} 24 25 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}} 26 S3_3(S3_3 &&); 27 S3_2 s32; 28 }; 29 30 // Diagnose invalid trivial_abi even when the type is templated because it has a non-trivial field. 31 template <class T> 32 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}} 33 S3_4(S3_4 &&); 34 S3_2 s32; 35 }; 36 37 struct S4 { 38 int a; 39 }; 40 41 struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}} 42 }; 43 44 struct __attribute__((trivial_abi)) S9 : public S4 { 45 }; 46 47 struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}} 48 int a; 49 }; 50 51 // Do not warn about deleted ctors when 'trivial_abi' is used to annotate a template class. 52 template <class T> 53 struct __attribute__((trivial_abi)) S10 { 54 T p; 55 }; 56 57 S10<int *> p1; 58 59 template <class T> 60 struct S14 { 61 T a; 62 }; 63 64 template <class T> 65 struct __attribute__((trivial_abi)) S15 : S14<T> { 66 }; 67 68 S15<int> s15; 69 70 template <class T> 71 struct __attribute__((trivial_abi)) S16 { 72 S14<T> a; 73 }; 74 75 S16<int> s16; 76 77 template <class T> 78 struct __attribute__((trivial_abi)) S17 { 79 }; 80 81 S17<int> s17; 82 83 namespace deletedCopyMoveConstructor { 84 struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}} 85 CopyMoveDeleted(const CopyMoveDeleted &) = delete; 86 CopyMoveDeleted(CopyMoveDeleted &&) = delete; 87 }; 88 89 struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}} 90 CopyMoveDeleted a; 91 }; 92 93 struct __attribute__((trivial_abi)) CopyDeleted { 94 CopyDeleted(const CopyDeleted &) = delete; 95 CopyDeleted(CopyDeleted &&) = default; 96 }; 97 98 struct __attribute__((trivial_abi)) MoveDeleted { 99 MoveDeleted(const MoveDeleted &) = default; 100 MoveDeleted(MoveDeleted &&) = delete; 101 }; 102 103 struct __attribute__((trivial_abi)) S19 { // expected-warning {{'trivial_abi' cannot be applied to 'S19'}} expected-note {{copy constructors and move constructors are all deleted}} 104 CopyDeleted a; 105 MoveDeleted b; 106 }; 107 108 // This is fine since the move constructor isn't deleted. 109 struct __attribute__((trivial_abi)) S20 { 110 int &&a; // a member of rvalue reference type deletes the copy constructor. 111 }; 112 } // namespace deletedCopyMoveConstructor 113