diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 110 |
1 files changed, 57 insertions, 53 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 44931d0..7eed4ee 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -4183,9 +4183,8 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { return phi; } -/// Emit pointer + index arithmetic. -static Value *emitPointerArithmetic(CodeGenFunction &CGF, - const BinOpInfo &op, +/// This function is used for BO_Add/BO_Sub/BO_AddAssign/BO_SubAssign. +static Value *emitPointerArithmetic(CodeGenFunction &CGF, const BinOpInfo &op, bool isSubtraction) { // Must have binary (not unary) expr here. Unary pointer // increment/decrement doesn't use this path. @@ -4202,11 +4201,19 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, std::swap(pointerOperand, indexOperand); } + return CGF.EmitPointerArithmetic(expr, pointerOperand, pointer, indexOperand, + index, isSubtraction); +} + +/// Emit pointer + index arithmetic. +llvm::Value *CodeGenFunction::EmitPointerArithmetic( + const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer, + Expr *indexOperand, llvm::Value *index, bool isSubtraction) { bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType(); unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth(); - auto &DL = CGF.CGM.getDataLayout(); - auto PtrTy = cast<llvm::PointerType>(pointer->getType()); + auto &DL = CGM.getDataLayout(); + auto *PtrTy = cast<llvm::PointerType>(pointer->getType()); // Some versions of glibc and gcc use idioms (particularly in their malloc // routines) that add a pointer-sized integer (known to be a pointer value) @@ -4227,79 +4234,77 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, // // Note that we do not suppress the pointer overflow check in this case. if (BinaryOperator::isNullPointerArithmeticExtension( - CGF.getContext(), op.Opcode, expr->getLHS(), expr->getRHS())) { - Value *Ptr = CGF.Builder.CreateIntToPtr(index, pointer->getType()); - if (CGF.getLangOpts().PointerOverflowDefined || - !CGF.SanOpts.has(SanitizerKind::PointerOverflow) || - NullPointerIsDefined(CGF.Builder.GetInsertBlock()->getParent(), + getContext(), BO->getOpcode(), pointerOperand, indexOperand)) { + llvm::Value *Ptr = Builder.CreateIntToPtr(index, pointer->getType()); + if (getLangOpts().PointerOverflowDefined || + !SanOpts.has(SanitizerKind::PointerOverflow) || + NullPointerIsDefined(Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace())) return Ptr; // The inbounds GEP of null is valid iff the index is zero. auto CheckOrdinal = SanitizerKind::SO_PointerOverflow; auto CheckHandler = SanitizerHandler::PointerOverflow; - SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler); - Value *IsZeroIndex = CGF.Builder.CreateIsNull(index); - llvm::Constant *StaticArgs[] = { - CGF.EmitCheckSourceLocation(op.E->getExprLoc())}; + SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler); + llvm::Value *IsZeroIndex = Builder.CreateIsNull(index); + llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(BO->getExprLoc())}; llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy); - Value *IntPtr = llvm::Constant::getNullValue(IntPtrTy); - Value *ComputedGEP = CGF.Builder.CreateZExtOrTrunc(index, IntPtrTy); - Value *DynamicArgs[] = {IntPtr, ComputedGEP}; - CGF.EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs, - DynamicArgs); + llvm::Value *IntPtr = llvm::Constant::getNullValue(IntPtrTy); + llvm::Value *ComputedGEP = Builder.CreateZExtOrTrunc(index, IntPtrTy); + llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP}; + EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs, + DynamicArgs); return Ptr; } if (width != DL.getIndexTypeSizeInBits(PtrTy)) { // Zero-extend or sign-extend the pointer value according to // whether the index is signed or not. - index = CGF.Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned, - "idx.ext"); + index = Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned, + "idx.ext"); } // If this is subtraction, negate the index. if (isSubtraction) - index = CGF.Builder.CreateNeg(index, "idx.neg"); + index = Builder.CreateNeg(index, "idx.neg"); - if (CGF.SanOpts.has(SanitizerKind::ArrayBounds)) - CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(), - /*Accessed*/ false); + if (SanOpts.has(SanitizerKind::ArrayBounds)) + EmitBoundsCheck(BO, pointerOperand, index, indexOperand->getType(), + /*Accessed*/ false); - const PointerType *pointerType - = pointerOperand->getType()->getAs<PointerType>(); + const PointerType *pointerType = + pointerOperand->getType()->getAs<PointerType>(); if (!pointerType) { QualType objectType = pointerOperand->getType() - ->castAs<ObjCObjectPointerType>() - ->getPointeeType(); - llvm::Value *objectSize - = CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(objectType)); + ->castAs<ObjCObjectPointerType>() + ->getPointeeType(); + llvm::Value *objectSize = + CGM.getSize(getContext().getTypeSizeInChars(objectType)); - index = CGF.Builder.CreateMul(index, objectSize); + index = Builder.CreateMul(index, objectSize); - Value *result = - CGF.Builder.CreateGEP(CGF.Int8Ty, pointer, index, "add.ptr"); - return CGF.Builder.CreateBitCast(result, pointer->getType()); + llvm::Value *result = Builder.CreateGEP(Int8Ty, pointer, index, "add.ptr"); + return Builder.CreateBitCast(result, pointer->getType()); } QualType elementType = pointerType->getPointeeType(); - if (const VariableArrayType *vla - = CGF.getContext().getAsVariableArrayType(elementType)) { + if (const VariableArrayType *vla = + getContext().getAsVariableArrayType(elementType)) { // The element count here is the total number of non-VLA elements. - llvm::Value *numElements = CGF.getVLASize(vla).NumElts; + llvm::Value *numElements = getVLASize(vla).NumElts; // Effectively, the multiply by the VLA size is part of the GEP. // GEP indexes are signed, and scaling an index isn't permitted to // signed-overflow, so we use the same semantics for our explicit // multiply. We suppress this if overflow is not undefined behavior. - llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType()); - if (CGF.getLangOpts().PointerOverflowDefined) { - index = CGF.Builder.CreateMul(index, numElements, "vla.index"); - pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr"); + llvm::Type *elemTy = ConvertTypeForMem(vla->getElementType()); + if (getLangOpts().PointerOverflowDefined) { + index = Builder.CreateMul(index, numElements, "vla.index"); + pointer = Builder.CreateGEP(elemTy, pointer, index, "add.ptr"); } else { - index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index"); - pointer = CGF.EmitCheckedInBoundsGEP( - elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(), - "add.ptr"); + index = Builder.CreateNSWMul(index, numElements, "vla.index"); + pointer = + EmitCheckedInBoundsGEP(elemTy, pointer, index, isSigned, + isSubtraction, BO->getExprLoc(), "add.ptr"); } return pointer; } @@ -4309,16 +4314,15 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, // future proof. llvm::Type *elemTy; if (elementType->isVoidType() || elementType->isFunctionType()) - elemTy = CGF.Int8Ty; + elemTy = Int8Ty; else - elemTy = CGF.ConvertTypeForMem(elementType); + elemTy = ConvertTypeForMem(elementType); - if (CGF.getLangOpts().PointerOverflowDefined) - return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr"); + if (getLangOpts().PointerOverflowDefined) + return Builder.CreateGEP(elemTy, pointer, index, "add.ptr"); - return CGF.EmitCheckedInBoundsGEP( - elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(), - "add.ptr"); + return EmitCheckedInBoundsGEP(elemTy, pointer, index, isSigned, isSubtraction, + BO->getExprLoc(), "add.ptr"); } // Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and |