change EmitLValueForField to cast the returned lvalue to the right
type, even when in the struct case. This was one root issue that was
causing type mismatches throughout the compiler.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134862 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index c7a104e..b974633 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -247,6 +247,7 @@
RV = CGF.EmitLoadOfPropertyRefLValue(LV);
return RV.getScalarVal();
}
+
if (LV.isSimple())
return LV.getAddress();
@@ -460,9 +461,7 @@
else {
switch (ObjCARCReferenceLifetimeType.getObjCLifetime()) {
case Qualifiers::OCL_None:
- llvm_unreachable("Not a reference temporary that needs to be deallocated");
- break;
-
+ assert(0 && "Not a reference temporary that needs to be deallocated");
case Qualifiers::OCL_ExplicitNone:
case Qualifiers::OCL_Autoreleasing:
// Nothing to do.
@@ -769,6 +768,7 @@
llvm::MDNode *TBAAInfo) {
Value = EmitToMemory(Value, Ty);
+ // If this is a pointer r-value, make sure that it has the right scalar type.
if (isa<llvm::PointerType>(Value->getType())) {
llvm::Type *EltTy =
cast<llvm::PointerType>(Addr->getType())->getElementType();
@@ -1295,13 +1295,14 @@
if (VD->getType()->isReferenceType())
V = CGF.Builder.CreateLoad(V, "tmp");
unsigned Alignment = CGF.getContext().getDeclAlign(VD).getQuantity();
+
LValue LV = CGF.MakeAddrLValue(V, E->getType(), Alignment);
setObjCGCLValueClass(CGF.getContext(), E, LV);
return LV;
}
static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
- const Expr *E, const FunctionDecl *FD) {
+ const Expr *E, const FunctionDecl *FD) {
llvm::Value *V = CGF.CGM.GetAddrOfFunction(FD);
if (!FD->hasPrototype()) {
if (const FunctionProtoType *Proto =
@@ -1813,20 +1814,14 @@
bool mayAlias = rec->hasAttr<MayAliasAttr>();
- llvm::Value *addr;
+ llvm::Value *addr = baseAddr;
if (rec->isUnion()) {
- // For unions, we just cast to the appropriate type.
+ // For unions, there is no pointer adjustment.
assert(!type->isReferenceType() && "union has reference member");
-
- const llvm::Type *llvmType = CGM.getTypes().ConvertTypeForMem(type);
- unsigned AS =
- cast<llvm::PointerType>(baseAddr->getType())->getAddressSpace();
- addr = Builder.CreateBitCast(baseAddr, llvmType->getPointerTo(AS),
- field->getName());
} else {
// For structs, we GEP to the field that the record layout suggests.
unsigned idx = CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
- addr = Builder.CreateStructGEP(baseAddr, idx, field->getName());
+ addr = Builder.CreateStructGEP(addr, idx, field->getName());
// If this is a reference field, load the reference right now.
if (const ReferenceType *refType = type->getAs<ReferenceType>()) {
@@ -1848,6 +1843,16 @@
cvr = 0; // qualifiers don't recursively apply to referencee
}
}
+
+ // Make sure that the address is pointing to the right type. This is critical
+ // for both unions and structs. A union needs a bitcast, a struct element
+ // will need a bitcast if the LLVM type laid out doesn't match the desired
+ // type.
+ const llvm::Type *llvmType = CGM.getTypes().ConvertTypeForMem(type);
+ unsigned AS = cast<llvm::PointerType>(baseAddr->getType())->getAddressSpace();
+ addr = Builder.CreateBitCast(addr, llvmType->getPointerTo(AS),
+ field->getName());
+
unsigned alignment = getContext().getDeclAlign(field).getQuantity();
LValue LV = MakeAddrLValue(addr, type, alignment);