@@ -4785,6 +4785,16 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
47854785 }
47864786
47874787 Expr *BaseExpr = E->getBase ();
4788+ bool IsInBounds = !getLangOpts ().PointerOverflowDefined ;
4789+ if (IsInBounds) {
4790+ // Check whether the underlying base pointer is a constant null.
4791+ // If so, we do not set inbounds flag for GEP to avoid breaking some
4792+ // old-style offsetof idioms.
4793+ Expr *UnderlyingBaseExpr = BaseExpr->IgnoreParens ();
4794+ while (auto *BaseMemberExpr = dyn_cast<MemberExpr>(UnderlyingBaseExpr))
4795+ UnderlyingBaseExpr = BaseMemberExpr->getBase ()->IgnoreParens ();
4796+ IsInBounds = !getContext ().isSentinelNullExpr (UnderlyingBaseExpr);
4797+ }
47884798 // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
47894799 LValue BaseLV;
47904800 if (E->isArrow ()) {
@@ -4806,7 +4816,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
48064816
48074817 NamedDecl *ND = E->getMemberDecl ();
48084818 if (auto *Field = dyn_cast<FieldDecl>(ND)) {
4809- LValue LV = EmitLValueForField (BaseLV, Field);
4819+ LValue LV = EmitLValueForField (BaseLV, Field, IsInBounds );
48104820 setObjCGCLValueClass (getContext (), E, LV);
48114821 if (getLangOpts ().OpenMP ) {
48124822 // If the member was explicitly marked as nontemporal, mark it as
@@ -4892,12 +4902,15 @@ unsigned CodeGenFunction::getDebugInfoFIndex(const RecordDecl *Rec,
48924902// / Get the address of a zero-sized field within a record. The resulting
48934903// / address doesn't necessarily have the right type.
48944904static Address emitAddrOfZeroSizeField (CodeGenFunction &CGF, Address Base,
4895- const FieldDecl *Field) {
4905+ const FieldDecl *Field,
4906+ bool IsInBounds) {
48964907 CharUnits Offset = CGF.getContext ().toCharUnitsFromBits (
48974908 CGF.getContext ().getFieldOffset (Field));
48984909 if (Offset.isZero ())
48994910 return Base;
49004911 Base = Base.withElementType (CGF.Int8Ty );
4912+ if (!IsInBounds)
4913+ return CGF.Builder .CreateConstByteGEP (Base, Offset);
49014914 return CGF.Builder .CreateConstInBoundsByteGEP (Base, Offset);
49024915}
49034916
@@ -4906,16 +4919,16 @@ static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base,
49064919// /
49074920// / The resulting address doesn't necessarily have the right type.
49084921static Address emitAddrOfFieldStorage (CodeGenFunction &CGF, Address base,
4909- const FieldDecl *field) {
4922+ const FieldDecl *field, bool IsInBounds ) {
49104923 if (isEmptyFieldForLayout (CGF.getContext (), field))
4911- return emitAddrOfZeroSizeField (CGF, base, field);
4924+ return emitAddrOfZeroSizeField (CGF, base, field, IsInBounds );
49124925
49134926 const RecordDecl *rec = field->getParent ();
49144927
49154928 unsigned idx =
49164929 CGF.CGM .getTypes ().getCGRecordLayout (rec).getLLVMFieldNo (field);
49174930
4918- if (CGF. getLangOpts (). PointerOverflowDefined )
4931+ if (!IsInBounds )
49194932 return CGF.Builder .CreateConstGEP2_32 (base, 0 , idx, field->getName ());
49204933
49214934 return CGF.Builder .CreateStructGEP (base, idx, field->getName ());
@@ -4953,8 +4966,8 @@ static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
49534966 return false ;
49544967}
49554968
4956- LValue CodeGenFunction::EmitLValueForField (LValue base,
4957- const FieldDecl *field ) {
4969+ LValue CodeGenFunction::EmitLValueForField (LValue base, const FieldDecl *field,
4970+ bool IsInBounds ) {
49584971 LValueBaseInfo BaseInfo = base.getBaseInfo ();
49594972
49604973 if (field->isBitField ()) {
@@ -5090,7 +5103,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
50905103 if (!IsInPreservedAIRegion &&
50915104 (!getDebugInfo () || !rec->hasAttr <BPFPreserveAccessIndexAttr>()))
50925105 // For structs, we GEP to the field that the record layout suggests.
5093- addr = emitAddrOfFieldStorage (*this , addr, field);
5106+ addr = emitAddrOfFieldStorage (*this , addr, field, IsInBounds );
50945107 else
50955108 // Remember the original struct field index
50965109 addr = emitPreserveStructAccess (*this , base, addr, field);
@@ -5134,7 +5147,9 @@ CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
51345147 if (!FieldType->isReferenceType ())
51355148 return EmitLValueForField (Base, Field);
51365149
5137- Address V = emitAddrOfFieldStorage (*this , Base.getAddress (), Field);
5150+ Address V = emitAddrOfFieldStorage (
5151+ *this , Base.getAddress (), Field,
5152+ /* IsInBounds=*/ !getLangOpts ().PointerOverflowDefined );
51385153
51395154 // Make sure that the address is pointing to the right type.
51405155 llvm::Type *llvmType = ConvertTypeForMem (FieldType);
0 commit comments