summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/references.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-20 08:36:28 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-20 08:36:28 +0000
commit7c38f153ac1830d808659d3091b86f2246f480ca (patch)
treea37f5b4b8e7ea0f09ee04e2a4bd6897de644cbb3 /clang/test/CodeGenCXX/references.cpp
parent58efb8e2bbd30fc8d3205031b31472e6301e157f (diff)
downloadbcm5719-llvm-7c38f153ac1830d808659d3091b86f2246f480ca.tar.gz
bcm5719-llvm-7c38f153ac1830d808659d3091b86f2246f480ca.zip
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class subobject while extending the lifetime of the complete object (of a derived type); for non-static data member subobjects, we could memcpy (!) the result and bind to that, which is rather broken. Now, we pull apart the expression that we're binding to, to figure out which subobject we're accessing, then construct the temporary object (adding a destruction if needed) and, finally, dig out the subobject we actually meant to access. This fixes yet another instance where we were memcpy'ing rather than doing the right thing. However, note the FIXME in references.cpp: there's more work to be done for binding to subobjects, since the AST is incorrectly modeling some member accesses in base classes as lvalues when they are really rvalues. llvm-svn: 104219
Diffstat (limited to 'clang/test/CodeGenCXX/references.cpp')
-rw-r--r--clang/test/CodeGenCXX/references.cpp55
1 files changed, 54 insertions, 1 deletions
diff --git a/clang/test/CodeGenCXX/references.cpp b/clang/test/CodeGenCXX/references.cpp
index 3ae1e474f88..ed162492b30 100644
--- a/clang/test/CodeGenCXX/references.cpp
+++ b/clang/test/CodeGenCXX/references.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -verify -emit-llvm -o - %s | FileCheck %s
void t1() {
extern int& a;
int b = a;
@@ -168,3 +168,56 @@ namespace N1 {
const int* const args_array[] = { &arg };
}
}
+
+// Bind to subobjects while extending the life of the complete object.
+namespace N2 {
+ class X {
+ public:
+ X(const X&);
+ X &operator=(const X&);
+ ~X();
+ };
+
+ struct P {
+ X first;
+ };
+
+ P getP();
+
+ // CHECK: define void @_ZN2N21fEi
+ // CHECK: call void @_ZN2N24getPEv
+ // CHECK: getelementptr inbounds
+ // CHECK: store i32 17
+ // CHECK: call void @_ZN2N21PD1Ev
+ void f(int i) {
+ const X& xr = getP().first;
+ i = 17;
+ }
+
+ struct SpaceWaster {
+ int i, j;
+ };
+
+ struct ReallyHasX {
+ X x;
+ };
+
+ struct HasX : ReallyHasX { };
+
+ struct HasXContainer {
+ HasX has;
+ };
+
+ struct Y : SpaceWaster, HasXContainer { };
+ struct Z : SpaceWaster, Y { };
+
+ Z getZ();
+
+ // CHECK: define void @_ZN2N21gEi
+ // CHECK: call void @_ZN2N24getZEv
+ // FIXME: Not treated as an lvalue!
+ void g(int i) {
+ const X &xr = getZ().has.x;
+ i = 19;
+ }
+}
OpenPOWER on IntegriCloud