1 //RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-unknown-linux | FileCheck --check-prefix=CHECKGEN %s
2 //RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios6.0 -target-abi apcs-gnu | FileCheck --check-prefix=CHECKARM %s
3 //RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios5.0 -target-abi apcs-gnu | FileCheck --check-prefix=CHECKIOS5 %s
4 //RUN: %clang_cc1 %s -emit-llvm -o - -triple=wasm32-unknown-unknown \
5 //RUN:   | FileCheck --check-prefix=CHECKARM %s
6 //RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-fuchsia | FileCheck --check-prefix=CHECKFUCHSIA %s
7 //RUN: %clang_cc1 %s -emit-llvm -o - -triple=aarch64-unknown-fuchsia | FileCheck --check-prefix=CHECKFUCHSIA %s
8 //RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-pc-win32 -fno-rtti | FileCheck --check-prefix=CHECKMS %s
9 // FIXME: these tests crash on the bots when run with -triple=x86_64-pc-win32
10 
11 // Make sure we attach the 'returned' attribute to the 'this' parameter of
12 // constructors and destructors which return this (and only these cases)
13 
14 class A {
15 public:
16   A();
17   virtual ~A();
18 
19 private:
20   int x_;
21 };
22 
23 class B : public A {
24 public:
25   B(int *i);
26   virtual ~B();
27 
28 private:
29   int *i_;
30 };
31 
B(int * i)32 B::B(int *i) : i_(i) { }
~B()33 B::~B() { }
34 
35 // CHECKGEN-LABEL: define{{.*}} void @_ZN1BC2EPi(%class.B* {{[^,]*}} %this, i32* %i)
36 // CHECKGEN-LABEL: define{{.*}} void @_ZN1BC1EPi(%class.B* {{[^,]*}} %this, i32* %i)
37 // CHECKGEN-LABEL: define{{.*}} void @_ZN1BD2Ev(%class.B* {{[^,]*}} %this)
38 // CHECKGEN-LABEL: define{{.*}} void @_ZN1BD1Ev(%class.B* {{[^,]*}} %this)
39 
40 // CHECKARM-LABEL: define{{.*}} %class.B* @_ZN1BC2EPi(%class.B* {{[^,]*}} returned {{[^,]*}} %this, i32* %i)
41 // CHECKARM-LABEL: define{{.*}} %class.B* @_ZN1BC1EPi(%class.B* {{[^,]*}} returned {{[^,]*}} %this, i32* %i)
42 // CHECKARM-LABEL: define{{.*}} %class.B* @_ZN1BD2Ev(%class.B* {{[^,]*}} returned {{[^,]*}} %this)
43 // CHECKARM-LABEL: define{{.*}} %class.B* @_ZN1BD1Ev(%class.B* {{[^,]*}} returned {{[^,]*}} %this)
44 
45 // CHECKIOS5-LABEL: define{{.*}} %class.B* @_ZN1BC2EPi(%class.B* {{[^,]*}} %this, i32* %i)
46 // CHECKIOS5-LABEL: define{{.*}} %class.B* @_ZN1BC1EPi(%class.B* {{[^,]*}} %this, i32* %i)
47 // CHECKIOS5-LABEL: define{{.*}} %class.B* @_ZN1BD2Ev(%class.B* {{[^,]*}} %this)
48 // CHECKIOS5-LABEL: define{{.*}} %class.B* @_ZN1BD1Ev(%class.B* {{[^,]*}} %this)
49 
50 // CHECKFUCHSIA-LABEL: define{{.*}} %class.B* @_ZN1BC2EPi(%class.B* {{[^,]*}} returned {{[^,]*}} %this, i32* %i)
51 // CHECKFUCHSIA-LABEL: define{{.*}} %class.B* @_ZN1BC1EPi(%class.B* {{[^,]*}} returned {{[^,]*}} %this, i32* %i)
52 // CHECKFUCHSIA-LABEL: define{{.*}} %class.B* @_ZN1BD2Ev(%class.B* {{[^,]*}} returned {{[^,]*}} %this)
53 // CHECKFUCHSIA-LABEL: define{{.*}} %class.B* @_ZN1BD1Ev(%class.B* {{[^,]*}} returned {{[^,]*}} %this)
54 
55 // CHECKMS-LABEL: define dso_local x86_thiscallcc %class.B* @"??0B@@QAE@PAH@Z"(%class.B* {{[^,]*}} returned {{[^,]*}} %this, i32* %i)
56 // CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1B@@UAE@XZ"(%class.B* {{[^,]*}} %this)
57 
58 class C : public A, public B {
59 public:
60   C(int *i, char *c);
61   virtual ~C();
62 private:
63   char *c_;
64 };
65 
C(int * i,char * c)66 C::C(int *i, char *c) : B(i), c_(c) { }
~C()67 C::~C() { }
68 
69 // CHECKGEN-LABEL: define{{.*}} void @_ZN1CC2EPiPc(%class.C* {{[^,]*}} %this, i32* %i, i8* %c)
70 // CHECKGEN-LABEL: define{{.*}} void @_ZN1CC1EPiPc(%class.C* {{[^,]*}} %this, i32* %i, i8* %c)
71 // CHECKGEN-LABEL: define{{.*}} void @_ZN1CD2Ev(%class.C* {{[^,]*}} %this)
72 // CHECKGEN-LABEL: define{{.*}} void @_ZN1CD1Ev(%class.C* {{[^,]*}} %this)
73 // CHECKGEN-LABEL: define{{.*}} void @_ZThn8_N1CD1Ev(%class.C* %this)
74 // CHECKGEN-LABEL: define{{.*}} void @_ZN1CD0Ev(%class.C* {{[^,]*}} %this)
75 // CHECKGEN-LABEL: define{{.*}} void @_ZThn8_N1CD0Ev(%class.C* %this)
76 
77 // CHECKARM-LABEL: define{{.*}} %class.C* @_ZN1CC2EPiPc(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
78 // CHECKARM-LABEL: define{{.*}} %class.C* @_ZN1CC1EPiPc(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
79 // CHECKARM-LABEL: define{{.*}} %class.C* @_ZN1CD2Ev(%class.C* {{[^,]*}} returned {{[^,]*}} %this)
80 // CHECKARM-LABEL: define{{.*}} %class.C* @_ZN1CD1Ev(%class.C* {{[^,]*}} returned {{[^,]*}} %this)
81 // CHECKARM-LABEL: define{{.*}} %class.C* @_ZThn8_N1CD1Ev(%class.C* %this)
82 // CHECKARM-LABEL: define{{.*}} void @_ZN1CD0Ev(%class.C* {{[^,]*}} %this)
83 // CHECKARM-LABEL: define{{.*}} void @_ZThn8_N1CD0Ev(%class.C* %this)
84 
85 // CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZN1CC2EPiPc(%class.C* {{[^,]*}} %this, i32* %i, i8* %c)
86 // CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZN1CC1EPiPc(%class.C* {{[^,]*}} %this, i32* %i, i8* %c)
87 // CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZN1CD2Ev(%class.C* {{[^,]*}} %this)
88 // CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZN1CD1Ev(%class.C* {{[^,]*}} %this)
89 // CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZThn8_N1CD1Ev(%class.C* %this)
90 // CHECKIOS5-LABEL: define{{.*}} void @_ZN1CD0Ev(%class.C* {{[^,]*}} %this)
91 // CHECKIOS5-LABEL: define{{.*}} void @_ZThn8_N1CD0Ev(%class.C* %this)
92 
93 // CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZN1CC2EPiPc(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
94 // CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZN1CC1EPiPc(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
95 // CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZN1CD2Ev(%class.C* {{[^,]*}} returned {{[^,]*}} %this)
96 // CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZN1CD1Ev(%class.C* {{[^,]*}} returned {{[^,]*}} %this)
97 // CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZThn16_N1CD1Ev(%class.C* %this)
98 // CHECKFUCHSIA-LABEL: define{{.*}} void @_ZN1CD0Ev(%class.C* {{[^,]*}} %this)
99 // CHECKFUCHSIA-LABEL: define{{.*}} void @_ZThn16_N1CD0Ev(%class.C* %this)
100 
101 // CHECKMS-LABEL: define dso_local x86_thiscallcc %class.C* @"??0C@@QAE@PAHPAD@Z"(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
102 // CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1C@@UAE@XZ"(%class.C* {{[^,]*}} %this)
103 
104 class D : public virtual A {
105 public:
106   D();
107   ~D();
108 };
109 
D()110 D::D() { }
~D()111 D::~D() { }
112 
113 // CHECKGEN-LABEL: define{{.*}} void @_ZN1DC2Ev(%class.D* {{[^,]*}} %this, i8** %vtt)
114 // CHECKGEN-LABEL: define{{.*}} void @_ZN1DC1Ev(%class.D* {{[^,]*}} %this)
115 // CHECKGEN-LABEL: define{{.*}} void @_ZN1DD2Ev(%class.D* {{[^,]*}} %this, i8** %vtt)
116 // CHECKGEN-LABEL: define{{.*}} void @_ZN1DD1Ev(%class.D* {{[^,]*}} %this)
117 
118 // CHECKARM-LABEL: define{{.*}} %class.D* @_ZN1DC2Ev(%class.D* {{[^,]*}} returned {{[^,]*}} %this, i8** %vtt)
119 // CHECKARM-LABEL: define{{.*}} %class.D* @_ZN1DC1Ev(%class.D* {{[^,]*}} returned {{[^,]*}} %this)
120 // CHECKARM-LABEL: define{{.*}} %class.D* @_ZN1DD2Ev(%class.D* {{[^,]*}} returned {{[^,]*}} %this, i8** %vtt)
121 // CHECKARM-LABEL: define{{.*}} %class.D* @_ZN1DD1Ev(%class.D* {{[^,]*}} returned {{[^,]*}} %this)
122 
123 // CHECKIOS5-LABEL: define{{.*}} %class.D* @_ZN1DC2Ev(%class.D* {{[^,]*}} %this, i8** %vtt)
124 // CHECKIOS5-LABEL: define{{.*}} %class.D* @_ZN1DC1Ev(%class.D* {{[^,]*}} %this)
125 // CHECKIOS5-LABEL: define{{.*}} %class.D* @_ZN1DD2Ev(%class.D* {{[^,]*}} %this, i8** %vtt)
126 // CHECKIOS5-LABEL: define{{.*}} %class.D* @_ZN1DD1Ev(%class.D* {{[^,]*}} %this)
127 
128 // CHECKFUCHSIA-LABEL: define{{.*}} %class.D* @_ZN1DC2Ev(%class.D* {{[^,]*}} returned {{[^,]*}} %this, i8** %vtt)
129 // CHECKFUCHSIA-LABEL: define{{.*}} %class.D* @_ZN1DC1Ev(%class.D* {{[^,]*}} returned {{[^,]*}} %this)
130 // CHECKFUCHSIA-LABEL: define{{.*}} %class.D* @_ZN1DD2Ev(%class.D* {{[^,]*}} returned {{[^,]*}} %this, i8** %vtt)
131 // CHECKFUCHSIA-LABEL: define{{.*}} %class.D* @_ZN1DD1Ev(%class.D* {{[^,]*}} returned {{[^,]*}} %this)
132 
133 // CHECKMS-LABEL: define dso_local x86_thiscallcc %class.D* @"??0D@@QAE@XZ"(%class.D* {{[^,]*}} returned {{[^,]*}} %this, i32 %is_most_derived)
134 // CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1D@@UAE@XZ"(%class.D* {{[^,]*}} %this)
135 
136 class E {
137 public:
138   E();
139   virtual ~E();
140 };
141 
142 E* gete();
143 
test_destructor()144 void test_destructor() {
145   const E& e1 = E();
146   E* e2 = gete();
147   e2->~E();
148 }
149 
150 // CHECKARM-LABEL,CHECKFUCHSIA-LABEL: define{{.*}} void @_Z15test_destructorv()
151 
152 // Verify that virtual calls to destructors are not marked with a 'returned'
153 // this parameter at the call site...
154 // CHECKARM: [[VFN:%.*]] = getelementptr inbounds %class.E* (%class.E*)*, %class.E* (%class.E*)**
155 // CHECKARM: [[THUNK:%.*]] = load %class.E* (%class.E*)*, %class.E* (%class.E*)** [[VFN]]
156 // CHECKFUCHSIA: [[THUNK_I8:%.*]] = call i8* @llvm.load.relative.i32(i8* {{.*}}, i32 0)
157 // CHECKFUCHSIA: [[THUNK:%.*]] = bitcast i8* [[THUNK_I8]] to %class.E* (%class.E*)*
158 // CHECKARM,CHECKFUCHSIA: call %class.E* [[THUNK]](%class.E* {{[^,]*}} %
159 
160 // ...but static calls create declarations with 'returned' this
161 // CHECKARM,CHECKFUCHSIA: {{%.*}} = call %class.E* @_ZN1ED1Ev(%class.E* {{[^,]*}} %
162 
163 // CHECKARM,CHECKFUCHSIA: declare %class.E* @_ZN1ED1Ev(%class.E* {{[^,]*}} returned {{[^,]*}})
164