[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