summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/rvalue-references.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-27 23:22:05 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-27 23:22:05 +0000
commit21d3fca917ec5b9dce432b802bc113bd7e50d2be (patch)
tree0d8ca5fc68b56f905b8418feb0286dec4e2edb84 /clang/test/CodeGenCXX/rvalue-references.cpp
parente4de27900921801cfbddeb02b725740fe2c0c5cc (diff)
downloadbcm5719-llvm-21d3fca917ec5b9dce432b802bc113bd7e50d2be.tar.gz
bcm5719-llvm-21d3fca917ec5b9dce432b802bc113bd7e50d2be.zip
When producing IR for a lvalue-to-rvalue cast *as an lvalue*, only
non-class prvalues actually require the realization of a temporary. For everything else, we already have an lvalue (or class prvalue) in the subexpression. Note: we're missing some move elision in this case. I'll tackle that next. llvm-svn: 124453
Diffstat (limited to 'clang/test/CodeGenCXX/rvalue-references.cpp')
-rw-r--r--clang/test/CodeGenCXX/rvalue-references.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/rvalue-references.cpp b/clang/test/CodeGenCXX/rvalue-references.cpp
index 693e1431ddc..a7c74ae5c06 100644
--- a/clang/test/CodeGenCXX/rvalue-references.cpp
+++ b/clang/test/CodeGenCXX/rvalue-references.cpp
@@ -34,3 +34,55 @@ int &&f1() { return static_cast<int&&>(getIntXValue()); }
// CHECK-NEXT: store i32 {{.*}}, i32*
// CHECK-NEXT: ret i32*
int &&f2() { return static_cast<int&&>(getIntPRValue()); }
+
+bool ok;
+
+class C
+{
+ int* state_;
+
+ C(const C&) = delete;
+ C& operator=(const C&) = delete;
+public:
+ C(int state) : state_(new int(state)) { }
+
+ C(C&& a) {
+ state_ = a.state_;
+ a.state_ = 0;
+ }
+
+ ~C() {
+ delete state_;
+ state_ = 0;
+ }
+};
+
+C test();
+
+// CHECK: define void @_Z15elide_copy_initv
+void elide_copy_init() {
+ ok = false;
+ // FIXME: We're doing an extra move here, when we shouldn't be!
+ // CHECK: call void @_Z4testv(%class.C* sret %ref.tmp)
+ // CHECK: call void @_ZN1CC1EOS_(%class.C* %a, %class.C* %ref.tmp)
+ // CHECK: call void @_ZN1CD1Ev(%class.C* %ref.tmp)
+ C a = test();
+ // CHECK: call void @_ZN1CD1Ev(%class.C* %a)
+ // CHECK: ret void
+}
+
+// CHECK: define void @_Z16test_move_returnv
+C test_move_return() {
+ // CHECK: call void @_ZN1CC1Ei
+ C a1(3);
+ // CHECK: call void @_ZN1CC1Ei
+ C a2(4);
+ if (ok)
+ // CHECK: call void @_ZN1CC1EOS_
+ return a1;
+ // CHECK: call void @_ZN1CC1EOS_
+ return a2;
+ // CHECK: call void @_ZN1CD1Ev
+ // CHECK: call void @_ZN1CD1Ev
+ //CHECK: ret void
+}
OpenPOWER on IntegriCloud