Index: cfe/trunk/lib/CodeGen/CGBlocks.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGBlocks.cpp +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp @@ -1189,8 +1189,8 @@ variable->getName()); } - if (auto refType = capture.fieldType()->getAs()) - addr = EmitLoadOfReference(addr, refType); + if (capture.fieldType()->isReferenceType()) + addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.fieldType())); return addr; } Index: cfe/trunk/lib/CodeGen/CGExpr.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -2160,22 +2160,30 @@ return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); } -Address CodeGenFunction::EmitLoadOfReference(Address Addr, - const ReferenceType *RefTy, - LValueBaseInfo *BaseInfo, - TBAAAccessInfo *TBAAInfo) { - llvm::Value *Ptr = Builder.CreateLoad(Addr); - return Address(Ptr, getNaturalTypeAlignment(RefTy->getPointeeType(), - BaseInfo, TBAAInfo, - /* forPointeeType= */ true)); -} - -LValue CodeGenFunction::EmitLoadOfReferenceLValue(Address RefAddr, - const ReferenceType *RefTy) { - LValueBaseInfo BaseInfo; - TBAAAccessInfo TBAAInfo; - Address Addr = EmitLoadOfReference(RefAddr, RefTy, &BaseInfo, &TBAAInfo); - return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo, TBAAInfo); +Address +CodeGenFunction::EmitLoadOfReference(LValue RefLVal, + LValueBaseInfo *PointeeBaseInfo, + TBAAAccessInfo *PointeeTBAAInfo) { + llvm::LoadInst *Load = Builder.CreateLoad(RefLVal.getAddress(), + RefLVal.isVolatile()); + TBAAAccessInfo RefTBAAInfo = RefLVal.getTBAAInfo(); + if (RefLVal.getBaseInfo().getMayAlias()) + RefTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + CGM.DecorateInstructionWithTBAA(Load, RefTBAAInfo); + + CharUnits Align = getNaturalTypeAlignment(RefLVal.getType()->getPointeeType(), + PointeeBaseInfo, PointeeTBAAInfo, + /* forPointeeType= */ true); + return Address(Load, Align); +} + +LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) { + LValueBaseInfo PointeeBaseInfo; + TBAAAccessInfo PointeeTBAAInfo; + Address PointeeAddr = EmitLoadOfReference(RefLVal, &PointeeBaseInfo, + &PointeeTBAAInfo); + return MakeAddrLValue(PointeeAddr, RefLVal.getType()->getPointeeType(), + PointeeBaseInfo, PointeeTBAAInfo); } Address CodeGenFunction::EmitLoadOfPointer(Address Ptr, @@ -2210,17 +2218,15 @@ V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy); CharUnits Alignment = CGF.getContext().getDeclAlign(VD); Address Addr(V, Alignment); - LValue LV; // Emit reference to the private copy of the variable if it is an OpenMP // threadprivate variable. if (CGF.getLangOpts().OpenMP && VD->hasAttr()) return EmitThreadPrivateVarDeclLValue(CGF, VD, T, Addr, RealVarTy, E->getExprLoc()); - if (auto RefTy = VD->getType()->getAs()) { - LV = CGF.EmitLoadOfReferenceLValue(Addr, RefTy); - } else { - LV = CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); - } + LValue LV = VD->getType()->isReferenceType() ? + CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(), + AlignmentSource::Decl) : + CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); setObjCGCLValueClass(CGF.getContext(), E, LV); return LV; } @@ -2338,8 +2344,9 @@ else if (CapturedStmtInfo) { auto I = LocalDeclMap.find(VD); if (I != LocalDeclMap.end()) { - if (auto RefTy = VD->getType()->getAs()) - return EmitLoadOfReferenceLValue(I->second, RefTy); + if (VD->getType()->isReferenceType()) + return EmitLoadOfReferenceLValue(I->second, VD->getType(), + AlignmentSource::Decl); return MakeAddrLValue(I->second, T); } LValue CapLVal = @@ -2410,12 +2417,9 @@ } // Drill into reference types. - LValue LV; - if (auto RefTy = VD->getType()->getAs()) { - LV = EmitLoadOfReferenceLValue(addr, RefTy); - } else { - LV = MakeAddrLValue(addr, T, AlignmentSource::Decl); - } + LValue LV = VD->getType()->isReferenceType() ? + EmitLoadOfReferenceLValue(addr, VD->getType(), AlignmentSource::Decl) : + MakeAddrLValue(addr, T, AlignmentSource::Decl); bool isLocalStorage = VD->hasLocalStorage(); @@ -3748,7 +3752,7 @@ } Address addr = base.getAddress(); - unsigned cvr = base.getVRQualifiers(); + unsigned RecordCVR = base.getVRQualifiers(); if (rec->isUnion()) { // For unions, there is no pointer adjustment. assert(!FieldType->isReferenceType() && "union has reference member"); @@ -3763,22 +3767,16 @@ addr = emitAddrOfFieldStorage(*this, addr, field); // If this is a reference field, load the reference right now. - if (const ReferenceType *refType = FieldType->getAs()) { - llvm::LoadInst *load = Builder.CreateLoad(addr, "ref"); - if (cvr & Qualifiers::Volatile) load->setVolatile(true); - - CGM.DecorateInstructionWithTBAA(load, FieldTBAAInfo); - - FieldType = refType->getPointeeType(); - CharUnits Align = getNaturalTypeAlignment(FieldType, &FieldBaseInfo, - &FieldTBAAInfo, - /* forPointeeType= */ true); - addr = Address(load, Align); - - // Qualifiers on the struct don't apply to the referencee, and - // we'll pick up CVR from the actual type later, so reset these - // additional qualifiers now. - cvr = 0; + if (FieldType->isReferenceType()) { + LValue RefLVal = MakeAddrLValue(addr, FieldType, FieldBaseInfo, + FieldTBAAInfo); + if (RecordCVR & Qualifiers::Volatile) + RefLVal.getQuals().setVolatile(true); + addr = EmitLoadOfReference(RefLVal, &FieldBaseInfo, &FieldTBAAInfo); + + // Qualifiers on the struct don't apply to the referencee. + RecordCVR = 0; + FieldType = FieldType->getPointeeType(); } } @@ -3793,7 +3791,7 @@ addr = EmitFieldAnnotations(field, addr); LValue LV = MakeAddrLValue(addr, FieldType, FieldBaseInfo, FieldTBAAInfo); - LV.getQuals().addCVRQualifiers(cvr); + LV.getQuals().addCVRQualifiers(RecordCVR); // __weak attribute on a field is ignored. if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak) Index: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1037,8 +1037,8 @@ if (auto *PtrTy = BaseTy->getAs()) BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy); else { - BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(), - BaseTy->castAs()); + LValue RefLVal = CGF.MakeAddrLValue(BaseLV.getAddress(), BaseTy); + BaseLV = CGF.EmitLoadOfReferenceLValue(RefLVal); } BaseTy = BaseTy->getPointeeType(); } Index: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp @@ -417,8 +417,7 @@ Address ArgAddr = ArgLVal.getAddress(); if (!VarTy->isReferenceType()) { if (ArgLVal.getType()->isLValueReferenceType()) { - ArgAddr = CGF.EmitLoadOfReference( - ArgAddr, ArgLVal.getType()->castAs()); + ArgAddr = CGF.EmitLoadOfReference(ArgLVal); } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) { assert(ArgLVal.getType()->isPointerType()); ArgAddr = CGF.EmitLoadOfPointer( Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -1952,10 +1952,17 @@ LValueBaseInfo *BaseInfo = nullptr, TBAAAccessInfo *TBAAInfo = nullptr); - Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, - LValueBaseInfo *BaseInfo = nullptr, - TBAAAccessInfo *TBAAInfo = nullptr); - LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); + Address EmitLoadOfReference(LValue RefLVal, + LValueBaseInfo *PointeeBaseInfo = nullptr, + TBAAAccessInfo *PointeeTBAAInfo = nullptr); + LValue EmitLoadOfReferenceLValue(LValue RefLVal); + LValue EmitLoadOfReferenceLValue(Address RefAddr, QualType RefTy, + AlignmentSource Source = + AlignmentSource::Type) { + LValue RefLVal = MakeAddrLValue(RefAddr, RefTy, LValueBaseInfo(Source), + CGM.getTBAAAccessInfo(RefTy)); + return EmitLoadOfReferenceLValue(RefLVal); + } Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, LValueBaseInfo *BaseInfo = nullptr, Index: cfe/trunk/test/CodeGen/tbaa-reference.cpp =================================================================== --- cfe/trunk/test/CodeGen/tbaa-reference.cpp +++ cfe/trunk/test/CodeGen/tbaa-reference.cpp @@ -6,24 +6,32 @@ struct B { S &s; - B(S &s) : s(s) {} - void bar(); + B(S &s); + S &get(); }; -void foo(S &s) { - B b(s); - b.bar(); -} - -// CHECK-LABEL: _Z3fooR1S -// Check initialization of the reference parameter in foo(). -// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer:!.*]] -// +B::B(S &s) : s(s) { // CHECK-LABEL: _ZN1BC2ER1S -// TODO: Check loading of the reference parameter in B::B(S&). -// Check initialization of B::s in B::B(S&). +// Check initialization of the reference parameter. +// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer:!.*]] + +// Check loading of the reference parameter. +// CHECK: load %struct.S*, %struct.S** {{.*}}, !tbaa [[TAG_pointer]] + +// Check initialization of the reference member. // CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer]] -// +} + +S &B::get() { +// CHECK-LABEL: _ZN1B3getEv +// Check that we access the reference as a structure member. +// CHECK: load %struct.S*, %struct.S** {{.*}}, !tbaa [[TAG_B_s:!.*]] + return s; +} + // CHECK-DAG: [[TAG_pointer]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0} +// CHECK-DAG: [[TAG_B_s]] = !{[[TYPE_B:!.*]], [[TYPE_pointer]], i64 0} +// +// CHECK-DAG: [[TYPE_B]] = !{!"_ZTS1B", [[TYPE_pointer]], i64 0} // CHECK-DAG: [[TYPE_pointer]] = !{!"any pointer", [[TYPE_char:!.*]], i64 0} // CHECK-DAG: [[TYPE_char]] = !{!"omnipotent char", {{!.*}}, i64 0}