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