30#include "llvm/ADT/APFixedPoint.h"
31#include "llvm/IR/CFG.h"
32#include "llvm/IR/Constants.h"
33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/DerivedTypes.h"
35#include "llvm/IR/FixedPointBuilder.h"
36#include "llvm/IR/Function.h"
37#include "llvm/IR/GetElementPtrTypeIterator.h"
38#include "llvm/IR/GlobalVariable.h"
39#include "llvm/IR/Intrinsics.h"
40#include "llvm/IR/IntrinsicsPowerPC.h"
41#include "llvm/IR/MatrixBuilder.h"
42#include "llvm/IR/Module.h"
43#include "llvm/Support/TypeSize.h"
48using namespace CodeGen;
66bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
68 llvm::APInt &Result) {
71 const auto &LHSAP = LHS->getValue();
72 const auto &RHSAP = RHS->getValue();
73 if (Opcode == BO_Add) {
74 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
75 : LHSAP.uadd_ov(RHSAP, Overflow);
76 }
else if (Opcode == BO_Sub) {
77 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
78 : LHSAP.usub_ov(RHSAP, Overflow);
79 }
else if (Opcode == BO_Mul) {
80 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
81 : LHSAP.umul_ov(RHSAP, Overflow);
82 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
83 if (
Signed && !RHS->isZero())
84 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
100 bool mayHaveIntegerOverflow()
const {
102 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
103 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
104 if (!LHSCI || !RHSCI)
108 return ::mayHaveIntegerOverflow(
113 bool isDivremOp()
const {
119 bool mayHaveIntegerDivisionByZero()
const {
121 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
127 bool mayHaveFloatDivisionByZero()
const {
129 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
130 return CFP->isZero();
137 bool isFixedPointOp()
const {
140 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
141 QualType LHSType = BinOp->getLHS()->getType();
142 QualType RHSType = BinOp->getRHS()->getType();
145 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
146 return UnOp->getSubExpr()->getType()->isFixedPointType();
151static bool MustVisitNullValue(
const Expr *E) {
159static std::optional<QualType> getUnwidenedIntegerType(
const ASTContext &Ctx,
174static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
175 return getUnwidenedIntegerType(Ctx, E).has_value();
179static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
180 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
181 "Expected a unary or binary operator");
185 if (!Op.mayHaveIntegerOverflow())
189 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
190 return !UO->canOverflow();
194 const auto *BO = cast<BinaryOperator>(Op.E);
195 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
199 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
208 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
214 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
215 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
219class ScalarExprEmitter
223 bool IgnoreResultAssign;
224 llvm::LLVMContext &VMContext;
228 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
229 VMContext(cgf.getLLVMContext()) {
236 bool TestAndClearIgnoreResultAssign() {
237 bool I = IgnoreResultAssign;
238 IgnoreResultAssign =
false;
244 LValue EmitCheckedLValue(
const Expr *E, CodeGenFunction::TypeCheckKind TCK) {
248 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
249 const BinOpInfo &Info);
255 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
256 const AlignValueAttr *AVAttr =
nullptr;
257 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
261 if (
const auto *TTy =
263 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
270 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
273 AVAttr = VD->
getAttr<AlignValueAttr>();
279 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
285 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
293 Value *
V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load),
296 EmitLValueAlignmentAssumption(E,
V);
306 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
312 enum ImplicitConversionCheckKind :
unsigned char {
313 ICCK_IntegerTruncation = 0,
314 ICCK_UnsignedIntegerTruncation = 1,
315 ICCK_SignedIntegerTruncation = 2,
316 ICCK_IntegerSignChange = 3,
317 ICCK_SignedIntegerTruncationOrSignChange = 4,
333 struct ScalarConversionOpts {
334 bool TreatBooleanAsSigned;
335 bool EmitImplicitIntegerTruncationChecks;
336 bool EmitImplicitIntegerSignChangeChecks;
338 ScalarConversionOpts()
339 : TreatBooleanAsSigned(
false),
340 EmitImplicitIntegerTruncationChecks(
false),
341 EmitImplicitIntegerSignChangeChecks(
false) {}
344 : TreatBooleanAsSigned(
false),
345 EmitImplicitIntegerTruncationChecks(
347 EmitImplicitIntegerSignChangeChecks(
351 llvm::Type *SrcTy, llvm::Type *DstTy,
352 ScalarConversionOpts Opts);
356 ScalarConversionOpts Opts = ScalarConversionOpts());
365 Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
375 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
376 return Builder.CreateFCmpUNE(
V, Zero,
"tobool");
383 return Builder.CreateICmpNE(
V, Zero,
"tobool");
390 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
391 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
392 Value *Result = ZI->getOperand(0);
397 ZI->eraseFromParent();
402 return Builder.CreateIsNotNull(
V,
"tobool");
416 llvm_unreachable(
"Stmt can't have complex result type!");
442 return Visit(
GE->getResultExpr());
456 return Builder.getInt(E->
getValue());
459 return Builder.getInt(E->
getValue());
462 return llvm::ConstantFP::get(VMContext, E->
getValue());
465 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
468 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
471 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
477 return EmitNullValue(E->
getType());
480 return EmitNullValue(E->
getType());
486 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
512 return EmitLoadOfLValue(E);
522 return EmitLoadOfLValue(E);
527 return EmitLoadOfLValue(E);
543 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
553 Value *VisitExtVectorElementExpr(
Expr *E) {
return EmitLoadOfLValue(E); }
560 return EmitLoadOfLValue(E);
567 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
572 return EmitNullValue(E->
getType());
576 return VisitCastExpr(E);
582 return EmitLoadOfLValue(E);
586 EmitLValueAlignmentAssumption(E,
V);
595 return EmitScalarPrePostIncDec(E, LV,
false,
false);
599 return EmitScalarPrePostIncDec(E, LV,
true,
false);
603 return EmitScalarPrePostIncDec(E, LV,
false,
true);
607 return EmitScalarPrePostIncDec(E, LV,
true,
true);
610 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
615 bool isInc,
bool isPre);
619 if (isa<MemberPointerType>(E->
getType()))
622 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
627 return EmitLoadOfLValue(E);
651 return EmitLoadOfLValue(E);
662 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
666 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
683 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
695 return llvm::ConstantInt::get(Builder.getInt32Ty(), E->
getValue());
699 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
713 return EmitNullValue(E->
getType());
722 return Builder.getInt1(E->
getValue());
726 Value *EmitMul(
const BinOpInfo &Ops) {
727 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
728 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
730 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
731 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
734 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
735 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
738 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
739 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
740 return EmitOverflowCheckedBinOp(Ops);
744 if (Ops.Ty->isConstantMatrixType()) {
745 llvm::MatrixBuilder MB(Builder);
748 auto *BO = cast<BinaryOperator>(Ops.E);
749 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
750 BO->getLHS()->getType().getCanonicalType());
751 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
752 BO->getRHS()->getType().getCanonicalType());
753 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
754 if (LHSMatTy && RHSMatTy)
755 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
756 LHSMatTy->getNumColumns(),
757 RHSMatTy->getNumColumns());
758 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
761 if (Ops.Ty->isUnsignedIntegerType() &&
762 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
763 !CanElideOverflowCheck(CGF.
getContext(), Ops))
764 return EmitOverflowCheckedBinOp(Ops);
766 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
768 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
769 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
771 if (Ops.isFixedPointOp())
772 return EmitFixedPointBinOp(Ops);
773 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
777 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
780 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
781 llvm::Value *Zero,
bool isDiv);
789 Value *EmitDiv(
const BinOpInfo &Ops);
790 Value *EmitRem(
const BinOpInfo &Ops);
791 Value *EmitAdd(
const BinOpInfo &Ops);
792 Value *EmitSub(
const BinOpInfo &Ops);
793 Value *EmitShl(
const BinOpInfo &Ops);
794 Value *EmitShr(
const BinOpInfo &Ops);
795 Value *EmitAnd(
const BinOpInfo &Ops) {
796 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
798 Value *EmitXor(
const BinOpInfo &Ops) {
799 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
801 Value *EmitOr (
const BinOpInfo &Ops) {
802 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
806 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
816 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
820 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
825 QualType ElementType = CT->getElementType();
832 unsigned NumElements = VT->getNumElements();
842#define HANDLEBINOP(OP) \
843 Value *VisitBin##OP(const BinaryOperator *E) { \
844 QualType promotionTy = getPromotionType(E->getType()); \
845 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
846 if (result && !promotionTy.isNull()) \
847 result = EmitUnPromotedValue(result, E->getType()); \
850 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
851 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
867 llvm::CmpInst::Predicate SICmpOpc,
868 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
869#define VISITCOMP(CODE, UI, SI, FP, SIG) \
870 Value *VisitBin##CODE(const BinaryOperator *E) { \
871 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
872 llvm::FCmpInst::FP, SIG); }
887 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
888 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
926 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
929 return EmitFloatToBoolConversion(Src);
935 "Unknown scalar type to convert");
937 if (isa<llvm::IntegerType>(Src->
getType()))
938 return EmitIntToBoolConversion(Src);
940 assert(isa<llvm::PointerType>(Src->
getType()));
941 return EmitPointerToBoolConversion(Src, SrcType);
944void ScalarExprEmitter::EmitFloatConversionCheck(
947 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
948 if (!isa<llvm::IntegerType>(DstTy))
951 CodeGenFunction::SanitizerScope SanScope(&CGF);
955 llvm::Value *Check =
nullptr;
956 const llvm::fltSemantics &SrcSema =
966 APFloat MinSrc(SrcSema, APFloat::uninitialized);
967 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
971 MinSrc = APFloat::getInf(SrcSema,
true);
975 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
978 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
979 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
983 MaxSrc = APFloat::getInf(SrcSema,
false);
987 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
992 const llvm::fltSemantics &
Sema =
995 MinSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
996 MaxSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1000 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1002 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1003 Check = Builder.CreateAnd(GE, LE);
1008 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
1009 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
1014static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1015 std::pair<llvm::Value *, SanitizerMask>>
1018 llvm::Type *SrcTy = Src->
getType();
1019 llvm::Type *DstTy = Dst->
getType();
1024 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1025 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1026 "non-integer llvm type");
1033 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1035 if (!SrcSigned && !DstSigned) {
1036 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1037 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
1039 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1040 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
1043 llvm::Value *Check =
nullptr;
1045 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1047 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1049 return std::make_pair(Kind, std::make_pair(Check, Mask));
1057void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1069 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1070 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1072 if (SrcBits <= DstBits)
1075 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1082 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1083 (!SrcSigned && DstSigned))
1086 CodeGenFunction::SanitizerScope SanScope(&CGF);
1088 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1089 std::pair<llvm::Value *, SanitizerMask>>
1098 llvm::Constant *StaticArgs[] = {
1101 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)};
1102 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1108static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1109 std::pair<llvm::Value *, SanitizerMask>>
1112 llvm::Type *SrcTy = Src->
getType();
1113 llvm::Type *DstTy = Dst->
getType();
1115 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1116 "non-integer llvm type");
1122 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1123 unsigned DstBits = DstTy->getScalarSizeInBits();
1127 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1128 "either the widths should be different, or the signednesses.");
1132 const char *Name) ->
Value * {
1134 bool VSigned = VType->isSignedIntegerOrEnumerationType();
1135 llvm::Type *VTy =
V->getType();
1139 return llvm::ConstantInt::getFalse(VTy->getContext());
1142 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1145 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V, Zero,
1146 llvm::Twine(Name) +
"." +
V->getName() +
1147 ".negativitycheck");
1151 llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType,
"src");
1153 llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType,
"dst");
1158 llvm::Value *Check =
nullptr;
1159 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1161 return std::make_pair(
1162 ScalarExprEmitter::ICCK_IntegerSignChange,
1163 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1166void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1169 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1172 llvm::Type *SrcTy = Src->
getType();
1173 llvm::Type *DstTy = Dst->
getType();
1183 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1184 unsigned DstBits = DstTy->getScalarSizeInBits();
1191 if (SrcSigned == DstSigned && SrcBits == DstBits)
1195 if (!SrcSigned && !DstSigned)
1200 if ((DstBits > SrcBits) && DstSigned)
1202 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1203 (SrcBits > DstBits) && SrcSigned) {
1211 CodeGenFunction::SanitizerScope SanScope(&CGF);
1213 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1214 std::pair<llvm::Value *, SanitizerMask>>
1218 ImplicitConversionCheckKind CheckKind;
1224 CheckKind = Check.first;
1225 Checks.emplace_back(Check.second);
1227 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1228 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1234 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1235 Checks.emplace_back(Check.second);
1239 llvm::Constant *StaticArgs[] = {
1242 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)};
1244 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1249 QualType DstType, llvm::Type *SrcTy,
1251 ScalarConversionOpts Opts) {
1253 llvm::Type *SrcElementTy;
1254 llvm::Type *DstElementTy;
1258 SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1259 DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1264 "cannot cast between matrix and non-matrix types");
1265 SrcElementTy = SrcTy;
1266 DstElementTy = DstTy;
1267 SrcElementType = SrcType;
1268 DstElementType = DstType;
1271 if (isa<llvm::IntegerType>(SrcElementTy)) {
1273 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1277 if (isa<llvm::IntegerType>(DstElementTy))
1278 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1280 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1281 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1284 if (isa<llvm::IntegerType>(DstElementTy)) {
1285 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1292 llvm::Intrinsic::ID IID =
1293 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1294 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1298 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1299 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1302 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1303 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1304 return Builder.CreateFPExt(Src, DstTy,
"conv");
1312 ScalarConversionOpts Opts) {
1327 return Builder.CreateIsNotNull(Src,
"tobool");
1330 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1333 "Unhandled scalar conversion from a fixed point type to another type.");
1337 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1340 "Unhandled scalar conversion to a fixed point type from another type.");
1343 QualType NoncanonicalSrcType = SrcType;
1344 QualType NoncanonicalDstType = DstType;
1348 if (SrcType == DstType)
return Src;
1352 llvm::Value *OrigSrc = Src;
1354 llvm::Type *SrcTy = Src->
getType();
1358 return EmitConversionToBool(Src, SrcType);
1360 llvm::Type *DstTy = ConvertType(DstType);
1365 if (DstTy->isFloatingPointTy()) {
1367 return Builder.CreateCall(
1375 Src = Builder.CreateCall(
1380 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1388 if (SrcTy == DstTy) {
1389 if (Opts.EmitImplicitIntegerSignChangeChecks)
1390 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1391 NoncanonicalDstType, Loc);
1399 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1401 if (isa<llvm::PointerType>(SrcTy))
1402 return Builder.CreateBitCast(Src, DstTy,
"conv");
1404 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1409 llvm::Value* IntResult =
1410 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1412 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1415 if (isa<llvm::PointerType>(SrcTy)) {
1417 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1418 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1427 "Splatted expr doesn't match with vector element type?");
1430 unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
1431 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1435 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1437 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1439 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1440 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1441 if (SrcSize == DstSize)
1442 return Builder.CreateBitCast(Src, DstTy,
"conv");
1451 llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1452 llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1455 assert(((SrcElementTy->isIntegerTy() &&
1456 DstElementTy->isIntegerTy()) ||
1457 (SrcElementTy->isFloatingPointTy() &&
1458 DstElementTy->isFloatingPointTy())) &&
1459 "unexpected conversion between a floating-point vector and an "
1463 if (SrcElementTy->isIntegerTy())
1464 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1467 if (SrcSize > DstSize)
1468 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1471 return Builder.CreateFPExt(Src, DstTy,
"conv");
1475 Value *Res =
nullptr;
1476 llvm::Type *ResTy = DstTy;
1483 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1485 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1491 if (SrcTy->isFloatingPointTy()) {
1495 return Builder.CreateCall(
1498 return Builder.CreateFPTrunc(Src, DstTy);
1503 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1505 if (DstTy != ResTy) {
1507 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1508 Res = Builder.CreateCall(
1512 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1516 if (Opts.EmitImplicitIntegerTruncationChecks)
1517 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1518 NoncanonicalDstType, Loc);
1520 if (Opts.EmitImplicitIntegerSignChangeChecks)
1521 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1522 NoncanonicalDstType, Loc);
1530 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1531 llvm::Value *Result;
1533 Result = FPBuilder.CreateFloatingToFixed(Src,
1536 Result = FPBuilder.CreateFixedToFloating(Src,
1538 ConvertType(DstTy));
1544 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1545 DstFPSema.getWidth(),
1546 DstFPSema.isSigned());
1548 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1551 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1558Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1567 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1568 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1569 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1576 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1587void ScalarExprEmitter::EmitBinOpCheck(
1588 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1600 if (UO && UO->
getOpcode() == UO_Minus) {
1601 Check = SanitizerHandler::NegateOverflow;
1603 DynamicData.push_back(Info.RHS);
1607 Check = SanitizerHandler::ShiftOutOfBounds;
1609 StaticData.push_back(
1611 StaticData.push_back(
1613 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1615 Check = SanitizerHandler::DivremOverflow;
1620 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1621 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1622 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1623 default: llvm_unreachable(
"unexpected opcode for bin op check");
1627 DynamicData.push_back(Info.LHS);
1628 DynamicData.push_back(Info.RHS);
1631 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1638Value *ScalarExprEmitter::VisitExpr(
Expr *E) {
1648 unsigned AddrSpace =
1650 llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1653 llvm::Type *ExprTy = ConvertType(E->
getType());
1654 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1665 auto *LTy = cast<llvm::FixedVectorType>(LHS->
getType());
1666 unsigned LHSElts = LTy->getNumElements();
1670 auto *MTy = cast<llvm::FixedVectorType>(Mask->
getType());
1674 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1675 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1683 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1684 MTy->getNumElements());
1685 Value* NewV = llvm::PoisonValue::get(RTy);
1686 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1687 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1688 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1690 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1691 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1703 if (Idx.isSigned() && Idx.isAllOnes())
1704 Indices.push_back(-1);
1706 Indices.push_back(Idx.getZExtValue());
1709 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1720 if (SrcType == DstType)
return Src;
1723 "ConvertVector source type must be a vector");
1725 "ConvertVector destination type must be a vector");
1727 llvm::Type *SrcTy = Src->
getType();
1728 llvm::Type *DstTy = ConvertType(DstType);
1737 assert(SrcTy->isVectorTy() &&
1738 "ConvertVector source IR type must be a vector");
1739 assert(DstTy->isVectorTy() &&
1740 "ConvertVector destination IR type must be a vector");
1742 llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
1743 *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
1745 if (DstEltType->isBooleanType()) {
1746 assert((SrcEltTy->isFloatingPointTy() ||
1747 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1749 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
1750 if (SrcEltTy->isFloatingPointTy()) {
1751 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1753 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1758 Value *Res =
nullptr;
1760 if (isa<llvm::IntegerType>(SrcEltTy)) {
1762 if (isa<llvm::IntegerType>(DstEltTy))
1763 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1764 else if (InputSigned)
1765 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1767 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1768 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1769 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1770 if (DstEltType->isSignedIntegerOrEnumerationType())
1771 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1773 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1775 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1776 "Unknown real conversion");
1777 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1778 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1780 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1793 llvm::APSInt
Value = Result.Val.getInt();
1795 return Builder.getInt(
Value);
1799 return EmitLoadOfLValue(E);
1803 TestAndClearIgnoreResultAssign();
1811 return EmitLoadOfLValue(E);
1819 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1822 return Builder.CreateExtractElement(
Base, Idx,
"vecext");
1826 TestAndClearIgnoreResultAssign();
1835 llvm::MatrixBuilder MB(Builder);
1836 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
1838 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
1843 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
1848 int MV = SVI->getMaskValue(Idx);
1855 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
1856 "Index operand too large for shufflevector mask!");
1857 return C->getZExtValue();
1861 bool Ignore = TestAndClearIgnoreResultAssign();
1863 assert (Ignore ==
false &&
"init list ignored");
1869 llvm::VectorType *VType =
1870 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
1873 if (NumInitElements == 0) {
1875 return EmitNullValue(E->
getType());
1881 if (isa<llvm::ScalableVectorType>(VType)) {
1882 if (NumInitElements == 0) {
1884 return EmitNullValue(E->
getType());
1887 if (NumInitElements == 1) {
1892 return Visit(InitVector);
1895 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
1898 unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
1905 unsigned CurIdx = 0;
1906 bool VIsPoisonShuffle =
false;
1907 llvm::Value *
V = llvm::PoisonValue::get(VType);
1908 for (
unsigned i = 0; i != NumInitElements; ++i) {
1913 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
1919 if (isa<ExtVectorElementExpr>(IE)) {
1920 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(
Init);
1922 if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
1923 ->getNumElements() == ResElts) {
1924 llvm::ConstantInt *
C = cast<llvm::ConstantInt>(EI->getIndexOperand());
1925 Value *LHS =
nullptr, *RHS =
nullptr;
1930 Args.resize(ResElts, -1);
1932 LHS = EI->getVectorOperand();
1934 VIsPoisonShuffle =
true;
1935 }
else if (VIsPoisonShuffle) {
1937 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
1938 for (
unsigned j = 0; j != CurIdx; ++j)
1940 Args.push_back(ResElts +
C->getZExtValue());
1941 Args.resize(ResElts, -1);
1943 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
1944 RHS = EI->getVectorOperand();
1945 VIsPoisonShuffle =
false;
1947 if (!Args.empty()) {
1948 V = Builder.CreateShuffleVector(LHS, RHS, Args);
1954 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
1956 VIsPoisonShuffle =
false;
1961 unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
1966 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
1967 if (isa<ExtVectorElementExpr>(IE)) {
1968 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(
Init);
1969 Value *SVOp = SVI->getOperand(0);
1970 auto *OpTy = cast<llvm::FixedVectorType>(SVOp->
getType());
1972 if (OpTy->getNumElements() == ResElts) {
1973 for (
unsigned j = 0; j != CurIdx; ++j) {
1976 if (VIsPoisonShuffle) {
1977 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(
V), j, 0));
1982 for (
unsigned j = 0, je = InitElts; j != je; ++j)
1984 Args.resize(ResElts, -1);
1986 if (VIsPoisonShuffle)
1987 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
1996 for (
unsigned j = 0; j != InitElts; ++j)
1998 Args.resize(ResElts, -1);
1999 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2002 for (
unsigned j = 0; j != CurIdx; ++j)
2004 for (
unsigned j = 0; j != InitElts; ++j)
2005 Args.push_back(j + Offset);
2006 Args.resize(ResElts, -1);
2013 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2014 VIsPoisonShuffle = isa<llvm::PoisonValue>(
Init);
2020 llvm::Type *EltTy = VType->getElementType();
2023 for (; CurIdx < ResElts; ++CurIdx) {
2024 Value *Idx = Builder.getInt32(CurIdx);
2025 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2026 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2031bool CodeGenFunction::ShouldNullCheckClassCastValue(
const CastExpr *CE) {
2034 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2044 if (ICE->isGLValue())
2058 CodeGenFunction::CGFPOptionsRAII
FPOptions(CGF, CE);
2062 bool Ignored = TestAndClearIgnoreResultAssign();
2068 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2069 case CK_BuiltinFnToFnPtr:
2070 llvm_unreachable(
"builtin functions are handled elsewhere");
2072 case CK_LValueBitCast:
2073 case CK_ObjCObjectLValueCast: {
2074 Address Addr = EmitLValue(E).getAddress(CGF);
2077 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2080 case CK_LValueToRValueBitCast: {
2086 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2089 case CK_CPointerToObjCPointerCast:
2090 case CK_BlockPointerToObjCPointerCast:
2091 case CK_AnyPointerToBlockPointerCast:
2093 Value *Src = Visit(
const_cast<Expr*
>(E));
2094 llvm::Type *SrcTy = Src->
getType();
2095 llvm::Type *DstTy = ConvertType(DestTy);
2097 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2098 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2099 "Address-space cast must be used to convert address spaces");
2101 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2104 PT->getPointeeType(),
2120 Src = Builder.CreateLaunderInvariantGroup(Src);
2128 Src = Builder.CreateStripInvariantGroup(Src);
2133 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2134 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE) &&
2135 !isa<CastExpr>(E)) {
2137 if (!PointeeType.
isNull())
2146 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2147 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2150 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2151 ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
2152 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2153 ScalableDstTy = llvm::ScalableVectorType::get(
2154 FixedSrcTy->getElementType(),
2155 ScalableDstTy->getElementCount().getKnownMinValue() / 8);
2157 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2158 llvm::Value *UndefVec = llvm::UndefValue::get(ScalableDstTy);
2159 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2160 llvm::Value *
Result = Builder.CreateInsertVector(
2161 ScalableDstTy, UndefVec, Src, Zero,
"cast.scalable");
2162 if (
Result->getType() != DstTy)
2172 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2173 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2176 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2177 ScalableSrcTy->getElementCount().isKnownMultipleOf(8) &&
2178 FixedDstTy->getElementType()->isIntegerTy(8)) {
2179 ScalableSrcTy = llvm::ScalableVectorType::get(
2180 FixedDstTy->getElementType(),
2181 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2182 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2184 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType()) {
2185 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2186 return Builder.CreateExtractVector(DstTy, Src, Zero,
"cast.fixed");
2197 if ((isa<llvm::FixedVectorType>(SrcTy) &&
2198 isa<llvm::ScalableVectorType>(DstTy)) ||
2199 (isa<llvm::ScalableVectorType>(SrcTy) &&
2200 isa<llvm::FixedVectorType>(DstTy))) {
2207 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2209 return Builder.CreateBitCast(Src, DstTy);
2211 case CK_AddressSpaceConversion: {
2214 Result.Val.isNullPointer()) {
2218 if (
Result.HasSideEffects)
2221 ConvertType(DestTy)), DestTy);
2229 case CK_AtomicToNonAtomic:
2230 case CK_NonAtomicToAtomic:
2231 case CK_UserDefinedConversion:
2232 return Visit(
const_cast<Expr*
>(E));
2236 : Visit(const_cast<
Expr *>(E));
2239 case CK_BaseToDerived: {
2241 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2255 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2263 case CK_UncheckedDerivedToBase:
2264 case CK_DerivedToBase: {
2276 case CK_ArrayToPointerDecay:
2278 case CK_FunctionToPointerDecay:
2279 return EmitLValue(E).getPointer(CGF);
2281 case CK_NullToPointer:
2282 if (MustVisitNullValue(E))
2288 case CK_NullToMemberPointer: {
2289 if (MustVisitNullValue(E))
2296 case CK_ReinterpretMemberPointer:
2297 case CK_BaseToDerivedMemberPointer:
2298 case CK_DerivedToBaseMemberPointer: {
2299 Value *Src = Visit(E);
2310 case CK_ARCProduceObject:
2312 case CK_ARCConsumeObject:
2314 case CK_ARCReclaimReturnedObject:
2316 case CK_ARCExtendBlockObject:
2319 case CK_CopyAndAutoreleaseBlockObject:
2322 case CK_FloatingRealToComplex:
2323 case CK_FloatingComplexCast:
2324 case CK_IntegralRealToComplex:
2325 case CK_IntegralComplexCast:
2326 case CK_IntegralComplexToFloatingComplex:
2327 case CK_FloatingComplexToIntegralComplex:
2328 case CK_ConstructorConversion:
2330 llvm_unreachable(
"scalar cast to non-scalar value");
2332 case CK_LValueToRValue:
2334 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2335 return Visit(
const_cast<Expr*
>(E));
2337 case CK_IntegralToPointer: {
2338 Value *Src = Visit(
const_cast<Expr*
>(E));
2342 auto DestLLVMTy = ConvertType(DestTy);
2345 llvm::Value* IntResult =
2346 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2348 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2354 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2358 case CK_PointerToIntegral: {
2359 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2360 auto *PtrExpr = Visit(E);
2368 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2371 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2377 case CK_MatrixCast: {
2378 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2381 case CK_VectorSplat: {
2382 llvm::Type *DstTy = ConvertType(DestTy);
2383 Value *Elt = Visit(
const_cast<Expr *
>(E));
2385 llvm::ElementCount NumElements =
2386 cast<llvm::VectorType>(DstTy)->getElementCount();
2387 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2390 case CK_FixedPointCast:
2391 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2394 case CK_FixedPointToBoolean:
2396 "Expected src type to be fixed point type");
2397 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2398 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2401 case CK_FixedPointToIntegral:
2403 "Expected src type to be fixed point type");
2404 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2405 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2408 case CK_IntegralToFixedPoint:
2410 "Expected src type to be an integer");
2412 "Expected dest type to be fixed point type");
2413 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2416 case CK_IntegralCast: {
2419 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
2423 ScalarConversionOpts Opts;
2424 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2425 if (!ICE->isPartOfExplicitCast())
2426 Opts = ScalarConversionOpts(CGF.
SanOpts);
2428 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2431 case CK_IntegralToFloating: {
2436 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
2437 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
2439 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2440 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2443 case CK_FloatingToIntegral: {
2448 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
2449 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
2451 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2452 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2455 case CK_FloatingCast: {
2462 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
2463 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
2465 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2466 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2469 case CK_FixedPointToFloating:
2470 case CK_FloatingToFixedPoint: {
2471 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2472 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2475 case CK_BooleanToSignedIntegral: {
2476 ScalarConversionOpts Opts;
2477 Opts.TreatBooleanAsSigned =
true;
2478 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2481 case CK_IntegralToBoolean:
2482 return EmitIntToBoolConversion(Visit(E));
2483 case CK_PointerToBoolean:
2484 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2485 case CK_FloatingToBoolean: {
2486 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2487 return EmitFloatToBoolConversion(Visit(E));
2489 case CK_MemberPointerToBoolean: {
2490 llvm::Value *MemPtr = Visit(E);
2495 case CK_FloatingComplexToReal:
2496 case CK_IntegralComplexToReal:
2499 case CK_FloatingComplexToBoolean:
2500 case CK_IntegralComplexToBoolean: {
2504 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
2508 case CK_ZeroToOCLOpaqueType: {
2511 "CK_ZeroToOCLEvent cast on non-event type");
2512 return llvm::Constant::getNullValue(ConvertType(DestTy));
2515 case CK_IntToOCLSampler:
2518 case CK_HLSLVectorTruncation: {
2519 assert(DestTy->
isVectorType() &&
"Expected dest type to be vector type");
2520 Value *Vec = Visit(
const_cast<Expr *
>(E));
2523 for (
unsigned I = 0; I != NumElts; ++I)
2526 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2531 llvm_unreachable(
"unknown scalar cast");
2535 CodeGenFunction::StmtExprEvaluation eval(CGF);
2545 CodeGenFunction::RunCleanupsScope
Scope(CGF);
2549 Scope.ForceCleanup({&
V});
2558 llvm::Value *InVal,
bool IsInc,
2562 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2564 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2565 BinOp.FPFeatures = FPFeatures;
2570llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2572 llvm::Value *Amount =
2573 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2574 StringRef Name = IsInc ?
"inc" :
"dec";
2575 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2577 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2578 return Builder.CreateAdd(InVal, Amount, Name);
2581 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2582 return Builder.CreateNSWAdd(InVal, Amount, Name);
2586 return Builder.CreateNSWAdd(InVal, Amount, Name);
2590 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2595class OMPLastprivateConditionalUpdateRAII {
2604 ~OMPLastprivateConditionalUpdateRAII() {
2614 bool isInc,
bool isPre) {
2615 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
2617 llvm::PHINode *atomicPHI =
nullptr;
2621 int amount = (isInc ? 1 : -1);
2622 bool isSubtraction = !isInc;
2625 type = atomicTy->getValueType();
2626 if (isInc &&
type->isBooleanType()) {
2630 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2631 return Builder.getTrue();
2635 return Builder.CreateAtomicRMW(
2636 llvm::AtomicRMWInst::Xchg, LV.
getAddress(CGF), True,
2637 llvm::AtomicOrdering::SequentiallyConsistent);
2642 if (!
type->isBooleanType() &&
type->isIntegerType() &&
2643 !(
type->isUnsignedIntegerType() &&
2644 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2647 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2648 llvm::AtomicRMWInst::Sub;
2649 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2650 llvm::Instruction::Sub;
2652 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
2654 Builder.CreateAtomicRMW(aop, LV.
getAddress(CGF), amt,
2655 llvm::AtomicOrdering::SequentiallyConsistent);
2656 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2658 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2661 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2664 Builder.CreateBr(opBB);
2665 Builder.SetInsertPoint(opBB);
2666 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2667 atomicPHI->addIncoming(value, startBB);
2670 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2681 if (isInc &&
type->isBooleanType()) {
2682 value = Builder.getTrue();
2685 }
else if (
type->isIntegerType()) {
2687 bool canPerformLossyDemotionCheck =
false;
2690 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
2691 canPerformLossyDemotionCheck =
true;
2692 canPerformLossyDemotionCheck &=
2695 canPerformLossyDemotionCheck &=
2697 type, promotedType);
2698 assert((!canPerformLossyDemotionCheck ||
2699 type->isSignedIntegerOrEnumerationType() ||
2701 ConvertType(
type)->getScalarSizeInBits() ==
2702 ConvertType(promotedType)->getScalarSizeInBits()) &&
2703 "The following check expects that if we do promotion to different "
2704 "underlying canonical type, at least one of the types (either "
2705 "base or promoted) will be signed, or the bitwidths will match.");
2708 SanitizerKind::ImplicitIntegerArithmeticValueChange) &&
2709 canPerformLossyDemotionCheck) {
2719 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
2720 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2721 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2724 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
2725 ScalarConversionOpts(CGF.
SanOpts));
2730 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
2731 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
2733 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2737 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2738 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2749 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2752 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
2755 elemTy, value, numElts,
false, isSubtraction,
2759 }
else if (
type->isFunctionType()) {
2760 llvm::Value *amt = Builder.getInt32(amount);
2763 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
2767 false, isSubtraction,
2772 llvm::Value *amt = Builder.getInt32(amount);
2775 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
2778 elemTy, value, amt,
false, isSubtraction,
2783 }
else if (
type->isVectorType()) {
2784 if (
type->hasIntegerRepresentation()) {
2785 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2787 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2789 value = Builder.CreateFAdd(
2791 llvm::ConstantFP::get(value->getType(), amount),
2792 isInc ?
"inc" :
"dec");
2796 }
else if (
type->isRealFloatingType()) {
2799 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
2804 value = Builder.CreateCall(
2807 input,
"incdec.conv");
2809 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
2813 if (value->getType()->isFloatTy())
2814 amt = llvm::ConstantFP::get(VMContext,
2815 llvm::APFloat(
static_cast<float>(amount)));
2816 else if (value->getType()->isDoubleTy())
2817 amt = llvm::ConstantFP::get(VMContext,
2818 llvm::APFloat(
static_cast<double>(amount)));
2822 llvm::APFloat F(
static_cast<float>(amount));
2824 const llvm::fltSemantics *FS;
2827 if (value->getType()->isFP128Ty())
2829 else if (value->getType()->isHalfTy())
2831 else if (value->getType()->isBFloatTy())
2833 else if (value->getType()->isPPC_FP128Ty())
2837 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
2838 amt = llvm::ConstantFP::get(VMContext, F);
2840 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
2844 value = Builder.CreateCall(
2847 value,
"incdec.conv");
2849 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
2854 }
else if (
type->isFixedPointType()) {
2861 Info.Opcode = isInc ? BO_Add : BO_Sub;
2863 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
2866 if (
type->isSignedFixedPointType()) {
2867 Info.Opcode = isInc ? BO_Sub : BO_Add;
2868 Info.RHS = Builder.CreateNeg(Info.RHS);
2873 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
2875 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
2876 value = EmitFixedPointBinOp(Info);
2883 if (!isInc) size = -size;
2884 llvm::Value *sizeValue =
2885 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
2888 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
2891 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
2893 value = Builder.CreateBitCast(value, input->getType());
2897 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
2902 llvm::Value *
success = Pair.second;
2903 atomicPHI->addIncoming(old, curBlock);
2904 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
2905 Builder.SetInsertPoint(contBB);
2906 return isPre ? value : input;
2917 return isPre ? value : input;
2926 Value *result = VisitPlus(E, promotionTy);
2927 if (result && !promotionTy.
isNull())
2928 result = EmitUnPromotedValue(result, E->
getType());
2935 TestAndClearIgnoreResultAssign();
2936 if (!PromotionType.
isNull())
2946 Value *result = VisitMinus(E, promotionTy);
2947 if (result && !promotionTy.
isNull())
2948 result = EmitUnPromotedValue(result, E->
getType());
2954 TestAndClearIgnoreResultAssign();
2956 if (!PromotionType.
isNull())
2962 if (Op->
getType()->isFPOrFPVectorTy())
2963 return Builder.CreateFNeg(Op,
"fneg");
2968 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
2970 BinOp.Opcode = BO_Sub;
2973 return EmitSub(BinOp);
2977 TestAndClearIgnoreResultAssign();
2979 return Builder.CreateNot(Op,
"not");
2990 if (Oper->
getType()->isFPOrFPVectorTy()) {
2991 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
2993 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
2995 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
2996 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3005 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3008 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3016 return Builder.getInt(
Value);
3021 llvm::Type* ResultType = ConvertType(E->
getType());
3022 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3024 for (
unsigned i = 0; i != n; ++i) {
3026 llvm::Value *Offset =
nullptr;
3033 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3040 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3044 Offset = Builder.CreateMul(Idx, ElemSize);
3058 Field != FieldEnd; ++Field, ++i) {
3059 if (*Field == MemberDecl)
3062 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3067 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3070 CurrentType = MemberDecl->
getType();
3075 llvm_unreachable(
"dependent __builtin_offsetof");
3091 auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
3093 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3105ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3109 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
3122 llvm::Value *size = VlaSize.
NumElts;
3126 if (!eltSize.
isOne())
3131 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3137 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3138 }
else if (E->
getKind() == UETT_VectorElements) {
3140 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3153 Value *result = VisitReal(E, promotionTy);
3154 if (result && !promotionTy.
isNull())
3155 result = EmitUnPromotedValue(result, E->
getType());
3167 if (!PromotionType.
isNull()) {
3169 Op, IgnoreResultAssign,
true);
3172 return result.first;
3182 if (!PromotionType.
isNull())
3192 Value *result = VisitImag(E, promotionTy);
3193 if (result && !promotionTy.
isNull())
3194 result = EmitUnPromotedValue(result, E->
getType());
3206 if (!PromotionType.
isNull()) {
3208 Op,
true, IgnoreResultAssign);
3211 return result.second;
3225 else if (!PromotionType.
isNull())
3229 if (!PromotionType.
isNull())
3230 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3231 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3238Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3240 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3243Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3245 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3250 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3252#define HANDLE_BINOP(OP) \
3254 return Emit##OP(EmitBinOps(BO, PromotionType));
3263 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3266 return VisitImag(UO, PromotionType);
3268 return VisitReal(UO, PromotionType);
3270 return VisitMinus(UO, PromotionType);
3272 return VisitPlus(UO, PromotionType);
3277 auto result = Visit(
const_cast<Expr *
>(E));
3279 if (!PromotionType.
isNull())
3280 return EmitPromotedValue(result, PromotionType);
3282 return EmitUnPromotedValue(result, E->
getType());
3289 TestAndClearIgnoreResultAssign();
3293 if (!PromotionType.
isNull())
3294 Result.Ty = PromotionType;
3303LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3305 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3318 if (PromotionTypeCR.
isNull())
3322 if (!PromotionTypeRHS.
isNull())
3325 OpInfo.RHS = Visit(E->
getRHS());
3326 OpInfo.Ty = PromotionTypeCR;
3333 llvm::PHINode *atomicPHI =
nullptr;
3336 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3337 !(
type->isUnsignedIntegerType() &&
3338 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3341 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3342 llvm::Instruction::BinaryOps Op;
3343 switch (OpInfo.Opcode) {
3345 case BO_MulAssign:
case BO_DivAssign:
3351 AtomicOp = llvm::AtomicRMWInst::Add;
3352 Op = llvm::Instruction::Add;
3355 AtomicOp = llvm::AtomicRMWInst::Sub;
3356 Op = llvm::Instruction::Sub;
3359 AtomicOp = llvm::AtomicRMWInst::And;
3360 Op = llvm::Instruction::And;
3363 AtomicOp = llvm::AtomicRMWInst::Xor;
3364 Op = llvm::Instruction::Xor;
3367 AtomicOp = llvm::AtomicRMWInst::Or;
3368 Op = llvm::Instruction::Or;
3371 llvm_unreachable(
"Invalid compound assignment type");
3373 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3375 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3378 Value *OldVal = Builder.CreateAtomicRMW(
3380 llvm::AtomicOrdering::SequentiallyConsistent);
3384 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3390 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3392 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3394 Builder.CreateBr(opBB);
3395 Builder.SetInsertPoint(opBB);
3396 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3397 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3398 OpInfo.LHS = atomicPHI;
3401 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3403 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3405 if (!PromotionTypeLHS.
isNull())
3406 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3409 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3417 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
3418 ScalarConversionOpts(CGF.
SanOpts));
3421 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3425 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3426 llvm::Value *
success = Pair.second;
3427 atomicPHI->addIncoming(old, curBlock);
3428 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3429 Builder.SetInsertPoint(contBB);
3449 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3450 bool Ignore = TestAndClearIgnoreResultAssign();
3451 Value *RHS =
nullptr;
3452 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
3467 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3470void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3471 const BinOpInfo &Ops, llvm::Value *Zero,
bool isDiv) {
3474 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3475 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
3476 SanitizerKind::IntegerDivideByZero));
3479 const auto *BO = cast<BinaryOperator>(Ops.E);
3480 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
3481 Ops.Ty->hasSignedIntegerRepresentation() &&
3483 Ops.mayHaveIntegerOverflow()) {
3484 llvm::IntegerType *Ty = cast<llvm::IntegerType>(
Zero->getType());
3486 llvm::Value *IntMin =
3487 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3488 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
3490 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
3491 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
3492 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
3494 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3497 if (Checks.size() > 0)
3498 EmitBinOpCheck(Checks, Ops);
3501Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
3503 CodeGenFunction::SanitizerScope SanScope(&CGF);
3504 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3505 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3506 Ops.Ty->isIntegerType() &&
3507 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3508 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3509 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
3510 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
3511 Ops.Ty->isRealFloatingType() &&
3512 Ops.mayHaveFloatDivisionByZero()) {
3513 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3514 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
3515 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3520 if (Ops.Ty->isConstantMatrixType()) {
3521 llvm::MatrixBuilder MB(Builder);
3524 auto *BO = cast<BinaryOperator>(Ops.E);
3528 "first operand must be a matrix");
3530 "second operand must be an arithmetic type");
3531 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3532 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3533 Ops.Ty->hasUnsignedIntegerRepresentation());
3536 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3538 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3539 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3543 else if (Ops.isFixedPointOp())
3544 return EmitFixedPointBinOp(Ops);
3545 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3546 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3548 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3551Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3553 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3554 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3555 Ops.Ty->isIntegerType() &&
3556 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3557 CodeGenFunction::SanitizerScope SanScope(&CGF);
3558 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3559 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3562 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3563 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3565 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3568Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3573 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3574 switch (Ops.Opcode) {
3578 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3579 llvm::Intrinsic::uadd_with_overflow;
3580 OverflowKind = SanitizerHandler::AddOverflow;
3585 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3586 llvm::Intrinsic::usub_with_overflow;
3587 OverflowKind = SanitizerHandler::SubOverflow;
3592 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3593 llvm::Intrinsic::umul_with_overflow;
3594 OverflowKind = SanitizerHandler::MulOverflow;
3597 llvm_unreachable(
"Unsupported operation for overflow detection");
3603 CodeGenFunction::SanitizerScope SanScope(&CGF);
3608 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3609 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3610 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3613 const std::string *handlerName =
3615 if (handlerName->empty()) {
3618 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3619 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3621 : SanitizerKind::UnsignedIntegerOverflow;
3622 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3624 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
3629 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3630 llvm::BasicBlock *continueBB =
3634 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3638 Builder.SetInsertPoint(overflowBB);
3641 llvm::Type *Int8Ty = CGF.
Int8Ty;
3642 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
3643 llvm::FunctionType *handlerTy =
3644 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3645 llvm::FunctionCallee handler =
3650 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
3651 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
3655 llvm::Value *handlerArgs[] = {
3658 Builder.getInt8(OpID),
3659 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3661 llvm::Value *handlerResult =
3665 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3666 Builder.CreateBr(continueBB);
3668 Builder.SetInsertPoint(continueBB);
3669 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3670 phi->addIncoming(result, initialBB);
3671 phi->addIncoming(handlerResult, overflowBB);
3678 const BinOpInfo &op,
3679 bool isSubtraction) {
3684 Value *pointer = op.LHS;
3685 Expr *pointerOperand =
expr->getLHS();
3686 Value *index = op.RHS;
3687 Expr *indexOperand =
expr->getRHS();
3690 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
3691 std::swap(pointer, index);
3692 std::swap(pointerOperand, indexOperand);
3697 unsigned width = cast<llvm::IntegerType>(index->
getType())->getBitWidth();
3699 auto PtrTy = cast<llvm::PointerType>(pointer->
getType());
3724 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
3727 index = CGF.
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
3733 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3735 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
3745 llvm::Value *objectSize
3748 index = CGF.
Builder.CreateMul(index, objectSize);
3767 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
3770 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
3772 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
3791 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
3802 bool negMul,
bool negAdd) {
3803 Value *MulOp0 = MulOp->getOperand(0);
3804 Value *MulOp1 = MulOp->getOperand(1);
3806 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
3808 Addend = Builder.CreateFNeg(Addend,
"neg");
3810 Value *FMulAdd =
nullptr;
3811 if (Builder.getIsFPConstrained()) {
3812 assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
3813 "Only constrained operation should be created when Builder is in FP "
3814 "constrained mode");
3815 FMulAdd = Builder.CreateConstrainedFPCall(
3816 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
3818 {MulOp0, MulOp1, Addend});
3820 FMulAdd = Builder.CreateCall(
3822 {MulOp0, MulOp1, Addend});
3824 MulOp->eraseFromParent();
3839 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
3840 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
3841 "Only fadd/fsub can be the root of an fmuladd.");
3844 if (!op.FPFeatures.allowFPContractWithinStatement())
3847 Value *LHS = op.LHS;
3848 Value *RHS = op.RHS;
3852 bool NegLHS =
false;
3853 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
3854 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
3855 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
3856 LHS = LHSUnOp->getOperand(0);
3861 bool NegRHS =
false;
3862 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
3863 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
3864 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
3865 RHS = RHSUnOp->getOperand(0);
3873 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
3874 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3875 (LHSBinOp->use_empty() || NegLHS)) {
3878 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
3879 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
3882 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
3883 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3884 (RHSBinOp->use_empty() || NegRHS)) {
3887 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
3888 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
3892 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
3893 if (LHSBinOp->getIntrinsicID() ==
3894 llvm::Intrinsic::experimental_constrained_fmul &&
3895 (LHSBinOp->use_empty() || NegLHS)) {
3898 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
3899 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
3902 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
3903 if (RHSBinOp->getIntrinsicID() ==
3904 llvm::Intrinsic::experimental_constrained_fmul &&
3905 (RHSBinOp->use_empty() || NegRHS)) {
3908 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
3909 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
3916Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
3917 if (op.LHS->getType()->isPointerTy() ||
3918 op.RHS->getType()->isPointerTy())
3921 if (op.Ty->isSignedIntegerOrEnumerationType()) {
3922 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3924 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3925 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3928 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3929 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3932 if (CanElideOverflowCheck(CGF.
getContext(), op))
3933 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3934 return EmitOverflowCheckedBinOp(op);
3939 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3940 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
3946 if (op.Ty->isConstantMatrixType()) {
3947 llvm::MatrixBuilder MB(Builder);
3948 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
3949 return MB.CreateAdd(op.LHS, op.RHS);
3952 if (op.Ty->isUnsignedIntegerType() &&
3953 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3954 !CanElideOverflowCheck(CGF.
getContext(), op))
3955 return EmitOverflowCheckedBinOp(op);
3957 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3958 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
3959 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
3962 if (op.isFixedPointOp())
3963 return EmitFixedPointBinOp(op);
3965 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3970Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
3972 using llvm::ConstantInt;
3980 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
3981 RHSTy = BinOp->getRHS()->getType();
3982 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
3987 LHSTy = CAO->getComputationLHSType();
3988 ResultTy = CAO->getComputationResultType();
3990 LHSTy = BinOp->getLHS()->getType();
3991 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
3992 LHSTy = UnOp->getSubExpr()->getType();
3993 RHSTy = UnOp->getSubExpr()->getType();
3996 Value *LHS = op.LHS;
3997 Value *RHS = op.RHS;
4002 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4006 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4007 switch (op.Opcode) {
4010 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4014 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4018 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4022 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4026 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4030 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4033 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4035 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4037 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4039 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4044 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4046 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4050 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4063 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4069 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4074Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4076 if (!op.LHS->getType()->isPointerTy()) {
4077 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4078 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4080 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4081 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4084 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4085 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4088 if (CanElideOverflowCheck(CGF.
getContext(), op))
4089 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4090 return EmitOverflowCheckedBinOp(op);
4095 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4096 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4102 if (op.Ty->isConstantMatrixType()) {
4103 llvm::MatrixBuilder MB(Builder);
4104 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4105 return MB.CreateSub(op.LHS, op.RHS);
4108 if (op.Ty->isUnsignedIntegerType() &&
4109 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4110 !CanElideOverflowCheck(CGF.
getContext(), op))
4111 return EmitOverflowCheckedBinOp(op);
4113 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4114 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4115 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4118 if (op.isFixedPointOp())
4119 return EmitFixedPointBinOp(op);
4121 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4126 if (!op.RHS->getType()->isPointerTy())
4133 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4135 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4136 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4140 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4142 llvm::Value *divisor =
nullptr;
4148 elementType = VlaSize.Type;
4149 divisor = VlaSize.NumElts;
4153 if (!eltSize.
isOne())
4169 if (elementSize.
isOne())
4178 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4181Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS) {
4182 llvm::IntegerType *Ty;
4183 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4184 Ty = cast<llvm::IntegerType>(VT->getElementType());
4186 Ty = cast<llvm::IntegerType>(LHS->
getType());
4191 llvm::Type *RHSTy = RHS->
getType();
4192 llvm::APInt RHSMax = llvm::APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4193 if (RHSMax.ult(Ty->getBitWidth()))
4194 return llvm::ConstantInt::get(RHSTy, RHSMax);
4195 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4199 const Twine &Name) {
4200 llvm::IntegerType *Ty;
4201 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4202 Ty = cast<llvm::IntegerType>(VT->getElementType());
4204 Ty = cast<llvm::IntegerType>(LHS->
getType());
4206 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4207 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS), Name);
4209 return Builder.CreateURem(
4210 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4213Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4215 if (Ops.isFixedPointOp())
4216 return EmitFixedPointBinOp(Ops);
4220 Value *RHS = Ops.RHS;
4221 if (Ops.LHS->getType() != RHS->
getType())
4222 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4224 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4225 Ops.Ty->hasSignedIntegerRepresentation() &&
4228 bool SanitizeUnsignedBase =
4229 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4230 Ops.Ty->hasUnsignedIntegerRepresentation();
4231 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4232 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4235 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4236 else if ((SanitizeBase || SanitizeExponent) &&
4237 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4238 CodeGenFunction::SanitizerScope SanScope(&CGF);
4240 llvm::Value *WidthMinusOne = GetMaximumShiftAmount(Ops.LHS, Ops.RHS);
4241 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4243 if (SanitizeExponent) {
4245 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
4252 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4255 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4256 llvm::Value *PromotedWidthMinusOne =
4257 (RHS == Ops.RHS) ? WidthMinusOne
4258 : GetMaximumShiftAmount(Ops.LHS, RHS);
4260 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4261 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4264 if (SanitizeUnsignedBase || CGF.
getLangOpts().CPlusPlus) {
4270 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4271 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4273 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4274 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
4276 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4277 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4278 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4279 Checks.push_back(std::make_pair(
4280 BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4281 : SanitizerKind::UnsignedShiftBase));
4284 assert(!Checks.empty());
4285 EmitBinOpCheck(Checks, Ops);
4288 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4291Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4293 if (Ops.isFixedPointOp())
4294 return EmitFixedPointBinOp(Ops);
4298 Value *RHS = Ops.RHS;
4299 if (Ops.LHS->getType() != RHS->
getType())
4300 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4304 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4305 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4306 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4307 CodeGenFunction::SanitizerScope SanScope(&CGF);
4308 llvm::Value *Valid =
4309 Builder.CreateICmpULE(Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS));
4310 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
4313 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4314 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4315 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4323 default: llvm_unreachable(
"unexpected element type");
4324 case BuiltinType::Char_U:
4325 case BuiltinType::UChar:
4326 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4327 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4328 case BuiltinType::Char_S:
4329 case BuiltinType::SChar:
4330 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4331 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4332 case BuiltinType::UShort:
4333 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4334 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4335 case BuiltinType::Short:
4336 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4337 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4338 case BuiltinType::UInt:
4339 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4340 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4341 case BuiltinType::Int:
4342 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4343 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4344 case BuiltinType::ULong:
4345 case BuiltinType::ULongLong:
4346 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4347 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4348 case BuiltinType::Long:
4349 case BuiltinType::LongLong:
4350 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4351 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4352 case BuiltinType::Float:
4353 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4354 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4355 case BuiltinType::Double:
4356 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4357 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4358 case BuiltinType::UInt128:
4359 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4360 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4361 case BuiltinType::Int128:
4362 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4363 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4368 llvm::CmpInst::Predicate UICmpOpc,
4369 llvm::CmpInst::Predicate SICmpOpc,
4370 llvm::CmpInst::Predicate FCmpOpc,
4372 TestAndClearIgnoreResultAssign();
4382 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
4384 BinOpInfo BOInfo = EmitBinOps(E);
4385 Value *LHS = BOInfo.LHS;
4386 Value *RHS = BOInfo.RHS;
4392 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4394 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4397 Value *FirstVecArg = LHS,
4398 *SecondVecArg = RHS;
4404 default: llvm_unreachable(
"is not a comparison operation");
4416 std::swap(FirstVecArg, SecondVecArg);
4423 if (ElementKind == BuiltinType::Float) {
4425 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4426 std::swap(FirstVecArg, SecondVecArg);
4434 if (ElementKind == BuiltinType::Float) {
4436 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4441 std::swap(FirstVecArg, SecondVecArg);
4446 Value *CR6Param = Builder.getInt32(CR6);
4448 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
4455 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(
Result->getType());
4456 if (ResultTy->getBitWidth() > 1 &&
4458 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
4463 if (BOInfo.isFixedPointOp()) {
4464 Result = EmitFixedPointBinOp(BOInfo);
4465 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
4466 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4468 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
4470 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
4472 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
4477 !isa<llvm::ConstantPointerNull>(LHS) &&
4478 !isa<llvm::ConstantPointerNull>(RHS)) {
4487 LHS = Builder.CreateStripInvariantGroup(LHS);
4489 RHS = Builder.CreateStripInvariantGroup(RHS);
4492 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
4498 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
4506 CETy = CTy->getElementType();
4508 LHS.first = Visit(E->
getLHS());
4509 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
4515 CTy->getElementType()) &&
4516 "The element types must always match.");
4519 RHS.first = Visit(E->
getRHS());
4520 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
4522 "The element types must always match.");
4525 Value *ResultR, *ResultI;
4529 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
4530 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
4534 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
4535 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
4539 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
4542 "Complex comparison other than == or != ?");
4543 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
4552 bool Ignore = TestAndClearIgnoreResultAssign();
4571 RHS = Visit(E->
getRHS());
4579 RHS = Visit(E->
getRHS());
4607 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4618 if (LHS->
getType()->isFPOrFPVectorTy()) {
4619 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4621 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4622 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4624 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4625 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4627 Value *
And = Builder.CreateAnd(LHS, RHS);
4628 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
4632 llvm::Type *ResTy = ConvertType(E->
getType());
4653 if (InstrumentRegions &&
4658 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4671 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
4676 return llvm::Constant::getNullValue(ResTy);
4688 CodeGenFunction::ConditionalEvaluation eval(CGF);
4697 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
4699 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4701 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
4710 RHSBlock = Builder.GetInsertBlock();
4715 if (InstrumentRegions &&
4719 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
4723 PN->addIncoming(RHSCond, RHSBlockCnt);
4733 PN->addIncoming(RHSCond, RHSBlock);
4743 PN->setDebugLoc(Builder.getCurrentDebugLocation());
4747 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
4758 if (LHS->
getType()->isFPOrFPVectorTy()) {
4759 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4761 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4762 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4764 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4765 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4767 Value *
Or = Builder.CreateOr(LHS, RHS);
4768 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
4772 llvm::Type *ResTy = ConvertType(E->
getType());
4793 if (InstrumentRegions &&
4798 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
4811 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
4816 return llvm::ConstantInt::get(ResTy, 1);
4828 CodeGenFunction::ConditionalEvaluation eval(CGF);
4838 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
4840 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4842 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
4854 RHSBlock = Builder.GetInsertBlock();
4859 if (InstrumentRegions &&
4863 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
4867 PN->addIncoming(RHSCond, RHSBlockCnt);
4873 PN->addIncoming(RHSCond, RHSBlock);
4881 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
4887 return Visit(E->
getRHS());
4912Value *ScalarExprEmitter::
4914 TestAndClearIgnoreResultAssign();
4917 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
4927 Expr *live = lhsExpr, *dead = rhsExpr;
4928 if (!CondExprBool) std::swap(live, dead);
4958 llvm::Value *LHS = Visit(lhsExpr);
4959 llvm::Value *RHS = Visit(rhsExpr);
4961 llvm::Type *condType = ConvertType(condExpr->
getType());
4962 auto *vecTy = cast<llvm::FixedVectorType>(condType);
4964 unsigned numElem = vecTy->getNumElements();
4965 llvm::Type *elemType = vecTy->getElementType();
4967 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
4968 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
4969 llvm::Value *tmp = Builder.CreateSExt(
4970 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
4971 llvm::Value *tmp2 = Builder.CreateNot(tmp);
4974 llvm::Value *RHSTmp = RHS;
4975 llvm::Value *LHSTmp = LHS;
4976 bool wasCast =
false;
4977 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
4978 if (rhsVTy->getElementType()->isFloatingPointTy()) {
4979 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
4980 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
4984 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
4985 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
4986 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
4988 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
4998 llvm::Value *LHS = Visit(lhsExpr);
4999 llvm::Value *RHS = Visit(rhsExpr);
5001 llvm::Type *CondType = ConvertType(condExpr->
getType());
5002 auto *VecTy = cast<llvm::VectorType>(CondType);
5003 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5005 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5006 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5015 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5024 llvm::Value *LHS = Visit(lhsExpr);
5025 llvm::Value *RHS = Visit(rhsExpr);
5028 assert(!RHS &&
"LHS and RHS types must match");
5031 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5042 CodeGenFunction::ConditionalEvaluation eval(CGF);
5060 Value *LHS = Visit(lhsExpr);
5063 LHSBlock = Builder.GetInsertBlock();
5064 Builder.CreateBr(ContBlock);
5078 Value *RHS = Visit(rhsExpr);
5081 RHSBlock = Builder.GetInsertBlock();
5091 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5092 PN->addIncoming(LHS, LHSBlock);
5093 PN->addIncoming(RHS, RHSBlock);
5116 llvm::Type *ArgTy = ConvertType(VE->
getType());
5121 return llvm::UndefValue::get(ArgTy);
5125 llvm::Value *Val = Builder.CreateLoad(ArgPtr);
5128 if (ArgTy != Val->getType()) {
5129 if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
5130 Val = Builder.CreateIntToPtr(Val, ArgTy);
5132 Val = Builder.CreateTrunc(Val, ArgTy);
5138Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5144 Value *Src,
unsigned NumElementsDst) {
5145 static constexpr int Mask[] = {0, 1, 2, -1};
5146 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5166 const llvm::DataLayout &DL,
5167 Value *Src, llvm::Type *DstTy,
5168 StringRef Name =
"") {
5172 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5173 return Builder.CreateBitCast(Src, DstTy, Name);
5176 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5177 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5180 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5182 if (!DstTy->isIntegerTy())
5183 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5185 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5189 if (!SrcTy->isIntegerTy())
5190 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5192 return Builder.CreateIntToPtr(Src, DstTy, Name);
5197 llvm::Type *DstTy = ConvertType(E->
getType());
5199 llvm::Type *SrcTy = Src->
getType();
5200 unsigned NumElementsSrc =
5201 isa<llvm::VectorType>(SrcTy)
5202 ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5204 unsigned NumElementsDst =
5205 isa<llvm::VectorType>(DstTy)
5206 ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5215 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5220 Src->setName(
"astype");
5227 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5228 auto *Vec4Ty = llvm::FixedVectorType::get(
5229 cast<llvm::VectorType>(DstTy)->getElementType(), 4);
5234 Src->setName(
"astype");
5239 Src, DstTy,
"astype");
5254 "Invalid scalar expression to emit");
5256 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5257 .Visit(
const_cast<Expr *
>(E));
5266 "Invalid scalar expression to emit");
5267 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
5277 "Invalid complex -> scalar conversion");
5278 return ScalarExprEmitter(*
this)
5279 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
5286 if (!PromotionType.
isNull())
5287 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5289 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
5295 bool isInc,
bool isPre) {
5296 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
5306 llvm::Type *BaseTy =
5321 ScalarExprEmitter
Scalar(*
this);
5324#define COMPOUND_OP(Op) \
5325 case BO_##Op##Assign: \
5326 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5363 llvm_unreachable(
"Not valid compound assignment operators");
5366 llvm_unreachable(
"Unhandled compound assignment operator");
5381 llvm::LLVMContext &VMContext,
5387 llvm::Value *TotalOffset =
nullptr;
5390 if (isa<llvm::Constant>(GEPVal)) {
5393 Value *BasePtr_int =
5394 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
5396 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
5397 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5398 return {TotalOffset, Builder.getFalse()};
5401 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5402 assert(GEP->getPointerOperand() == BasePtr &&
5403 "BasePtr must be the base of the GEP.");
5404 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
5406 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
5409 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5410 auto *SAddIntrinsic =
5411 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
5412 auto *SMulIntrinsic =
5413 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
5416 llvm::Value *OffsetOverflows = Builder.getFalse();
5420 llvm::Value *RHS) -> llvm::Value * {
5421 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
5424 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
5425 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
5427 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
5430 OffsetOverflows = Builder.getTrue();
5431 return llvm::ConstantInt::get(VMContext, N);
5436 auto *ResultAndOverflow = Builder.CreateCall(
5437 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
5438 OffsetOverflows = Builder.CreateOr(
5439 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
5440 return Builder.CreateExtractValue(ResultAndOverflow, 0);
5444 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
5445 GTI != GTE; ++GTI) {
5446 llvm::Value *LocalOffset;
5447 auto *Index = GTI.getOperand();
5449 if (
auto *STy = GTI.getStructTypeOrNull()) {
5452 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
5453 LocalOffset = llvm::ConstantInt::get(
5454 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
5459 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
5460 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
5461 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
5466 if (!TotalOffset || TotalOffset == Zero)
5467 TotalOffset = LocalOffset;
5469 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
5472 return {TotalOffset, OffsetOverflows};
5478 bool SignedIndices,
bool IsSubtraction,
5480 llvm::Type *PtrTy = Ptr->
getType();
5481 Value *GEPVal =
Builder.CreateInBoundsGEP(ElemTy, Ptr, IdxList, Name);
5484 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5488 bool PerformNullCheck = !NullPointerIsDefined(
5489 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5492 bool PerformOverflowCheck =
5493 !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5495 if (!(PerformNullCheck || PerformOverflowCheck))
5500 SanitizerScope SanScope(
this);
5501 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
5506 assert((!isa<llvm::Constant>(EvaluatedGEP.
TotalOffset) ||
5508 "If the offset got constant-folded, we don't expect that there was an "
5511 auto *
Zero = llvm::ConstantInt::getNullValue(
IntPtrTy);
5525 if (PerformNullCheck) {
5537 auto *BaseIsNotNullptr =
Builder.CreateIsNotNull(Ptr);
5538 auto *ResultIsNotNullptr =
Builder.CreateIsNotNull(ComputedGEP);
5541 ?
Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5542 :
Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5543 Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5546 if (PerformOverflowCheck) {
5551 llvm::Value *ValidGEP;
5553 if (SignedIndices) {
5559 auto *PosOrZeroValid =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5560 auto *PosOrZeroOffset =
5562 llvm::Value *NegValid =
Builder.CreateICmpULT(ComputedGEP, IntPtr);
5564 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5570 ValidGEP =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5576 ValidGEP =
Builder.CreateICmpULE(ComputedGEP, IntPtr);
5578 ValidGEP =
Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5579 Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5582 assert(!Checks.empty() &&
"Should have produced some checks.");
5586 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5587 EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
CodeGenFunction::ComplexPairTy ComplexPairTy
#define VISITCOMP(CODE, UI, SI, FP, SIG)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static Value * emitPointerArithmetic(CodeGenFunction &CGF, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, CodeGenFunction &CGF)
isCheapEnoughToEvaluateUnconditionally - Return true if the specified expression is cheap enough and ...
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static Decl::Kind getKind(const Decl *D)
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
const LangOptions & getLangOpts() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
AddrLabelExpr - The GNU address of label extension, representing &&label.
LabelDecl * getLabel() const
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
uint64_t getValue() const
QualType getElementType() const
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
This class is used for builtin types like 'int'.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
A boolean literal, per ([C++ lex.bool] Boolean literals).
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a delete expression for memory deallocation and destructor calls, e.g.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Represents a C++ struct/union/class.
A rewritten comparison expression that was originally written using operator syntax.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
unsigned getValue() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Represents a 'co_await' expression.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::Value * getPointer() const
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateGEP(Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, QualType Type, CharUnits Alignment=CharUnits::Zero(), SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
Emit a check that V is the address of storage of the appropriate size and alignment for an object of ...
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
SanitizerSet SanOpts
Sanitizers enabled for this function.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
static bool hasScalarEvaluationKind(QualType T)
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
const TargetInfo & getTarget() const
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
CGDebugInfo * getDebugInfo()
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
Address CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
llvm::Type * ConvertType(QualType T)
Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr)
Generate code to get an argument from the passed in pointer and update it accordingly.
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot())
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
RValue EmitAtomicExpr(AtomicExpr *E)
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
void setTBAAInfo(TBAAAccessInfo Info)
Address getAddress(CodeGenFunction &CGF) const
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
virtual llvm::Value * performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, llvm::Value *V, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Perform address space cast of an expression of pointer type.
Complex values, per C99 6.2.5p11.
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
CompoundLiteralExpr - [C99 6.5.2.5].
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumRows() const
Returns the number of rows in the matrix.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents a 'co_yield' expression.
const Expr * getDefaultExpr() const
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
A reference to a declared variable, function, enum, etc.
ExplicitCastExpr - An explicit cast written in the source code.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
An expression trait intrinsic.
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
unsigned getNumInits() const
bool hadArrayRangeDesignator() const
const Expr * getInit(unsigned Init) const
bool isSignedOverflowDefined() const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Represents a matrix type, as defined in the Matrix Types clang extensions.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
A runtime availability query.
VersionTuple getVersion() const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
SourceLocation getExprLoc() const LLVM_READONLY
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
ObjCProtocolExpr used for protocol expression in Objective-C.
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
ParenExpr - This represents a parethesized expression, e.g.
const Expr * getSubExpr() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Represents a struct/union/class.
field_iterator field_end() const
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
Sema - This implements semantic analysis and AST building for C.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Represents an expression that computes the length of a parameter pack.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
CompoundStmt * getSubStmt()
RetTy Visit(PTR(Stmt) S, ParamTys... P)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represents a call to the builtin function __builtin_va_arg.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
VectorKind getVectorKind() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool LE(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
@ Generic
not a target-specific vector type
YAML serialization mapping.
cl::opt< bool > EnableSingleByteCoverage
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.