@@ -4785,6 +4785,16 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
4785
4785
}
4786
4786
4787
4787
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
+ }
4788
4798
// If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
4789
4799
LValue BaseLV;
4790
4800
if (E->isArrow ()) {
@@ -4806,7 +4816,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
4806
4816
4807
4817
NamedDecl *ND = E->getMemberDecl ();
4808
4818
if (auto *Field = dyn_cast<FieldDecl>(ND)) {
4809
- LValue LV = EmitLValueForField (BaseLV, Field);
4819
+ LValue LV = EmitLValueForField (BaseLV, Field, IsInBounds );
4810
4820
setObjCGCLValueClass (getContext (), E, LV);
4811
4821
if (getLangOpts ().OpenMP ) {
4812
4822
// If the member was explicitly marked as nontemporal, mark it as
@@ -4892,12 +4902,15 @@ unsigned CodeGenFunction::getDebugInfoFIndex(const RecordDecl *Rec,
4892
4902
// / Get the address of a zero-sized field within a record. The resulting
4893
4903
// / address doesn't necessarily have the right type.
4894
4904
static Address emitAddrOfZeroSizeField (CodeGenFunction &CGF, Address Base,
4895
- const FieldDecl *Field) {
4905
+ const FieldDecl *Field,
4906
+ bool IsInBounds) {
4896
4907
CharUnits Offset = CGF.getContext ().toCharUnitsFromBits (
4897
4908
CGF.getContext ().getFieldOffset (Field));
4898
4909
if (Offset.isZero ())
4899
4910
return Base;
4900
4911
Base = Base.withElementType (CGF.Int8Ty );
4912
+ if (!IsInBounds)
4913
+ return CGF.Builder .CreateConstByteGEP (Base, Offset);
4901
4914
return CGF.Builder .CreateConstInBoundsByteGEP (Base, Offset);
4902
4915
}
4903
4916
@@ -4906,16 +4919,16 @@ static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base,
4906
4919
// /
4907
4920
// / The resulting address doesn't necessarily have the right type.
4908
4921
static Address emitAddrOfFieldStorage (CodeGenFunction &CGF, Address base,
4909
- const FieldDecl *field) {
4922
+ const FieldDecl *field, bool IsInBounds ) {
4910
4923
if (isEmptyFieldForLayout (CGF.getContext (), field))
4911
- return emitAddrOfZeroSizeField (CGF, base, field);
4924
+ return emitAddrOfZeroSizeField (CGF, base, field, IsInBounds );
4912
4925
4913
4926
const RecordDecl *rec = field->getParent ();
4914
4927
4915
4928
unsigned idx =
4916
4929
CGF.CGM .getTypes ().getCGRecordLayout (rec).getLLVMFieldNo (field);
4917
4930
4918
- if (CGF. getLangOpts (). PointerOverflowDefined )
4931
+ if (!IsInBounds )
4919
4932
return CGF.Builder .CreateConstGEP2_32 (base, 0 , idx, field->getName ());
4920
4933
4921
4934
return CGF.Builder .CreateStructGEP (base, idx, field->getName ());
@@ -4953,8 +4966,8 @@ static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
4953
4966
return false ;
4954
4967
}
4955
4968
4956
- LValue CodeGenFunction::EmitLValueForField (LValue base,
4957
- const FieldDecl *field ) {
4969
+ LValue CodeGenFunction::EmitLValueForField (LValue base, const FieldDecl *field,
4970
+ bool IsInBounds ) {
4958
4971
LValueBaseInfo BaseInfo = base.getBaseInfo ();
4959
4972
4960
4973
if (field->isBitField ()) {
@@ -5090,7 +5103,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
5090
5103
if (!IsInPreservedAIRegion &&
5091
5104
(!getDebugInfo () || !rec->hasAttr <BPFPreserveAccessIndexAttr>()))
5092
5105
// 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 );
5094
5107
else
5095
5108
// Remember the original struct field index
5096
5109
addr = emitPreserveStructAccess (*this , base, addr, field);
@@ -5134,7 +5147,9 @@ CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
5134
5147
if (!FieldType->isReferenceType ())
5135
5148
return EmitLValueForField (Base, Field);
5136
5149
5137
- Address V = emitAddrOfFieldStorage (*this , Base.getAddress (), Field);
5150
+ Address V = emitAddrOfFieldStorage (
5151
+ *this , Base.getAddress (), Field,
5152
+ /* IsInBounds=*/ !getLangOpts ().PointerOverflowDefined );
5138
5153
5139
5154
// Make sure that the address is pointing to the right type.
5140
5155
llvm::Type *llvmType = ConvertTypeForMem (FieldType);
0 commit comments