[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