blob: 6181f0eee131efeba7706d683dd78d99ee22a8ca [file] [log] [blame]
Douglas Gregor3d91bbc2010-05-17 15:52:46 +00001// RUN: %clang_cc1 -emit-llvm -O1 -o - %s | FileCheck %s
John McCallf1549f62010-07-06 01:34:17 +00002// RUN: %clang_cc1 -emit-llvm -O1 -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
Douglas Gregord86c4772010-05-15 06:46:45 +00003
4// Test code generation for the named return value optimization.
5class X {
6public:
7 X();
8 X(const X&);
9 ~X();
10};
11
12// CHECK: define void @_Z5test0v
Douglas Gregorb5b30b92010-05-15 16:39:56 +000013// CHECK-EH: define void @_Z5test0v
Douglas Gregord86c4772010-05-15 06:46:45 +000014X test0() {
15 X x;
John McCallf1549f62010-07-06 01:34:17 +000016 // CHECK: call void @_ZN1XC1Ev
17 // CHECK-NEXT: ret void
18
19 // CHECK-EH: call void @_ZN1XC1Ev
20 // CHECK-EH-NEXT: ret void
Douglas Gregord86c4772010-05-15 06:46:45 +000021 return x;
22}
23
24// CHECK: define void @_Z5test1b(
John McCallf1549f62010-07-06 01:34:17 +000025// CHECK-EH: define void @_Z5test1b(
Douglas Gregord86c4772010-05-15 06:46:45 +000026X test1(bool B) {
John McCallf1549f62010-07-06 01:34:17 +000027 // CHECK: tail call void @_ZN1XC1Ev
28 // CHECK-NEXT: ret void
Douglas Gregord86c4772010-05-15 06:46:45 +000029 X x;
Douglas Gregord86c4772010-05-15 06:46:45 +000030 if (B)
31 return (x);
32 return x;
John McCallf1549f62010-07-06 01:34:17 +000033 // CHECK-EH: tail call void @_ZN1XC1Ev
34 // CHECK-EH-NEXT: ret void
Douglas Gregord86c4772010-05-15 06:46:45 +000035}
36
37// CHECK: define void @_Z5test2b
Douglas Gregorb5b30b92010-05-15 16:39:56 +000038// CHECK-EH: define void @_Z5test2b
Douglas Gregord86c4772010-05-15 06:46:45 +000039X test2(bool B) {
John McCallf1549f62010-07-06 01:34:17 +000040 // No NRVO.
41
Douglas Gregord86c4772010-05-15 06:46:45 +000042 X x;
Douglas Gregord86c4772010-05-15 06:46:45 +000043 X y;
Douglas Gregord86c4772010-05-15 06:46:45 +000044 if (B)
45 return y;
Douglas Gregord86c4772010-05-15 06:46:45 +000046 return x;
John McCallf1549f62010-07-06 01:34:17 +000047
48 // CHECK: call void @_ZN1XC1Ev
49 // CHECK-NEXT: call void @_ZN1XC1Ev
50 // CHECK: call void @_ZN1XC1ERKS_
51 // CHECK: call void @_ZN1XC1ERKS_
Douglas Gregord86c4772010-05-15 06:46:45 +000052 // CHECK: call void @_ZN1XD1Ev
53 // CHECK: call void @_ZN1XD1Ev
54 // CHECK: ret void
John McCallf1549f62010-07-06 01:34:17 +000055
56 // The block ordering in the -fexceptions IR is unfortunate.
57
58 // CHECK-EH: call void @_ZN1XC1Ev
59 // CHECK-EH-NEXT: invoke void @_ZN1XC1Ev
60 // -> %invoke.cont1, %lpad
61
62 // %invoke.cont1:
63 // CHECK-EH: br i1
64 // -> %if.then, %if.end
65
66 // %if.then: returning 'x'
67 // CHECK-EH: invoke void @_ZN1XC1ERKS_
68 // -> %cleanup, %lpad5
69
70 // %invoke.cont: rethrow block for %eh.cleanup.
71 // This really should be elsewhere in the function.
72 // CHECK-EH: call void @_Unwind_Resume_or_Rethrow
73 // CHECK-EH-NEXT: unreachable
74
75 // %lpad: landing pad for ctor of 'y', dtor of 'y'
76 // CHECK-EH: call i8* @llvm.eh.exception()
77 // CHECK-EH: call i32 (i8*, i8*, ...)* @llvm.eh.selector
78 // CHECK-EH-NEXT: br label
79 // -> %eh.cleanup
80
81 // %invoke.cont2: normal cleanup for 'x'
82 // CHECK-EH: call void @_ZN1XD1Ev
83 // CHECK-EH-NEXT: ret void
84
85 // %lpad5: landing pad for return copy ctors, EH cleanup for 'y'
Douglas Gregorb5b30b92010-05-15 16:39:56 +000086 // CHECK-EH: invoke void @_ZN1XD1Ev
John McCallf1549f62010-07-06 01:34:17 +000087 // -> %eh.cleanup, %terminate.lpad
88
89 // %if.end: returning 'y'
90 // CHECK-EH: invoke void @_ZN1XC1ERKS_
91 // -> %cleanup, %lpad5
92
93 // %cleanup: normal cleanup for 'y'
Douglas Gregorb5b30b92010-05-15 16:39:56 +000094 // CHECK-EH: invoke void @_ZN1XD1Ev
John McCallf1549f62010-07-06 01:34:17 +000095 // -> %invoke.cont2, %lpad
96
97 // %eh.cleanup: EH cleanup for 'x'
98 // CHECK-EH: invoke void @_ZN1XD1Ev
99 // -> %invoke.cont, %terminate.lpad
100
101 // %terminate.lpad: terminate landing pad.
102 // CHECK-EH: call i8* @llvm.eh.exception()
103 // CHECK-EH-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector
104 // CHECK-EH-NEXT: call void @_ZSt9terminatev()
105 // CHECK-EH-NEXT: unreachable
106
Douglas Gregord86c4772010-05-15 06:46:45 +0000107}
108
109X test3(bool B) {
110 // FIXME: We don't manage to apply NRVO here, although we could.
111 {
112 X y;
113 return y;
114 }
115 X x;
116 return x;
117}
Douglas Gregor3d91bbc2010-05-17 15:52:46 +0000118
119extern "C" void exit(int) throw();
120
121// CHECK: define void @_Z5test4b
122X test4(bool B) {
123 {
124 // CHECK: tail call void @_ZN1XC1Ev
125 X x;
126 // CHECK: br i1
127 if (B)
128 return x;
129 }
130 // CHECK: tail call void @_ZN1XD1Ev
131 // CHECK: tail call void @exit(i32 1)
132 exit(1);
133}