[cfe-commits] r104434 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprObjC.cpp test/CodeGenCXX/references.cpp
Douglas Gregor
dgregor at apple.com
Fri May 21 22:17:18 PDT 2010
Author: dgregor
Date: Sat May 22 00:17:18 2010
New Revision: 104434
URL: http://llvm.org/viewvc/llvm-project?rev=104434&view=rev
Log:
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.
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprAgg.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/CodeGenCXX/references.cpp
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=104434&r1=104433&r2=104434&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat May 22 00:17:18 2010
@@ -211,9 +211,15 @@
llvm::SmallVector<SubobjectAdjustment, 2> Adjustments;
do {
- if (const CastExpr *CE
- = dyn_cast<CastExpr>(E->IgnoreParenNoopCasts(getContext()))) {
- if (CE->getCastKind() == CastExpr::CK_DerivedToBase) {
+ if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
+ E = PE->getSubExpr();
+ continue;
+ }
+
+ if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
+ if ((CE->getCastKind() == CastExpr::CK_DerivedToBase ||
+ CE->getCastKind() == CastExpr::CK_UncheckedDerivedToBase) &&
+ E->getType()->isRecordType()) {
E = CE->getSubExpr();
CXXRecordDecl *Derived
= cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
@@ -221,9 +227,12 @@
Derived));
continue;
}
- } else if (const MemberExpr *ME
- = dyn_cast<MemberExpr>(
- E->IgnoreParenNoopCasts(getContext()))) {
+
+ if (CE->getCastKind() == CastExpr::CK_NoOp) {
+ E = CE->getSubExpr();
+ continue;
+ }
+ } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
if (ME->getBase()->isLvalue(getContext()) != Expr::LV_Valid &&
ME->getBase()->getType()->isRecordType()) {
if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
@@ -234,7 +243,10 @@
}
}
}
- } while (false);
+
+ // Nothing changed.
+ break;
+ } while (true);
Val = EmitAnyExprToTemp(E, /*IsAggLocVolatile=*/false,
IsInitializer);
Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=104434&r1=104433&r2=104434&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Sat May 22 00:17:18 2010
@@ -216,6 +216,14 @@
break;
}
+ case CastExpr::CK_DerivedToBase:
+ case CastExpr::CK_BaseToDerived:
+ case CastExpr::CK_UncheckedDerivedToBase: {
+ assert(0 && "cannot perform hierarchy conversion in EmitAggExpr: "
+ "should have been unpacked before we got here");
+ break;
+ }
+
// FIXME: Remove the CK_Unknown check here.
case CastExpr::CK_Unknown:
case CastExpr::CK_NoOp:
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=104434&r1=104433&r2=104434&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat May 22 00:17:18 2010
@@ -1404,6 +1404,9 @@
SourceRange FromRange = From->getSourceRange();
SourceLocation FromLoc = FromRange.getBegin();
+ bool isLvalue
+ = (From->isLvalue(Context) == Expr::LV_Valid) && !PointerConversions;
+
// C++ [class.member.lookup]p8:
// [...] Ambiguities can often be resolved by qualifying a name with its
// class name.
@@ -1441,7 +1444,7 @@
if (PointerConversions)
QType = Context.getPointerType(QType);
ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase,
- /*isLvalue=*/!PointerConversions, BasePath);
+ isLvalue, BasePath);
FromType = QType;
FromRecordType = QRecordType;
@@ -1478,7 +1481,7 @@
if (PointerConversions)
UType = Context.getPointerType(UType);
ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase,
- /*isLvalue=*/!PointerConversions, BasePath);
+ isLvalue, BasePath);
FromType = UType;
FromRecordType = URecordType;
}
@@ -1495,7 +1498,7 @@
return true;
ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase,
- /*isLvalue=*/!PointerConversions, BasePath);
+ isLvalue, BasePath);
return false;
}
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=104434&r1=104433&r2=104434&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Sat May 22 00:17:18 2010
@@ -764,15 +764,17 @@
}
// Construct the appropriate ObjCMessageExpr.
+ Expr *Result;
if (SuperLoc.isValid())
- return Owned(ObjCMessageExpr::Create(Context, ReturnType, LBracLoc,
- SuperLoc, /*IsInstanceSuper=*/false,
- ReceiverType, Sel, Method, Args,
- NumArgs, RBracLoc));
-
- return Owned(ObjCMessageExpr::Create(Context, ReturnType, LBracLoc,
- ReceiverTypeInfo, Sel, Method, Args,
- NumArgs, RBracLoc));
+ Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc,
+ SuperLoc, /*IsInstanceSuper=*/false,
+ ReceiverType, Sel, Method, Args,
+ NumArgs, RBracLoc);
+ else
+ Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc,
+ ReceiverTypeInfo, Sel, Method, Args,
+ NumArgs, RBracLoc);
+ return MaybeBindToTemporary(Result);
}
// ActOnClassMessage - used for both unary and keyword messages.
@@ -1007,14 +1009,16 @@
return ExprError();
// Construct the appropriate ObjCMessageExpr instance.
+ Expr *Result;
if (SuperLoc.isValid())
- return Owned(ObjCMessageExpr::Create(Context, ReturnType, LBracLoc,
- SuperLoc, /*IsInstanceSuper=*/true,
- ReceiverType, Sel, Method,
- Args, NumArgs, RBracLoc));
-
- return Owned(ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver,
- Sel, Method, Args, NumArgs, RBracLoc));
+ Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc,
+ SuperLoc, /*IsInstanceSuper=*/true,
+ ReceiverType, Sel, Method,
+ Args, NumArgs, RBracLoc);
+ else
+ Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver,
+ Sel, Method, Args, NumArgs, RBracLoc);
+ return MaybeBindToTemporary(Result);
}
// ActOnInstanceMessage - used for both unary and keyword messages.
Modified: cfe/trunk/test/CodeGenCXX/references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/references.cpp?rev=104434&r1=104433&r2=104434&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/references.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/references.cpp Sat May 22 00:17:18 2010
@@ -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;
More information about the cfe-commits
mailing list