Improve our handling of reference binding for subobjects of
temporaries. There are actually several interrelated fixes here:
- When converting an object to a base class, it's only an lvalue
cast when the original object was an lvalue and we aren't casting
pointer-to-derived to pointer-to-base. Previously, we were
misclassifying derived-to-base casts of class rvalues as lvalues,
causing various oddities (including problems with reference binding
not extending the lifetimes of some temporaries).
- Teach the code for emitting a reference binding how to look
through no-op casts and parentheses directly, since
Expr::IgnoreParenNoOpCasts is just plain wrong for this. Also, make
sure that we properly look through multiple levels of indirection
from the temporary object, but destroy the actual temporary object;
this fixes the reference-binding issue mentioned above.
- Teach Objective-C message sends to bind the result as a temporary
when needed. This is actually John's change, but it triggered the
reference-binding problem above, so it's included here. Now John
can actually test his return-slot improvements.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104434 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
index ed16249..6fc6102 100644
--- a/test/CodeGenCXX/references.cpp
+++ b/test/CodeGenCXX/references.cpp
@@ -215,7 +215,11 @@
// CHECK: define void @_ZN2N21gEi
// CHECK: call void @_ZN2N24getZEv
- // FIXME: Not treated as an lvalue!
+ // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
+ // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
+ // CHECK: store i32 19
+ // CHECK: call void @_ZN2N21ZD1Ev
+ // CHECK: ret void
void g(int i) {
const X &xr = getZ().has.x;
i = 19;