On Mar 16, 2011, at 2:33 PM, Matt Beaumont-Gay wrote: > Hi John, > ' > On Tue, Mar 15, 2011 at 14:17, John McCall <[email protected]> wrote: >> Author: rjmccall >> Date: Tue Mar 15 16:17:48 2011 >> New Revision: 127702 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=127702&view=rev >> Log: >> Reorganize the emission of (unfoldable) constant casts a bit, and >> make sure that upcasts of member pointer types are covered as constants. >> Fixed rdar://problem/9130221 >> >> >> Modified: >> cfe/trunk/lib/CodeGen/CGExprConstant.cpp >> cfe/trunk/test/CodeGenCXX/member-function-pointers.cpp >> >> Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=127702&r1=127701&r2=127702&view=diff >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) >> +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Mar 15 16:17:48 2011 >> @@ -483,18 +483,17 @@ >> } >> >> llvm::Constant *VisitCastExpr(CastExpr* E) { >> + Expr *subExpr = E->getSubExpr(); >> + llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), >> CGF); >> + if (!C) return 0; >> + >> + const llvm::Type *destType = ConvertType(E->getType()); >> + >> switch (E->getCastKind()) { >> case CK_ToUnion: { >> // GCC cast to union extension >> assert(E->getType()->isUnionType() && >> "Destination type is not union type!"); >> - const llvm::Type *Ty = ConvertType(E->getType()); >> - Expr *SubExpr = E->getSubExpr(); >> - >> - llvm::Constant *C = >> - CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF); >> - if (!C) >> - return 0; >> >> // Build a struct with the union sub-element as the first member, >> // and padded to the appropriate size >> @@ -503,7 +502,7 @@ >> Elts.push_back(C); >> Types.push_back(C->getType()); >> unsigned CurSize = CGM.getTargetData().getTypeAllocSize(C->getType()); >> - unsigned TotalSize = CGM.getTargetData().getTypeAllocSize(Ty); >> + unsigned TotalSize = CGM.getTargetData().getTypeAllocSize(destType); >> >> assert(CurSize <= TotalSize && "Union size mismatch!"); >> if (unsigned NumPadBytes = TotalSize - CurSize) { >> @@ -523,39 +522,101 @@ >> const MemberPointerType *MPT = >> E->getType()->getAs<MemberPointerType>(); >> return CGM.getCXXABI().EmitNullMemberPointer(MPT); >> } >> - >> - case CK_BaseToDerivedMemberPointer: { >> - Expr *SubExpr = E->getSubExpr(); >> - llvm::Constant *C = >> - CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF); >> - if (!C) return 0; >> >> + case CK_DerivedToBaseMemberPointer: >> + case CK_BaseToDerivedMemberPointer: >> return CGM.getCXXABI().EmitMemberPointerConversion(C, E); >> - } >> >> - case CK_BitCast: >> - // This must be a member function pointer cast. >> - return Visit(E->getSubExpr()); >> - >> - default: { >> - // FIXME: This should be handled by the CK_NoOp cast kind. >> - // Explicit and implicit no-op casts >> - QualType Ty = E->getType(), SubTy = E->getSubExpr()->getType(); >> - if (CGM.getContext().hasSameUnqualifiedType(Ty, SubTy)) >> - return Visit(E->getSubExpr()); >> - >> - // Handle integer->integer casts for address-of-label differences. >> - if (Ty->isIntegerType() && SubTy->isIntegerType() && >> - CGF) { >> - llvm::Value *Src = Visit(E->getSubExpr()); >> - if (Src == 0) return 0; >> - >> - // Use EmitScalarConversion to perform the conversion. >> - return cast<llvm::Constant>(CGF->EmitScalarConversion(Src, SubTy, >> Ty)); >> - } >> - >> + case CK_LValueToRValue: >> + case CK_NoOp: >> + return C; >> + >> + case CK_AnyPointerToObjCPointerCast: >> + case CK_AnyPointerToBlockPointerCast: >> + case CK_LValueBitCast: >> + case CK_BitCast: >> + if (C->getType() == destType) return C; >> + return llvm::ConstantExpr::getBitCast(C, destType); >> + >> + case CK_Dependent: llvm_unreachable("saw dependent cast!"); >> + >> + // These will never be supported. >> + case CK_ObjCObjectLValueCast: >> + case CK_GetObjCProperty: >> + case CK_ToVoid: >> + case CK_Dynamic: >> return 0; >> + >> + // These might need to be supported for constexpr. >> + case CK_UserDefinedConversion: >> + case CK_ConstructorConversion: >> + return 0; >> + >> + // These should eventually be supported. >> + case CK_ArrayToPointerDecay: >> + case CK_FunctionToPointerDecay: >> + case CK_BaseToDerived: >> + case CK_DerivedToBase: >> + case CK_UncheckedDerivedToBase: >> + case CK_MemberPointerToBoolean: >> + case CK_VectorSplat: >> + case CK_FloatingRealToComplex: >> + case CK_FloatingComplexToReal: >> + case CK_FloatingComplexToBoolean: >> + case CK_FloatingComplexCast: >> + case CK_FloatingComplexToIntegralComplex: >> + case CK_IntegralRealToComplex: >> + case CK_IntegralComplexToReal: >> + case CK_IntegralComplexToBoolean: >> + case CK_IntegralComplexCast: >> + case CK_IntegralComplexToFloatingComplex: >> + return 0; >> + >> + case CK_PointerToIntegral: >> + if (!E->getType()->isBooleanType()) >> + return llvm::ConstantExpr::getPtrToInt(C, destType); >> + // fallthrough >> + >> + case CK_PointerToBoolean: >> + return llvm::ConstantExpr::getICmp(llvm::CmpInst::ICMP_EQ, C, >> + >> llvm::ConstantPointerNull::get(cast<llvm::PointerType>(C->getType()))); >> + >> + case CK_NullToPointer: >> + return >> llvm::ConstantPointerNull::get(cast<llvm::PointerType>(destType)); >> + >> + case CK_IntegralCast: { >> + bool isSigned = subExpr->getType()->isSignedIntegerType(); >> + return llvm::ConstantExpr::getIntegerCast(C, destType, isSigned); >> + } >> + >> + case CK_IntegralToPointer: { >> + bool isSigned = subExpr->getType()->isSignedIntegerType(); >> + C = llvm::ConstantExpr::getIntegerCast(C, CGM.IntPtrTy, isSigned); >> + return llvm::ConstantExpr::getIntToPtr(C, destType); >> } >> + >> + case CK_IntegralToBoolean: >> + return llvm::ConstantExpr::getICmp(llvm::CmpInst::ICMP_EQ, C, >> + llvm::Constant::getNullValue(C->getType())); >> + >> + case CK_IntegralToFloating: >> + if (subExpr->getType()->isSignedIntegerType()) >> + return llvm::ConstantExpr::getSIToFP(C, destType); >> + else >> + return llvm::ConstantExpr::getUIToFP(C, destType); >> + >> + case CK_FloatingToIntegral: >> + if (E->getType()->isSignedIntegerType()) >> + return llvm::ConstantExpr::getFPToSI(C, destType); >> + else >> + return llvm::ConstantExpr::getFPToUI(C, destType); >> + >> + case CK_FloatingToBoolean: >> + return llvm::ConstantExpr::getFCmp(llvm::CmpInst::FCMP_UNE, C, >> + llvm::Constant::getNullValue(C->getType())); >> + >> + case CK_FloatingCast: >> + return llvm::ConstantExpr::getFPCast(C, destType); >> } >> } > > Here's the latest salvo in my continuing feud with GCC's -Wreturn-type: > tools/clang/lib/CodeGen/CGExprConstant.cpp: In member function > 'llvm::Constant*<unnamed>::ConstExprEmitter::VisitCastExpr(clang::CastExpr*)': > tools/clang/lib/CodeGen/CGExprConstant.cpp:621: error: control reaches > end of non-void function > > Is the new llvm_unreachable the right tool here? E.g.:
Yes, that should work. The old llvm_unreachable would have worked fine, too. John. _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
