Skip to content

Commit ac82955

Browse files
authored
[Clang][CodeGen] Move EmitPointerArithmetic into CodeGenFunction. NFC. (#152634)
`CodeGenFunction::EmitPointerArithmetic` is needed by llvm/llvm-project#152575. Separate the NFC changes into a new PR for smooth review.
1 parent 26b302f commit ac82955

File tree

2 files changed

+63
-53
lines changed

2 files changed

+63
-53
lines changed

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4183,9 +4183,8 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
41834183
return phi;
41844184
}
41854185

4186-
/// Emit pointer + index arithmetic.
4187-
static Value *emitPointerArithmetic(CodeGenFunction &CGF,
4188-
const BinOpInfo &op,
4186+
/// This function is used for BO_Add/BO_Sub/BO_AddAssign/BO_SubAssign.
4187+
static Value *emitPointerArithmetic(CodeGenFunction &CGF, const BinOpInfo &op,
41894188
bool isSubtraction) {
41904189
// Must have binary (not unary) expr here. Unary pointer
41914190
// increment/decrement doesn't use this path.
@@ -4202,11 +4201,19 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
42024201
std::swap(pointerOperand, indexOperand);
42034202
}
42044203

4204+
return CGF.EmitPointerArithmetic(expr, pointerOperand, pointer, indexOperand,
4205+
index, isSubtraction);
4206+
}
4207+
4208+
/// Emit pointer + index arithmetic.
4209+
llvm::Value *CodeGenFunction::EmitPointerArithmetic(
4210+
const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer,
4211+
Expr *indexOperand, llvm::Value *index, bool isSubtraction) {
42054212
bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType();
42064213

42074214
unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
4208-
auto &DL = CGF.CGM.getDataLayout();
4209-
auto PtrTy = cast<llvm::PointerType>(pointer->getType());
4215+
auto &DL = CGM.getDataLayout();
4216+
auto *PtrTy = cast<llvm::PointerType>(pointer->getType());
42104217

42114218
// Some versions of glibc and gcc use idioms (particularly in their malloc
42124219
// routines) that add a pointer-sized integer (known to be a pointer value)
@@ -4227,79 +4234,77 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
42274234
//
42284235
// Note that we do not suppress the pointer overflow check in this case.
42294236
if (BinaryOperator::isNullPointerArithmeticExtension(
4230-
CGF.getContext(), op.Opcode, expr->getLHS(), expr->getRHS())) {
4231-
Value *Ptr = CGF.Builder.CreateIntToPtr(index, pointer->getType());
4232-
if (CGF.getLangOpts().PointerOverflowDefined ||
4233-
!CGF.SanOpts.has(SanitizerKind::PointerOverflow) ||
4234-
NullPointerIsDefined(CGF.Builder.GetInsertBlock()->getParent(),
4237+
getContext(), BO->getOpcode(), pointerOperand, indexOperand)) {
4238+
llvm::Value *Ptr = Builder.CreateIntToPtr(index, pointer->getType());
4239+
if (getLangOpts().PointerOverflowDefined ||
4240+
!SanOpts.has(SanitizerKind::PointerOverflow) ||
4241+
NullPointerIsDefined(Builder.GetInsertBlock()->getParent(),
42354242
PtrTy->getPointerAddressSpace()))
42364243
return Ptr;
42374244
// The inbounds GEP of null is valid iff the index is zero.
42384245
auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
42394246
auto CheckHandler = SanitizerHandler::PointerOverflow;
4240-
SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
4241-
Value *IsZeroIndex = CGF.Builder.CreateIsNull(index);
4242-
llvm::Constant *StaticArgs[] = {
4243-
CGF.EmitCheckSourceLocation(op.E->getExprLoc())};
4247+
SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
4248+
llvm::Value *IsZeroIndex = Builder.CreateIsNull(index);
4249+
llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(BO->getExprLoc())};
42444250
llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
4245-
Value *IntPtr = llvm::Constant::getNullValue(IntPtrTy);
4246-
Value *ComputedGEP = CGF.Builder.CreateZExtOrTrunc(index, IntPtrTy);
4247-
Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4248-
CGF.EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4249-
DynamicArgs);
4251+
llvm::Value *IntPtr = llvm::Constant::getNullValue(IntPtrTy);
4252+
llvm::Value *ComputedGEP = Builder.CreateZExtOrTrunc(index, IntPtrTy);
4253+
llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4254+
EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4255+
DynamicArgs);
42504256
return Ptr;
42514257
}
42524258

42534259
if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
42544260
// Zero-extend or sign-extend the pointer value according to
42554261
// whether the index is signed or not.
4256-
index = CGF.Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
4257-
"idx.ext");
4262+
index = Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
4263+
"idx.ext");
42584264
}
42594265

42604266
// If this is subtraction, negate the index.
42614267
if (isSubtraction)
4262-
index = CGF.Builder.CreateNeg(index, "idx.neg");
4268+
index = Builder.CreateNeg(index, "idx.neg");
42634269

4264-
if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
4265-
CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(),
4266-
/*Accessed*/ false);
4270+
if (SanOpts.has(SanitizerKind::ArrayBounds))
4271+
EmitBoundsCheck(BO, pointerOperand, index, indexOperand->getType(),
4272+
/*Accessed*/ false);
42674273

4268-
const PointerType *pointerType
4269-
= pointerOperand->getType()->getAs<PointerType>();
4274+
const PointerType *pointerType =
4275+
pointerOperand->getType()->getAs<PointerType>();
42704276
if (!pointerType) {
42714277
QualType objectType = pointerOperand->getType()
4272-
->castAs<ObjCObjectPointerType>()
4273-
->getPointeeType();
4274-
llvm::Value *objectSize
4275-
= CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(objectType));
4278+
->castAs<ObjCObjectPointerType>()
4279+
->getPointeeType();
4280+
llvm::Value *objectSize =
4281+
CGM.getSize(getContext().getTypeSizeInChars(objectType));
42764282

4277-
index = CGF.Builder.CreateMul(index, objectSize);
4283+
index = Builder.CreateMul(index, objectSize);
42784284

4279-
Value *result =
4280-
CGF.Builder.CreateGEP(CGF.Int8Ty, pointer, index, "add.ptr");
4281-
return CGF.Builder.CreateBitCast(result, pointer->getType());
4285+
llvm::Value *result = Builder.CreateGEP(Int8Ty, pointer, index, "add.ptr");
4286+
return Builder.CreateBitCast(result, pointer->getType());
42824287
}
42834288

42844289
QualType elementType = pointerType->getPointeeType();
4285-
if (const VariableArrayType *vla
4286-
= CGF.getContext().getAsVariableArrayType(elementType)) {
4290+
if (const VariableArrayType *vla =
4291+
getContext().getAsVariableArrayType(elementType)) {
42874292
// The element count here is the total number of non-VLA elements.
4288-
llvm::Value *numElements = CGF.getVLASize(vla).NumElts;
4293+
llvm::Value *numElements = getVLASize(vla).NumElts;
42894294

42904295
// Effectively, the multiply by the VLA size is part of the GEP.
42914296
// GEP indexes are signed, and scaling an index isn't permitted to
42924297
// signed-overflow, so we use the same semantics for our explicit
42934298
// multiply. We suppress this if overflow is not undefined behavior.
4294-
llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
4295-
if (CGF.getLangOpts().PointerOverflowDefined) {
4296-
index = CGF.Builder.CreateMul(index, numElements, "vla.index");
4297-
pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
4299+
llvm::Type *elemTy = ConvertTypeForMem(vla->getElementType());
4300+
if (getLangOpts().PointerOverflowDefined) {
4301+
index = Builder.CreateMul(index, numElements, "vla.index");
4302+
pointer = Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
42984303
} else {
4299-
index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index");
4300-
pointer = CGF.EmitCheckedInBoundsGEP(
4301-
elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4302-
"add.ptr");
4304+
index = Builder.CreateNSWMul(index, numElements, "vla.index");
4305+
pointer =
4306+
EmitCheckedInBoundsGEP(elemTy, pointer, index, isSigned,
4307+
isSubtraction, BO->getExprLoc(), "add.ptr");
43034308
}
43044309
return pointer;
43054310
}
@@ -4309,16 +4314,15 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
43094314
// future proof.
43104315
llvm::Type *elemTy;
43114316
if (elementType->isVoidType() || elementType->isFunctionType())
4312-
elemTy = CGF.Int8Ty;
4317+
elemTy = Int8Ty;
43134318
else
4314-
elemTy = CGF.ConvertTypeForMem(elementType);
4319+
elemTy = ConvertTypeForMem(elementType);
43154320

4316-
if (CGF.getLangOpts().PointerOverflowDefined)
4317-
return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
4321+
if (getLangOpts().PointerOverflowDefined)
4322+
return Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
43184323

4319-
return CGF.EmitCheckedInBoundsGEP(
4320-
elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4321-
"add.ptr");
4324+
return EmitCheckedInBoundsGEP(elemTy, pointer, index, isSigned, isSubtraction,
4325+
BO->getExprLoc(), "add.ptr");
43224326
}
43234327

43244328
// Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5212,6 +5212,12 @@ class CodeGenFunction : public CodeGenTypeCache {
52125212
/// operation is a subtraction.
52135213
enum { NotSubtraction = false, IsSubtraction = true };
52145214

5215+
/// Emit pointer + index arithmetic.
5216+
llvm::Value *EmitPointerArithmetic(const BinaryOperator *BO,
5217+
Expr *pointerOperand, llvm::Value *pointer,
5218+
Expr *indexOperand, llvm::Value *index,
5219+
bool isSubtraction);
5220+
52155221
/// Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to
52165222
/// detect undefined behavior when the pointer overflow sanitizer is enabled.
52175223
/// \p SignedIndices indicates whether any of the GEP indices are signed.

0 commit comments

Comments
 (0)