diff options
Diffstat (limited to 'test/CodeGenCXX/nrvo.cpp')
-rw-r--r-- | test/CodeGenCXX/nrvo.cpp | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp index b83dd727e0bb..aad287dc3206 100644 --- a/test/CodeGenCXX/nrvo.cpp +++ b/test/CodeGenCXX/nrvo.cpp @@ -9,6 +9,14 @@ public: ~X(); }; +template<typename T> struct Y { + Y(); + static Y f() { + Y y; + return y; + } +}; + // CHECK-LABEL: define void @_Z5test0v // CHECK-EH-LABEL: define void @_Z5test0v X test0() { @@ -108,12 +116,17 @@ X test2(bool B) { } +// CHECK-LABEL: define void @_Z5test3b X test3(bool B) { - // FIXME: We don't manage to apply NRVO here, although we could. - { + // CHECK: tail call {{.*}} @_ZN1XC1Ev + // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_ + // CHECK: call {{.*}} @_ZN1XC1Ev + // CHECK: call {{.*}} @_ZN1XC1ERKS_ + if (B) { X y; return y; } + // FIXME: we should NRVO this variable too. X x; return x; } @@ -156,9 +169,40 @@ X test6() { return a; // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]]) - // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* [[A]]) + // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* dereferenceable({{[0-9]+}}) [[A]]) // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]]) // CHECK-NEXT: ret void } +// CHECK-LABEL: define void @_Z5test7b +X test7(bool b) { + // CHECK: tail call {{.*}} @_ZN1XC1Ev + // CHECK-NEXT: ret + if (b) { + X x; + return x; + } + return X(); +} + +// CHECK-LABEL: define void @_Z5test8b +X test8(bool b) { + // CHECK: tail call {{.*}} @_ZN1XC1Ev + // CHECK-NEXT: ret + if (b) { + X x; + return x; + } else { + X y; + return y; + } +} + +Y<int> test9() { + Y<int>::f(); +} + +// CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv +// CHECK: tail call {{.*}} @_ZN1YIiEC1Ev + // CHECK-EH: attributes [[NR_NUW]] = { noreturn nounwind } |