[cfe-commits] r89987 - in /cfe/trunk/lib: CodeGen/CGExprScalar.cpp Sema/SemaExprCXX.cpp

Eli Friedman eli.friedman at gmail.com
Thu Nov 26 20:41:52 PST 2009


Author: efriedma
Date: Thu Nov 26 22:41:50 2009
New Revision: 89987

URL: http://llvm.org/viewvc/llvm-project?rev=89987&view=rev
Log:
More work on ScalarExprEmitter::EmitCastExpr: for every cast kind, either
implement it explicitly or assert that it doesn't make sense for a scalar.
This caught a couple interesting issues: one, CK_BaseToDerivedMemberPointer
casts were getting silently miscompiled, and two, Sema was constructing some
strange implicit casts of type CK_UserDefinedConversion.

The change in SemaExprCXX makes sure the cast kinds are getting set correctly.


Modified:
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=89987&r1=89986&r2=89987&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Thu Nov 26 22:41:50 2009
@@ -187,14 +187,14 @@
   Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
     return llvm::Constant::getNullValue(ConvertType(E->getType()));
   }
-  Value *VisitCastExpr(const CastExpr *E) {
+  Value *VisitCastExpr(CastExpr *E) {
     // Make sure to evaluate VLA bounds now so that we have them for later.
     if (E->getType()->isVariablyModifiedType())
       CGF.EmitVLASize(E->getType());
 
     return EmitCastExpr(E);
   }
-  Value *EmitCastExpr(const CastExpr *E);
+  Value *EmitCastExpr(CastExpr *E);
 
   Value *VisitCallExpr(const CallExpr *E) {
     if (E->getCallReturnType()->isReferenceType())
@@ -782,8 +782,8 @@
 // VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
 // have to handle a more broad range of conversions than explicit casts, as they
 // handle things like function to ptr-to-function decay etc.
-Value *ScalarExprEmitter::EmitCastExpr(const CastExpr *CE) {
-  const Expr *E = CE->getSubExpr();
+Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
+  Expr *E = CE->getSubExpr();
   QualType DestTy = CE->getType();
   CastExpr::CastKind Kind = CE->getCastKind();
   
@@ -795,6 +795,7 @@
   // are in the same order as in the CastKind enum.
   switch (Kind) {
   case CastExpr::CK_Unknown:
+    // FIXME: All casts should have a known kind!
     //assert(0 && "Unknown cast kind!");
     break;
 
@@ -838,10 +839,10 @@
     const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE);
     return CGF.EmitDynamicCast(V, DCE);
   }
-  case CastExpr::CK_ToUnion: {
+  case CastExpr::CK_ToUnion:
     assert(0 && "Should be unreachable!");
     break;
-  }
+
   case CastExpr::CK_ArrayToPointerDecay: {
     assert(E->getType()->isArrayType() &&
            "Array to pointer decay must have array source type!");
@@ -867,9 +868,32 @@
     return CGF.CGM.EmitNullConstant(DestTy);
 
   case CastExpr::CK_BaseToDerivedMemberPointer:
-  case CastExpr::CK_DerivedToBaseMemberPointer:
+  case CastExpr::CK_DerivedToBaseMemberPointer: {
+    Value *Src = Visit(E);
+
+    // See if we need to adjust the pointer.
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(E->getType()->getAs<MemberPointerType>()->
+                          getClass()->getAs<RecordType>()->getDecl());
+    const CXXRecordDecl *DerivedDecl = 
+      cast<CXXRecordDecl>(CE->getType()->getAs<MemberPointerType>()->
+                          getClass()->getAs<RecordType>()->getDecl());
+    if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
+      std::swap(DerivedDecl, BaseDecl);
+
+    llvm::Constant *Adj = CGF.CGM.GetCXXBaseClassOffset(DerivedDecl, BaseDecl);
+    if (Adj) {
+      if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
+        Src = Builder.CreateSub(Src, Adj, "adj");
+      else
+        Src = Builder.CreateAdd(Src, Adj, "adj");
+    }
+    return Src;
+  }
+
   case CastExpr::CK_UserDefinedConversion:
   case CastExpr::CK_ConstructorConversion:
+    assert(0 && "Should be unreachable!");
     break;
 
   case CastExpr::CK_IntegralToPointer: {
@@ -918,7 +942,7 @@
   case CastExpr::CK_IntegralToFloating:
   case CastExpr::CK_FloatingToIntegral:
   case CastExpr::CK_FloatingCast:
-    break;
+    return EmitScalarConversion(Visit(E), E->getType(), DestTy);
 
   case CastExpr::CK_MemberPointerToBoolean: {
     const MemberPointerType* T = E->getType()->getAs<MemberPointerType>();

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=89987&r1=89986&r2=89987&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Nov 26 22:41:50 2009
@@ -1141,21 +1141,25 @@
 
       if (CastArg.isInvalid())
         return true;
-    
+
+      From = CastArg.takeAs<Expr>();
+
+      // FIXME: This and the following if statement shouldn't be necessary, but
+      // there's some nasty stuff involving MaybeBindToTemporary going on here.
       if (ICS.UserDefined.After.Second == ICK_Derived_To_Base &&
           ICS.UserDefined.After.CopyConstructor) {
-        From = CastArg.takeAs<Expr>();
         return BuildCXXDerivedToBaseExpr(From, CastKind, ICS, Flavor);
       }
-    
-      if (ICS.UserDefined.After.Second == ICK_Pointer_Member &&
-          ToType.getNonReferenceType()->isMemberFunctionPointerType())
-        CastKind = CastExpr::CK_BaseToDerivedMemberPointer;
-      
-      From = new (Context) ImplicitCastExpr(ToType.getNonReferenceType(),
-                                            CastKind, CastArg.takeAs<Expr>(),
-                                            ToType->isLValueReferenceType());
-      return false;
+
+      if (ICS.UserDefined.After.CopyConstructor) {
+        From = new (Context) ImplicitCastExpr(ToType.getNonReferenceType(),
+                                              CastKind, From,
+                                              ToType->isLValueReferenceType());
+        return false;
+      }
+
+      return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
+                                       "converting", IgnoreBaseAccess);
   }
       
   case ImplicitConversionSequence::EllipsisConversion:





More information about the cfe-commits mailing list