@@ -4778,6 +4778,10 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
47784778 }
47794779
47804780 Expr *BaseExpr = E->getBase ();
4781+ Expr *UnderlyingBaseExpr = BaseExpr;
4782+ while (auto *BaseMemberExpr = dyn_cast<MemberExpr>(UnderlyingBaseExpr))
4783+ UnderlyingBaseExpr = BaseMemberExpr->getBase ();
4784+ bool IsBaseConstantNull = getContext ().isSentinelNullExpr (UnderlyingBaseExpr);
47814785 // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
47824786 LValue BaseLV;
47834787 if (E->isArrow ()) {
@@ -4799,7 +4803,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
47994803
48004804 NamedDecl *ND = E->getMemberDecl ();
48014805 if (auto *Field = dyn_cast<FieldDecl>(ND)) {
4802- LValue LV = EmitLValueForField (BaseLV, Field);
4806+ LValue LV = EmitLValueForField (BaseLV, Field, IsBaseConstantNull );
48034807 setObjCGCLValueClass (getContext (), E, LV);
48044808 if (getLangOpts ().OpenMP ) {
48054809 // If the member was explicitly marked as nontemporal, mark it as
@@ -4885,12 +4889,15 @@ unsigned CodeGenFunction::getDebugInfoFIndex(const RecordDecl *Rec,
48854889// / Get the address of a zero-sized field within a record. The resulting
48864890// / address doesn't necessarily have the right type.
48874891static Address emitAddrOfZeroSizeField (CodeGenFunction &CGF, Address Base,
4888- const FieldDecl *Field) {
4892+ const FieldDecl *Field,
4893+ bool IsBaseConstantNull) {
48894894 CharUnits Offset = CGF.getContext ().toCharUnitsFromBits (
48904895 CGF.getContext ().getFieldOffset (Field));
48914896 if (Offset.isZero ())
48924897 return Base;
48934898 Base = Base.withElementType (CGF.Int8Ty );
4899+ if (IsBaseConstantNull)
4900+ return CGF.Builder .CreateConstByteGEP (Base, Offset);
48944901 return CGF.Builder .CreateConstInBoundsByteGEP (Base, Offset);
48954902}
48964903
@@ -4899,15 +4906,18 @@ static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base,
48994906// /
49004907// / The resulting address doesn't necessarily have the right type.
49014908static Address emitAddrOfFieldStorage (CodeGenFunction &CGF, Address base,
4902- const FieldDecl *field) {
4909+ const FieldDecl *field,
4910+ bool IsBaseConstantNull) {
49034911 if (isEmptyFieldForLayout (CGF.getContext (), field))
4904- return emitAddrOfZeroSizeField (CGF, base, field);
4912+ return emitAddrOfZeroSizeField (CGF, base, field, IsBaseConstantNull );
49054913
49064914 const RecordDecl *rec = field->getParent ();
49074915
49084916 unsigned idx =
49094917 CGF.CGM .getTypes ().getCGRecordLayout (rec).getLLVMFieldNo (field);
49104918
4919+ if (IsBaseConstantNull)
4920+ return CGF.Builder .CreateConstGEP (base, idx, field->getName ());
49114921 return CGF.Builder .CreateStructGEP (base, idx, field->getName ());
49124922}
49134923
@@ -4943,8 +4953,8 @@ static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
49434953 return false ;
49444954}
49454955
4946- LValue CodeGenFunction::EmitLValueForField (LValue base,
4947- const FieldDecl *field ) {
4956+ LValue CodeGenFunction::EmitLValueForField (LValue base, const FieldDecl *field,
4957+ bool IsBaseConstantNull ) {
49484958 LValueBaseInfo BaseInfo = base.getBaseInfo ();
49494959
49504960 if (field->isBitField ()) {
@@ -5076,7 +5086,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
50765086 if (!IsInPreservedAIRegion &&
50775087 (!getDebugInfo () || !rec->hasAttr <BPFPreserveAccessIndexAttr>()))
50785088 // For structs, we GEP to the field that the record layout suggests.
5079- addr = emitAddrOfFieldStorage (*this , addr, field);
5089+ addr = emitAddrOfFieldStorage (*this , addr, field, IsBaseConstantNull );
50805090 else
50815091 // Remember the original struct field index
50825092 addr = emitPreserveStructAccess (*this , base, addr, field);
@@ -5120,7 +5130,8 @@ CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
51205130 if (!FieldType->isReferenceType ())
51215131 return EmitLValueForField (Base, Field);
51225132
5123- Address V = emitAddrOfFieldStorage (*this , Base.getAddress (), Field);
5133+ Address V = emitAddrOfFieldStorage (*this , Base.getAddress (), Field,
5134+ /* IsBaseConstantNull=*/ false );
51245135
51255136 // Make sure that the address is pointing to the right type.
51265137 llvm::Type *llvmType = ConvertTypeForMem (FieldType);
0 commit comments