29 #include "llvm/ADT/Optional.h" 30 #include "llvm/IR/CFG.h" 31 #include "llvm/IR/Constants.h" 32 #include "llvm/IR/DataLayout.h" 33 #include "llvm/IR/Function.h" 34 #include "llvm/IR/GetElementPtrTypeIterator.h" 35 #include "llvm/IR/GlobalVariable.h" 36 #include "llvm/IR/Intrinsics.h" 37 #include "llvm/IR/Module.h" 40 using namespace clang;
41 using namespace CodeGen;
55 bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
57 llvm::APInt &Result) {
60 const auto &LHSAP = LHS->getValue();
61 const auto &RHSAP = RHS->getValue();
62 if (Opcode == BO_Add) {
64 Result = LHSAP.sadd_ov(RHSAP, Overflow);
66 Result = LHSAP.uadd_ov(RHSAP, Overflow);
67 }
else if (Opcode == BO_Sub) {
69 Result = LHSAP.ssub_ov(RHSAP, Overflow);
71 Result = LHSAP.usub_ov(RHSAP, Overflow);
72 }
else if (Opcode == BO_Mul) {
74 Result = LHSAP.smul_ov(RHSAP, Overflow);
76 Result = LHSAP.umul_ov(RHSAP, Overflow);
77 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
78 if (Signed && !RHS->isZero())
79 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
95 bool mayHaveIntegerOverflow()
const {
97 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
98 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
103 return ::mayHaveIntegerOverflow(
108 bool isDivremOp()
const {
109 return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
110 Opcode == BO_RemAssign;
114 bool mayHaveIntegerDivisionByZero()
const {
116 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
122 bool mayHaveFloatDivisionByZero()
const {
124 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
125 return CFP->isZero();
133 bool isFixedPointBinOp()
const {
136 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
137 QualType LHSType = BinOp->getLHS()->getType();
138 QualType RHSType = BinOp->getRHS()->getType();
145 static bool MustVisitNullValue(
const Expr *E) {
168 static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
169 return getUnwidenedIntegerType(Ctx, E).hasValue();
173 static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
174 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
175 "Expected a unary or binary operator");
179 if (!Op.mayHaveIntegerOverflow())
183 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
184 return !UO->canOverflow();
188 const auto *BO = cast<BinaryOperator>(Op.E);
189 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
193 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
202 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
208 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
209 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
214 static void updateFastMathFlags(llvm::FastMathFlags &FMF,
220 static Value *propagateFMFlags(
Value *
V,
const BinOpInfo &Op) {
221 if (
auto *I = dyn_cast<llvm::Instruction>(V)) {
222 llvm::FastMathFlags FMF = I->getFastMathFlags();
223 updateFastMathFlags(FMF, Op.FPFeatures);
224 I->setFastMathFlags(FMF);
229 class ScalarExprEmitter
233 bool IgnoreResultAssign;
234 llvm::LLVMContext &VMContext;
238 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
239 VMContext(cgf.getLLVMContext()) {
246 bool TestAndClearIgnoreResultAssign() {
247 bool I = IgnoreResultAssign;
248 IgnoreResultAssign =
false;
258 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
259 const BinOpInfo &Info);
265 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *V) {
266 const AlignValueAttr *AVAttr =
nullptr;
267 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
271 if (
const auto *TTy =
273 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
280 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
283 AVAttr = VD->
getAttr<AlignValueAttr>();
288 if (
const auto *TTy =
289 dyn_cast<TypedefType>(E->
getType()))
290 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
296 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
298 AlignmentCI->getZExtValue());
308 EmitLValueAlignmentAssumption(E, V);
318 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
324 enum ImplicitConversionCheckKind :
unsigned char {
325 ICCK_IntegerTruncation = 0,
326 ICCK_UnsignedIntegerTruncation = 1,
327 ICCK_SignedIntegerTruncation = 2,
328 ICCK_IntegerSignChange = 3,
329 ICCK_SignedIntegerTruncationOrSignChange = 4,
345 struct ScalarConversionOpts {
346 bool TreatBooleanAsSigned;
347 bool EmitImplicitIntegerTruncationChecks;
348 bool EmitImplicitIntegerSignChangeChecks;
350 ScalarConversionOpts()
351 : TreatBooleanAsSigned(
false),
352 EmitImplicitIntegerTruncationChecks(
false),
353 EmitImplicitIntegerSignChangeChecks(
false) {}
356 : TreatBooleanAsSigned(
false),
357 EmitImplicitIntegerTruncationChecks(
359 EmitImplicitIntegerSignChangeChecks(
365 ScalarConversionOpts Opts = ScalarConversionOpts());
374 bool DstIsInteger =
false);
388 llvm::Value *Zero = llvm::Constant::getNullValue(V->getType());
389 return Builder.CreateFCmpUNE(V, Zero,
"tobool");
396 return Builder.CreateICmpNE(V, Zero,
"tobool");
403 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
404 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
405 Value *Result = ZI->getOperand(0);
410 ZI->eraseFromParent();
415 return Builder.CreateIsNotNull(V,
"tobool");
429 llvm_unreachable(
"Stmt can't have complex result type!");
457 return Builder.getInt(E->
getValue());
460 return Builder.getInt(E->
getValue());
463 return llvm::ConstantFP::get(VMContext, E->
getValue());
466 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
469 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
472 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
475 return EmitNullValue(E->
getType());
478 return EmitNullValue(E->
getType());
508 return EmitLoadOfLValue(E);
518 return EmitLoadOfLValue(E);
523 return EmitLoadOfLValue(E);
539 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
543 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, Version.getMajor()),
544 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, Min ? *Min : 0),
545 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, SMin ? *SMin : 0),
555 Value *VisitExtVectorElementExpr(
Expr *E) {
return EmitLoadOfLValue(E); }
557 return EmitLoadOfLValue(E);
564 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
569 return EmitNullValue(E->
getType());
573 return VisitCastExpr(E);
579 return EmitLoadOfLValue(E);
583 EmitLValueAlignmentAssumption(E, V);
592 return EmitScalarPrePostIncDec(E, LV,
false,
false);
596 return EmitScalarPrePostIncDec(E, LV,
true,
false);
600 return EmitScalarPrePostIncDec(E, LV,
false,
true);
604 return EmitScalarPrePostIncDec(E, LV,
true,
true);
612 bool isInc,
bool isPre);
616 if (isa<MemberPointerType>(E->
getType()))
619 return EmitLValue(E->
getSubExpr()).getPointer();
624 return EmitLoadOfLValue(E);
628 TestAndClearIgnoreResultAssign();
642 return EmitLoadOfLValue(E);
674 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
678 return llvm::ConstantInt::get(Builder.getInt32Ty(), E->
getValue());
682 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
696 return EmitNullValue(E->
getType());
705 return Builder.getInt1(E->
getValue());
709 Value *EmitMul(
const BinOpInfo &Ops) {
710 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
711 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
713 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
715 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
716 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
719 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
720 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
721 return EmitOverflowCheckedBinOp(Ops);
725 if (Ops.Ty->isUnsignedIntegerType() &&
726 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
727 !CanElideOverflowCheck(CGF.
getContext(), Ops))
728 return EmitOverflowCheckedBinOp(Ops);
730 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
731 Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
732 return propagateFMFlags(V, Ops);
734 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
738 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
741 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
745 Value *EmitDiv(
const BinOpInfo &Ops);
746 Value *EmitRem(
const BinOpInfo &Ops);
747 Value *EmitAdd(
const BinOpInfo &Ops);
748 Value *EmitSub(
const BinOpInfo &Ops);
749 Value *EmitShl(
const BinOpInfo &Ops);
750 Value *EmitShr(
const BinOpInfo &Ops);
751 Value *EmitAnd(
const BinOpInfo &Ops) {
752 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
754 Value *EmitXor(
const BinOpInfo &Ops) {
755 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
757 Value *EmitOr (
const BinOpInfo &Ops) {
758 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
762 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
766 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
770 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
773 #define HANDLEBINOP(OP) \ 774 Value *VisitBin ## OP(const BinaryOperator *E) { \ 775 return Emit ## OP(EmitBinOps(E)); \ 777 Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \ 778 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \ 794 llvm::CmpInst::Predicate SICmpOpc,
795 llvm::CmpInst::Predicate FCmpOpc);
796 #define VISITCOMP(CODE, UI, SI, FP) \ 797 Value *VisitBin##CODE(const BinaryOperator *E) { \ 798 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \ 799 llvm::FCmpInst::FP); } 801 VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT)
802 VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE)
803 VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE)
804 VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ)
805 VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE)
814 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
815 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
846 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
849 return EmitFloatToBoolConversion(Src);
854 assert((SrcType->
isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
855 "Unknown scalar type to convert");
857 if (isa<llvm::IntegerType>(Src->getType()))
858 return EmitIntToBoolConversion(Src);
860 assert(isa<llvm::PointerType>(Src->getType()));
861 return EmitPointerToBoolConversion(Src, SrcType);
864 void ScalarExprEmitter::EmitFloatConversionCheck(
867 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
868 if (!isa<llvm::IntegerType>(DstTy))
876 const llvm::fltSemantics &SrcSema =
885 APSInt Min = APSInt::getMinValue(Width, Unsigned);
886 APFloat MinSrc(SrcSema, APFloat::uninitialized);
887 if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
891 MinSrc = APFloat::getInf(SrcSema,
true);
895 MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
897 APSInt Max = APSInt::getMaxValue(Width, Unsigned);
898 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
899 if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
903 MaxSrc = APFloat::getInf(SrcSema,
false);
907 MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
912 const llvm::fltSemantics &
Sema =
915 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
916 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
920 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
922 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
923 Check = Builder.CreateAnd(GE, LE);
928 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
929 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
934 static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
935 std::pair<llvm::Value *, SanitizerMask>>
944 assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits());
945 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
946 "non-integer llvm type");
953 ScalarExprEmitter::ImplicitConversionCheckKind
Kind;
955 if (!SrcSigned && !DstSigned) {
956 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
957 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
959 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
960 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
965 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
967 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
969 return std::make_pair(Kind, std::make_pair(Check, Mask));
972 void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
983 unsigned SrcBits = Src->getType()->getScalarSizeInBits();
984 unsigned DstBits = Dst->getType()->getScalarSizeInBits();
986 if (SrcBits <= DstBits)
989 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
996 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
997 (!SrcSigned && DstSigned))
1002 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1003 std::pair<llvm::Value *, SanitizerMask>>
1012 llvm::Constant *StaticArgs[] = {
1015 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)};
1016 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1022 static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1023 std::pair<llvm::Value *, SanitizerMask>>
1029 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1030 "non-integer llvm type");
1036 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1037 unsigned DstBits = DstTy->getScalarSizeInBits();
1041 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1042 "either the widths should be different, or the signednesses.");
1046 const char *Name) ->
Value * {
1048 bool VSigned = VType->isSignedIntegerOrEnumerationType();
1053 return llvm::ConstantInt::getFalse(VTy->getContext());
1056 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1059 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
1060 llvm::Twine(Name) +
"." + V->getName() +
1061 ".negativitycheck");
1065 llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType,
"src");
1067 llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType,
"dst");
1073 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1075 return std::make_pair(
1076 ScalarExprEmitter::ICCK_IntegerSignChange,
1077 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1080 void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1083 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1096 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1097 unsigned DstBits = DstTy->getScalarSizeInBits();
1104 if (SrcSigned == DstSigned && SrcBits == DstBits)
1108 if (!SrcSigned && !DstSigned)
1113 if ((DstBits > SrcBits) && DstSigned)
1115 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1116 (SrcBits > DstBits) && SrcSigned) {
1126 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1127 std::pair<llvm::Value *, SanitizerMask>>
1131 ImplicitConversionCheckKind CheckKind;
1137 CheckKind = Check.first;
1138 Checks.emplace_back(Check.second);
1140 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1141 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1147 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1148 Checks.emplace_back(Check.second);
1152 llvm::Constant *StaticArgs[] = {
1155 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)};
1157 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1166 ScalarConversionOpts Opts) {
1181 return Builder.CreateIsNotNull(Src,
"tobool");
1183 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1186 "Unhandled scalar conversion from a fixed point type to another type.");
1190 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1193 "Unhandled scalar conversion to a fixed point type from another type.");
1196 QualType NoncanonicalSrcType = SrcType;
1197 QualType NoncanonicalDstType = DstType;
1201 if (SrcType == DstType)
return Src;
1211 return EmitConversionToBool(Src, SrcType);
1218 if (DstTy->isFloatingPointTy()) {
1220 return Builder.CreateCall(
1228 Src = Builder.CreateCall(
1233 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1241 if (SrcTy == DstTy) {
1242 if (Opts.EmitImplicitIntegerSignChangeChecks)
1243 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1244 NoncanonicalDstType, Loc);
1252 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1254 if (isa<llvm::PointerType>(SrcTy))
1257 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1263 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1265 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1268 if (isa<llvm::PointerType>(SrcTy)) {
1270 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1271 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1280 "Splatted expr doesn't match with vector element type?");
1283 unsigned NumElements = DstTy->getVectorNumElements();
1284 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1287 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1289 unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
1290 unsigned DstSize = DstTy->getPrimitiveSizeInBits();
1291 if (SrcSize == DstSize)
1301 llvm::Type *SrcElementTy = SrcTy->getVectorElementType();
1302 llvm::Type *DstElementTy = DstTy->getVectorElementType();
1305 assert(((SrcElementTy->isIntegerTy() &&
1306 DstElementTy->isIntegerTy()) ||
1307 (SrcElementTy->isFloatingPointTy() &&
1308 DstElementTy->isFloatingPointTy())) &&
1309 "unexpected conversion between a floating-point vector and an " 1313 if (SrcElementTy->isIntegerTy())
1314 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1317 if (SrcSize > DstSize)
1318 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1321 return Builder.CreateFPExt(Src, DstTy,
"conv");
1325 Value *Res =
nullptr;
1333 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1335 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1341 if (SrcTy->isFloatingPointTy()) {
1345 return Builder.CreateCall(
1348 return Builder.CreateFPTrunc(Src, DstTy);
1353 if (isa<llvm::IntegerType>(SrcTy)) {
1355 if (SrcType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1358 if (isa<llvm::IntegerType>(DstTy))
1359 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1360 else if (InputSigned)
1361 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1363 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1364 }
else if (isa<llvm::IntegerType>(DstTy)) {
1365 assert(SrcTy->isFloatingPointTy() &&
"Unknown real conversion");
1367 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1369 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1371 assert(SrcTy->isFloatingPointTy() && DstTy->isFloatingPointTy() &&
1372 "Unknown real conversion");
1373 if (DstTy->getTypeID() < SrcTy->getTypeID())
1374 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1376 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1379 if (DstTy != ResTy) {
1381 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1382 Res = Builder.CreateCall(
1386 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1390 if (Opts.EmitImplicitIntegerTruncationChecks)
1391 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1392 NoncanonicalDstType, Loc);
1394 if (Opts.EmitImplicitIntegerSignChangeChecks)
1395 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1396 NoncanonicalDstType, Loc);
1408 return EmitFixedPointConversion(Src, SrcFPSema, DstFPSema, Loc,
1412 Value *ScalarExprEmitter::EmitFixedPointConversion(
1416 using llvm::ConstantInt;
1419 unsigned SrcWidth = SrcFPSema.
getWidth();
1420 unsigned DstWidth = DstFPSema.
getWidth();
1421 unsigned SrcScale = SrcFPSema.
getScale();
1422 unsigned DstScale = DstFPSema.
getScale();
1423 bool SrcIsSigned = SrcFPSema.
isSigned();
1424 bool DstIsSigned = DstFPSema.
isSigned();
1426 llvm::Type *DstIntTy = Builder.getIntNTy(DstWidth);
1428 Value *Result = Src;
1429 unsigned ResultWidth = SrcWidth;
1432 if (DstScale < SrcScale) {
1436 if (DstIsInteger && SrcIsSigned) {
1437 Value *Zero = llvm::Constant::getNullValue(Result->getType());
1438 Value *IsNegative = Builder.CreateICmpSLT(Result, Zero);
1439 Value *LowBits = ConstantInt::get(
1440 CGF.
getLLVMContext(), APInt::getLowBitsSet(ResultWidth, SrcScale));
1441 Value *Rounded = Builder.CreateAdd(Result, LowBits);
1442 Result = Builder.CreateSelect(IsNegative, Rounded, Result);
1445 Result = SrcIsSigned
1446 ? Builder.CreateAShr(Result, SrcScale - DstScale,
"downscale")
1447 : Builder.CreateLShr(Result, SrcScale - DstScale,
"downscale");
1452 Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
1455 if (DstScale > SrcScale)
1456 Result = Builder.CreateShl(Result, DstScale - SrcScale,
"upscale");
1459 if (DstScale > SrcScale) {
1461 ResultWidth =
std::max(SrcWidth + DstScale - SrcScale, DstWidth);
1462 llvm::Type *UpscaledTy = Builder.getIntNTy(ResultWidth);
1463 Result = Builder.CreateIntCast(Result, UpscaledTy, SrcIsSigned,
"resize");
1464 Result = Builder.CreateShl(Result, DstScale - SrcScale,
"upscale");
1470 Value *Max = ConstantInt::get(
1473 Value *TooHigh = SrcIsSigned ? Builder.CreateICmpSGT(Result, Max)
1474 : Builder.CreateICmpUGT(Result, Max);
1475 Result = Builder.CreateSelect(TooHigh, Max, Result,
"satmax");
1479 if (SrcIsSigned && (LessIntBits || !DstIsSigned)) {
1480 Value *Min = ConstantInt::get(
1483 Value *TooLow = Builder.CreateICmpSLT(Result, Min);
1484 Result = Builder.CreateSelect(TooLow, Min, Result,
"satmin");
1488 if (ResultWidth != DstWidth)
1489 Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
1496 Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1505 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1506 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1507 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1514 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1525 void ScalarExprEmitter::EmitBinOpCheck(
1526 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1538 if (UO && UO->
getOpcode() == UO_Minus) {
1539 Check = SanitizerHandler::NegateOverflow;
1541 DynamicData.push_back(Info.RHS);
1545 Check = SanitizerHandler::ShiftOutOfBounds;
1547 StaticData.push_back(
1549 StaticData.push_back(
1551 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1553 Check = SanitizerHandler::DivremOverflow;
1558 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1559 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1560 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1561 default: llvm_unreachable(
"unexpected opcode for bin op check");
1565 DynamicData.push_back(Info.LHS);
1566 DynamicData.push_back(Info.RHS);
1569 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1576 Value *ScalarExprEmitter::VisitExpr(
Expr *E) {
1590 llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType());
1591 unsigned LHSElts = LTy->getNumElements();
1595 llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType());
1599 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1600 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1608 llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(),
1609 MTy->getNumElements());
1610 Value* NewV = llvm::UndefValue::get(RTy);
1611 for (
unsigned i = 0, e = MTy->getNumElements();
i != e; ++
i) {
1613 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1615 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1616 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1628 if (Idx.isSigned() && Idx.isAllOnesValue())
1629 indices.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
1631 indices.push_back(Builder.getInt32(Idx.getZExtValue()));
1634 Value *SV = llvm::ConstantVector::get(indices);
1635 return Builder.CreateShuffleVector(V1, V2, SV,
"shuffle");
1646 if (SrcType == DstType)
return Src;
1649 "ConvertVector source type must be a vector");
1651 "ConvertVector destination type must be a vector");
1663 assert(SrcTy->isVectorTy() &&
1664 "ConvertVector source IR type must be a vector");
1665 assert(DstTy->isVectorTy() &&
1666 "ConvertVector destination IR type must be a vector");
1668 llvm::Type *SrcEltTy = SrcTy->getVectorElementType(),
1669 *DstEltTy = DstTy->getVectorElementType();
1671 if (DstEltType->isBooleanType()) {
1672 assert((SrcEltTy->isFloatingPointTy() ||
1673 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1675 llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
1676 if (SrcEltTy->isFloatingPointTy()) {
1677 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1679 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1684 Value *Res =
nullptr;
1686 if (isa<llvm::IntegerType>(SrcEltTy)) {
1688 if (isa<llvm::IntegerType>(DstEltTy))
1689 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1690 else if (InputSigned)
1691 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1693 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1694 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1695 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1696 if (DstEltType->isSignedIntegerOrEnumerationType())
1697 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1699 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1701 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1702 "Unknown real conversion");
1703 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1704 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1706 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1721 return Builder.getInt(Value);
1725 return EmitLoadOfLValue(E);
1729 TestAndClearIgnoreResultAssign();
1736 return EmitLoadOfLValue(E);
1744 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1747 return Builder.CreateExtractElement(Base, Idx,
"vecext");
1750 static llvm::Constant *
getMaskElt(llvm::ShuffleVectorInst *SVI,
unsigned Idx,
1752 int MV = SVI->getMaskValue(Idx);
1754 return llvm::UndefValue::get(I32Ty);
1755 return llvm::ConstantInt::get(I32Ty, Off+MV);
1759 if (C->getBitWidth() != 32) {
1760 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
1761 C->getZExtValue()) &&
1762 "Index operand too large for shufflevector mask!");
1763 return llvm::ConstantInt::get(I32Ty, C->getZExtValue());
1769 bool Ignore = TestAndClearIgnoreResultAssign();
1771 assert (Ignore ==
false &&
"init list ignored");
1777 llvm::VectorType *VType =
1778 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
1781 if (NumInitElements == 0) {
1783 return EmitNullValue(E->
getType());
1789 unsigned ResElts = VType->getNumElements();
1796 unsigned CurIdx = 0;
1797 bool VIsUndefShuffle =
false;
1799 for (
unsigned i = 0;
i != NumInitElements; ++
i) {
1801 Value *Init = Visit(IE);
1804 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
1810 if (isa<ExtVectorElementExpr>(IE)) {
1811 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
1813 if (EI->getVectorOperandType()->getNumElements() == ResElts) {
1814 llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
1815 Value *LHS =
nullptr, *RHS =
nullptr;
1820 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1822 LHS = EI->getVectorOperand();
1824 VIsUndefShuffle =
true;
1825 }
else if (VIsUndefShuffle) {
1827 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
1828 for (
unsigned j = 0; j != CurIdx; ++j)
1830 Args.push_back(Builder.getInt32(ResElts + C->getZExtValue()));
1831 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1833 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
1834 RHS = EI->getVectorOperand();
1835 VIsUndefShuffle =
false;
1837 if (!Args.empty()) {
1838 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1839 V = Builder.CreateShuffleVector(LHS, RHS, Mask);
1845 V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
1847 VIsUndefShuffle =
false;
1852 unsigned InitElts = VVT->getNumElements();
1857 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
1858 if (isa<ExtVectorElementExpr>(IE)) {
1859 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
1860 Value *SVOp = SVI->getOperand(0);
1861 llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType());
1863 if (OpTy->getNumElements() == ResElts) {
1864 for (
unsigned j = 0; j != CurIdx; ++j) {
1867 if (VIsUndefShuffle) {
1868 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0,
1871 Args.push_back(Builder.getInt32(j));
1874 for (
unsigned j = 0, je = InitElts; j != je; ++j)
1876 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1878 if (VIsUndefShuffle)
1879 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
1888 for (
unsigned j = 0; j != InitElts; ++j)
1889 Args.push_back(Builder.getInt32(j));
1890 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1891 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1892 Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT),
1896 for (
unsigned j = 0; j != CurIdx; ++j)
1897 Args.push_back(Builder.getInt32(j));
1898 for (
unsigned j = 0; j != InitElts; ++j)
1899 Args.push_back(Builder.getInt32(j+Offset));
1900 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1907 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1908 V = Builder.CreateShuffleVector(V, Init, Mask,
"vecinit");
1909 VIsUndefShuffle = isa<llvm::UndefValue>(Init);
1918 for (; CurIdx < ResElts; ++CurIdx) {
1919 Value *Idx = Builder.getInt32(CurIdx);
1920 llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
1921 V = Builder.CreateInsertElement(V, Init, Idx,
"vecinit");
1929 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
1956 bool Ignored = TestAndClearIgnoreResultAssign();
1962 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
1963 case CK_BuiltinFnToFnPtr:
1964 llvm_unreachable(
"builtin functions are handled elsewhere");
1966 case CK_LValueBitCast:
1967 case CK_ObjCObjectLValueCast: {
1968 Address Addr = EmitLValue(E).getAddress();
1971 return EmitLoadOfLValue(LV, CE->
getExprLoc());
1974 case CK_LValueToRValueBitCast: {
1980 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
1983 case CK_CPointerToObjCPointerCast:
1984 case CK_BlockPointerToObjCPointerCast:
1985 case CK_AnyPointerToBlockPointerCast:
1987 Value *Src = Visit(const_cast<Expr*>(E));
1990 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
1991 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
1992 llvm_unreachable(
"wrong cast for pointers in different address spaces" 1993 "(must be an address space cast)!");
1996 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2010 Src = Builder.CreateLaunderInvariantGroup(Src);
2018 Src = Builder.CreateStripInvariantGroup(Src);
2023 if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(Src))
2024 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE))
2030 case CK_AddressSpaceConversion: {
2040 ConvertType(DestTy)), DestTy);
2048 case CK_AtomicToNonAtomic:
2049 case CK_NonAtomicToAtomic:
2051 case CK_UserDefinedConversion:
2052 return Visit(const_cast<Expr*>(E));
2054 case CK_BaseToDerived: {
2056 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2070 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2078 case CK_UncheckedDerivedToBase:
2079 case CK_DerivedToBase: {
2091 case CK_ArrayToPointerDecay:
2093 case CK_FunctionToPointerDecay:
2094 return EmitLValue(E).getPointer();
2096 case CK_NullToPointer:
2097 if (MustVisitNullValue(E))
2103 case CK_NullToMemberPointer: {
2104 if (MustVisitNullValue(E))
2111 case CK_ReinterpretMemberPointer:
2112 case CK_BaseToDerivedMemberPointer:
2113 case CK_DerivedToBaseMemberPointer: {
2114 Value *Src = Visit(E);
2125 case CK_ARCProduceObject:
2127 case CK_ARCConsumeObject:
2129 case CK_ARCReclaimReturnedObject:
2131 case CK_ARCExtendBlockObject:
2134 case CK_CopyAndAutoreleaseBlockObject:
2137 case CK_FloatingRealToComplex:
2138 case CK_FloatingComplexCast:
2139 case CK_IntegralRealToComplex:
2140 case CK_IntegralComplexCast:
2141 case CK_IntegralComplexToFloatingComplex:
2142 case CK_FloatingComplexToIntegralComplex:
2143 case CK_ConstructorConversion:
2145 llvm_unreachable(
"scalar cast to non-scalar value");
2147 case CK_LValueToRValue:
2149 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2150 return Visit(const_cast<Expr*>(E));
2152 case CK_IntegralToPointer: {
2153 Value *Src = Visit(const_cast<Expr*>(E));
2157 auto DestLLVMTy = ConvertType(DestTy);
2161 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2163 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2169 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2173 case CK_PointerToIntegral: {
2174 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2175 auto *PtrExpr = Visit(E);
2183 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2186 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2192 case CK_VectorSplat: {
2194 Value *Elt = Visit(const_cast<Expr*>(E));
2196 unsigned NumElements = DstTy->getVectorNumElements();
2197 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2200 case CK_FixedPointCast:
2201 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2204 case CK_FixedPointToBoolean:
2206 "Expected src type to be fixed point type");
2207 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2208 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2211 case CK_FixedPointToIntegral:
2213 "Expected src type to be fixed point type");
2214 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2215 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2218 case CK_IntegralToFixedPoint:
2220 "Expected src type to be an integer");
2222 "Expected dest type to be fixed point type");
2223 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2226 case CK_IntegralCast: {
2227 ScalarConversionOpts Opts;
2228 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2229 if (!ICE->isPartOfExplicitCast())
2230 Opts = ScalarConversionOpts(CGF.
SanOpts);
2232 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2235 case CK_IntegralToFloating:
2236 case CK_FloatingToIntegral:
2237 case CK_FloatingCast:
2238 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2240 case CK_BooleanToSignedIntegral: {
2241 ScalarConversionOpts Opts;
2242 Opts.TreatBooleanAsSigned =
true;
2243 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2246 case CK_IntegralToBoolean:
2247 return EmitIntToBoolConversion(Visit(E));
2248 case CK_PointerToBoolean:
2249 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2250 case CK_FloatingToBoolean:
2251 return EmitFloatToBoolConversion(Visit(E));
2252 case CK_MemberPointerToBoolean: {
2258 case CK_FloatingComplexToReal:
2259 case CK_IntegralComplexToReal:
2262 case CK_FloatingComplexToBoolean:
2263 case CK_IntegralComplexToBoolean: {
2267 return EmitComplexToScalarConversion(V, E->
getType(), DestTy,
2271 case CK_ZeroToOCLOpaqueType: {
2274 "CK_ZeroToOCLEvent cast on non-event type");
2275 return llvm::Constant::getNullValue(ConvertType(DestTy));
2278 case CK_IntToOCLSampler:
2283 llvm_unreachable(
"unknown scalar cast");
2286 Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
2314 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2316 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2322 llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2325 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2326 StringRef Name = IsInc ?
"inc" :
"dec";
2327 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2329 return Builder.CreateAdd(InVal, Amount, Name);
2331 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2332 return Builder.CreateNSWAdd(InVal, Amount, Name);
2336 return Builder.CreateNSWAdd(InVal, Amount, Name);
2339 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2344 bool isInc,
bool isPre) {
2347 llvm::PHINode *atomicPHI =
nullptr;
2351 int amount = (isInc ? 1 : -1);
2352 bool isSubtraction = !isInc;
2355 type = atomicTy->getValueType();
2360 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2361 return Builder.getTrue();
2365 return Builder.CreateAtomicRMW(
2366 llvm::AtomicRMWInst::Xchg, LV.
getPointer(), True,
2367 llvm::AtomicOrdering::SequentiallyConsistent);
2374 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2377 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2378 llvm::AtomicRMWInst::Sub;
2379 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2380 llvm::Instruction::Sub;
2382 llvm::ConstantInt::get(ConvertType(type), 1,
true), type);
2384 LV.
getPointer(), amt, llvm::AtomicOrdering::SequentiallyConsistent);
2385 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2387 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2390 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2393 Builder.CreateBr(opBB);
2394 Builder.SetInsertPoint(opBB);
2395 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2396 atomicPHI->addIncoming(value, startBB);
2399 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2411 value = Builder.getTrue();
2418 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
2420 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2424 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2425 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2436 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2438 value = Builder.CreateGEP(value, numElts,
"vla.inc");
2441 value, numElts,
false, isSubtraction,
2450 value = Builder.CreateGEP(value, amt,
"incdec.funcptr");
2461 value = Builder.CreateGEP(value, amt,
"incdec.ptr");
2471 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2473 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2475 value = Builder.CreateFAdd(
2477 llvm::ConstantFP::get(value->getType(), amount),
2478 isInc ?
"inc" :
"dec");
2489 value = Builder.CreateCall(
2492 input,
"incdec.conv");
2494 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
2498 if (value->getType()->isFloatTy())
2499 amt = llvm::ConstantFP::get(VMContext,
2500 llvm::APFloat(static_cast<float>(amount)));
2501 else if (value->getType()->isDoubleTy())
2502 amt = llvm::ConstantFP::get(VMContext,
2503 llvm::APFloat(static_cast<double>(amount)));
2506 llvm::APFloat F(static_cast<float>(amount));
2508 const llvm::fltSemantics *FS;
2511 if (value->getType()->isFP128Ty())
2513 else if (value->getType()->isHalfTy())
2517 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
2518 amt = llvm::ConstantFP::get(VMContext, F);
2520 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
2524 value = Builder.CreateCall(
2527 value,
"incdec.conv");
2529 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
2539 if (!isInc) size = -size;
2544 value = Builder.CreateGEP(value, sizeValue,
"incdec.objptr");
2547 false, isSubtraction,
2553 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
2559 atomicPHI->addIncoming(old, curBlock);
2560 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
2561 Builder.SetInsertPoint(contBB);
2562 return isPre ? value : input;
2573 return isPre ? value : input;
2579 TestAndClearIgnoreResultAssign();
2584 if (BinOp.RHS->getType()->isFPOrFPVectorTy())
2585 BinOp.LHS = llvm::ConstantFP::getZeroValueForNegation(BinOp.RHS->getType());
2587 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
2589 BinOp.Opcode = BO_Sub;
2592 return EmitSub(BinOp);
2596 TestAndClearIgnoreResultAssign();
2598 return Builder.CreateNot(Op,
"neg");
2605 Value *Zero = llvm::Constant::getNullValue(Oper->getType());
2607 if (Oper->getType()->isFPOrFPVectorTy())
2608 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
2610 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
2611 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
2620 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
2623 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
2631 return Builder.getInt(Value);
2637 llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
2639 for (
unsigned i = 0;
i != n; ++
i) {
2648 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
2655 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
2659 Offset = Builder.CreateMul(Idx, ElemSize);
2673 Field != FieldEnd; ++Field, ++
i) {
2674 if (*Field == MemberDecl)
2677 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
2682 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
2685 CurrentType = MemberDecl->
getType();
2690 llvm_unreachable(
"dependent __builtin_offsetof");
2708 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
2712 Result = Builder.CreateAdd(Result, Offset);
2720 ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
2740 if (!eltSize.
isOne())
2751 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
2796 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
2803 BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E) {
2804 TestAndClearIgnoreResultAssign();
2806 Result.LHS = Visit(E->
getLHS());
2807 Result.RHS = Visit(E->
getRHS());
2815 LValue ScalarExprEmitter::EmitCompoundAssignLValue(
2817 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &),
2827 OpInfo.RHS = Visit(E->
getRHS());
2835 llvm::PHINode *atomicPHI =
nullptr;
2840 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2843 llvm::AtomicRMWInst::BinOp aop = llvm::AtomicRMWInst::BAD_BINOP;
2844 switch (OpInfo.Opcode) {
2846 case BO_MulAssign:
case BO_DivAssign:
2852 aop = llvm::AtomicRMWInst::Add;
2855 aop = llvm::AtomicRMWInst::Sub;
2861 aop = llvm::AtomicRMWInst::Xor;
2864 aop = llvm::AtomicRMWInst::Or;
2867 llvm_unreachable(
"Invalid compound assignment type");
2869 if (aop != llvm::AtomicRMWInst::BAD_BINOP) {
2871 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
2874 Builder.CreateAtomicRMW(aop, LHSLV.
getPointer(), amt,
2875 llvm::AtomicOrdering::SequentiallyConsistent);
2881 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2883 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2885 Builder.CreateBr(opBB);
2886 Builder.SetInsertPoint(opBB);
2887 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
2888 atomicPHI->addIncoming(OpInfo.LHS, startBB);
2889 OpInfo.LHS = atomicPHI;
2892 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2899 Result = (this->*Func)(OpInfo);
2904 Loc, ScalarConversionOpts(CGF.
SanOpts));
2907 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
2913 atomicPHI->addIncoming(old, curBlock);
2914 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
2915 Builder.SetInsertPoint(contBB);
2932 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &)) {
2933 bool Ignore = TestAndClearIgnoreResultAssign();
2934 Value *RHS =
nullptr;
2935 LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
2950 return EmitLoadOfLValue(LHS, E->
getExprLoc());
2953 void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
2954 const BinOpInfo &Ops,
llvm::Value *Zero,
bool isDiv) {
2957 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
2958 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
2959 SanitizerKind::IntegerDivideByZero));
2962 const auto *BO = cast<BinaryOperator>(Ops.E);
2963 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
2964 Ops.Ty->hasSignedIntegerRepresentation() &&
2965 !IsWidenedIntegerOp(CGF.
getContext(), BO->getLHS()) &&
2966 Ops.mayHaveIntegerOverflow()) {
2967 llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
2970 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
2971 llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL);
2973 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
2974 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
2975 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
2977 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
2980 if (Checks.size() > 0)
2981 EmitBinOpCheck(Checks, Ops);
2984 Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
2987 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
2988 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
2989 Ops.Ty->isIntegerType() &&
2990 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
2991 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2992 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
2993 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
2994 Ops.Ty->isRealFloatingType() &&
2995 Ops.mayHaveFloatDivisionByZero()) {
2996 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2997 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
2998 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3003 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3004 llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3013 if (ValTy->isFloatTy() ||
3014 (isa<llvm::VectorType>(ValTy) &&
3015 cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy()))
3020 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3021 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3023 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3026 Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3028 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3029 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3030 Ops.Ty->isIntegerType() &&
3031 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3033 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3034 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3037 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3038 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3040 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3043 Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3047 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3048 switch (Ops.Opcode) {
3052 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3053 llvm::Intrinsic::uadd_with_overflow;
3058 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3059 llvm::Intrinsic::usub_with_overflow;
3064 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3065 llvm::Intrinsic::umul_with_overflow;
3068 llvm_unreachable(
"Unsupported operation for overflow detection");
3079 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3080 Value *
result = Builder.CreateExtractValue(resultAndOverflow, 0);
3081 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3084 const std::string *handlerName =
3086 if (handlerName->empty()) {
3089 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3090 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3092 : SanitizerKind::UnsignedIntegerOverflow;
3093 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3100 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3101 llvm::BasicBlock *continueBB =
3105 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3109 Builder.SetInsertPoint(overflowBB);
3114 llvm::FunctionType *handlerTy =
3115 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3116 llvm::FunctionCallee handler =
3129 Builder.getInt8(OpID),
3130 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3136 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3137 Builder.CreateBr(continueBB);
3139 Builder.SetInsertPoint(continueBB);
3140 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3141 phi->addIncoming(result, initialBB);
3142 phi->addIncoming(handlerResult, overflowBB);
3149 const BinOpInfo &op,
3150 bool isSubtraction) {
3155 Value *pointer = op.LHS;
3157 Value *index = op.RHS;
3161 if (!isSubtraction && !pointer->getType()->isPointerTy()) {
3162 std::swap(pointer, index);
3163 std::swap(pointerOperand, indexOperand);
3168 unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
3170 auto PtrTy = cast<llvm::PointerType>(pointer->getType());
3193 return CGF.
Builder.CreateIntToPtr(index, pointer->getType());
3195 if (width != DL.getTypeSizeInBits(PtrTy)) {
3198 index = CGF.
Builder.CreateIntCast(index, DL.getIntPtrType(PtrTy), isSigned,
3204 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3206 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
3219 index = CGF.
Builder.CreateMul(index, objectSize);
3222 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
3237 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
3238 pointer = CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
3240 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
3243 op.E->getExprLoc(),
"add.ptr");
3253 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
3258 return CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
3261 op.E->getExprLoc(),
"add.ptr");
3271 bool negMul,
bool negAdd) {
3272 assert(!(negMul && negAdd) &&
"Only one of negMul and negAdd should be set.");
3274 Value *MulOp0 = MulOp->getOperand(0);
3275 Value *MulOp1 = MulOp->getOperand(1);
3279 llvm::ConstantFP::getZeroValueForNegation(MulOp0->getType()), MulOp0,
3281 }
else if (negAdd) {
3284 llvm::ConstantFP::getZeroValueForNegation(Addend->getType()), Addend,
3288 Value *FMulAdd = Builder.CreateCall(
3290 {MulOp0, MulOp1, Addend});
3291 MulOp->eraseFromParent();
3306 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
3307 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
3308 "Only fadd/fsub can be the root of an fmuladd.");
3311 if (!op.FPFeatures.allowFPContractWithinStatement())
3317 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) {
3318 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3319 LHSBinOp->use_empty())
3320 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder,
false, isSub);
3322 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) {
3323 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3324 RHSBinOp->use_empty())
3325 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub,
false);
3331 Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
3332 if (op.LHS->getType()->isPointerTy() ||
3333 op.RHS->getType()->isPointerTy())
3336 if (op.Ty->isSignedIntegerOrEnumerationType()) {
3337 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3339 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3341 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3342 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3345 if (CanElideOverflowCheck(CGF.
getContext(), op))
3346 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3347 return EmitOverflowCheckedBinOp(op);
3351 if (op.Ty->isUnsignedIntegerType() &&
3352 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3353 !CanElideOverflowCheck(CGF.
getContext(), op))
3354 return EmitOverflowCheckedBinOp(op);
3356 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3361 Value *V = Builder.CreateFAdd(op.LHS, op.RHS,
"add");
3362 return propagateFMFlags(V, op);
3365 if (op.isFixedPointBinOp())
3366 return EmitFixedPointBinOp(op);
3368 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3373 Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
3375 using llvm::ConstantInt;
3377 const auto *BinOp = cast<BinaryOperator>(op.E);
3383 QualType LHSTy = BinOp->getLHS()->getType();
3384 QualType RHSTy = BinOp->getRHS()->getType();
3386 Value *LHS = op.LHS;
3387 Value *RHS = op.RHS;
3395 Value *FullLHS = EmitFixedPointConversion(LHS, LHSFixedSema, CommonFixedSema,
3396 BinOp->getExprLoc());
3397 Value *FullRHS = EmitFixedPointConversion(RHS, RHSFixedSema, CommonFixedSema,
3398 BinOp->getExprLoc());
3402 switch (BinOp->getOpcode()) {
3404 if (ResultFixedSema.isSaturated()) {
3406 ? llvm::Intrinsic::sadd_sat
3407 : llvm::Intrinsic::uadd_sat;
3408 Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS);
3410 Result = Builder.CreateAdd(FullLHS, FullRHS);
3415 if (ResultFixedSema.isSaturated()) {
3417 ? llvm::Intrinsic::ssub_sat
3418 : llvm::Intrinsic::usub_sat;
3419 Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS);
3421 Result = Builder.CreateSub(FullLHS, FullRHS);
3426 return CommonFixedSema.isSigned() ? Builder.CreateICmpSLT(FullLHS, FullRHS)
3427 : Builder.CreateICmpULT(FullLHS, FullRHS);
3429 return CommonFixedSema.isSigned() ? Builder.CreateICmpSGT(FullLHS, FullRHS)
3430 : Builder.CreateICmpUGT(FullLHS, FullRHS);
3432 return CommonFixedSema.isSigned() ? Builder.CreateICmpSLE(FullLHS, FullRHS)
3433 : Builder.CreateICmpULE(FullLHS, FullRHS);
3435 return CommonFixedSema.isSigned() ? Builder.CreateICmpSGE(FullLHS, FullRHS)
3436 : Builder.CreateICmpUGE(FullLHS, FullRHS);
3441 return Builder.CreateICmpEQ(FullLHS, FullRHS);
3443 return Builder.CreateICmpNE(FullLHS, FullRHS);
3457 llvm_unreachable(
"Found unimplemented fixed point binary operation");
3470 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
3474 return EmitFixedPointConversion(Result, CommonFixedSema, ResultFixedSema,
3475 BinOp->getExprLoc());
3478 Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
3480 if (!op.LHS->getType()->isPointerTy()) {
3481 if (op.Ty->isSignedIntegerOrEnumerationType()) {
3482 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3484 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
3486 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3487 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
3490 if (CanElideOverflowCheck(CGF.
getContext(), op))
3491 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
3492 return EmitOverflowCheckedBinOp(op);
3496 if (op.Ty->isUnsignedIntegerType() &&
3497 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3498 !CanElideOverflowCheck(CGF.
getContext(), op))
3499 return EmitOverflowCheckedBinOp(op);
3501 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3505 Value *V = Builder.CreateFSub(op.LHS, op.RHS,
"sub");
3506 return propagateFMFlags(V, op);
3509 if (op.isFixedPointBinOp())
3510 return EmitFixedPointBinOp(op);
3512 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
3517 if (!op.RHS->getType()->isPointerTy())
3524 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
3526 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
3527 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
3539 elementType = VlaSize.
Type;
3540 divisor = VlaSize.NumElts;
3544 if (!eltSize.
isOne())
3554 if (elementType->isVoidType() || elementType->isFunctionType())
3560 if (elementSize.
isOne())
3569 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
3572 Value *ScalarExprEmitter::GetWidthMinusOneValue(
Value* LHS,
Value* RHS) {
3573 llvm::IntegerType *Ty;
3574 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
3575 Ty = cast<llvm::IntegerType>(VT->getElementType());
3577 Ty = cast<llvm::IntegerType>(LHS->getType());
3578 return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1);
3581 Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
3584 Value *RHS = Ops.RHS;
3585 if (Ops.LHS->getType() != RHS->getType())
3586 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3588 bool SanitizeBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
3589 Ops.Ty->hasSignedIntegerRepresentation() &&
3592 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
3596 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shl.mask");
3597 else if ((SanitizeBase || SanitizeExponent) &&
3598 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3601 llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
3602 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
3604 if (SanitizeExponent) {
3606 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
3613 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
3616 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
3618 (RHS == Ops.RHS) ? WidthMinusOne
3619 : GetWidthMinusOneValue(Ops.LHS, RHS);
3622 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
3630 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
3631 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
3633 llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
3634 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
3636 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
3637 BaseCheck->addIncoming(Builder.getTrue(), Orig);
3638 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
3639 Checks.push_back(std::make_pair(BaseCheck, SanitizerKind::ShiftBase));
3642 assert(!Checks.empty());
3643 EmitBinOpCheck(Checks, Ops);
3646 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
3649 Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
3652 Value *RHS = Ops.RHS;
3653 if (Ops.LHS->getType() != RHS->getType())
3654 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3659 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shr.mask");
3660 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
3661 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3664 Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
3665 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
3668 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3669 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
3670 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
3678 default: llvm_unreachable(
"unexpected element type");
3679 case BuiltinType::Char_U:
3680 case BuiltinType::UChar:
3681 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3682 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
3683 case BuiltinType::Char_S:
3684 case BuiltinType::SChar:
3685 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3686 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
3687 case BuiltinType::UShort:
3688 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3689 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
3690 case BuiltinType::Short:
3691 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3692 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
3693 case BuiltinType::UInt:
3694 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3695 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
3696 case BuiltinType::Int:
3697 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3698 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
3699 case BuiltinType::ULong:
3700 case BuiltinType::ULongLong:
3701 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3702 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
3703 case BuiltinType::Long:
3704 case BuiltinType::LongLong:
3705 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3706 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
3707 case BuiltinType::Float:
3708 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
3709 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
3710 case BuiltinType::Double:
3711 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
3712 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
3717 llvm::CmpInst::Predicate UICmpOpc,
3718 llvm::CmpInst::Predicate SICmpOpc,
3719 llvm::CmpInst::Predicate FCmpOpc) {
3720 TestAndClearIgnoreResultAssign();
3730 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
3732 BinOpInfo BOInfo = EmitBinOps(E);
3733 Value *LHS = BOInfo.LHS;
3734 Value *RHS = BOInfo.RHS;
3740 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
3745 Value *FirstVecArg = LHS,
3746 *SecondVecArg = RHS;
3753 default: llvm_unreachable(
"is not a comparison operation");
3765 std::swap(FirstVecArg, SecondVecArg);
3772 if (ElementKind == BuiltinType::Float) {
3774 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3775 std::swap(FirstVecArg, SecondVecArg);
3783 if (ElementKind == BuiltinType::Float) {
3785 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3790 std::swap(FirstVecArg, SecondVecArg);
3795 Value *CR6Param = Builder.getInt32(CR6);
3797 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
3804 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
3805 if (ResultTy->getBitWidth() > 1 &&
3807 Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
3812 if (BOInfo.isFixedPointBinOp()) {
3813 Result = EmitFixedPointBinOp(BOInfo);
3814 }
else if (LHS->getType()->isFPOrFPVectorTy()) {
3815 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
3817 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
3822 !isa<llvm::ConstantPointerNull>(LHS) &&
3823 !isa<llvm::ConstantPointerNull>(RHS)) {
3832 LHS = Builder.CreateStripInvariantGroup(LHS);
3834 RHS = Builder.CreateStripInvariantGroup(RHS);
3837 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
3843 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
3851 CETy = CTy->getElementType();
3853 LHS.first = Visit(E->
getLHS());
3854 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
3860 CTy->getElementType()) &&
3861 "The element types must always match.");
3864 RHS.first = Visit(E->
getRHS());
3865 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
3867 "The element types must always match.");
3870 Value *ResultR, *ResultI;
3872 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
3873 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
3877 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
3878 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
3882 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
3885 "Complex comparison other than == or != ?");
3886 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
3895 bool Ignore = TestAndClearIgnoreResultAssign();
3914 RHS = Visit(E->
getRHS());
3922 RHS = Visit(E->
getRHS());
3929 if (LHS.isBitField()) {
3950 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3960 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
3961 if (LHS->getType()->isFPOrFPVectorTy()) {
3962 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
3963 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
3965 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
3966 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
3968 Value *
And = Builder.CreateAnd(LHS, RHS);
3969 return Builder.CreateSExt(And, ConvertType(E->
getType()),
"sext");
3983 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
3988 return llvm::Constant::getNullValue(ResTy);
4005 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4007 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
4016 RHSBlock = Builder.GetInsertBlock();
4025 PN->addIncoming(RHSCond, RHSBlock);
4030 PN->setDebugLoc(Builder.getCurrentDebugLocation());
4034 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
4044 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
4045 if (LHS->getType()->isFPOrFPVectorTy()) {
4046 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4047 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4049 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4050 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4052 Value *Or = Builder.CreateOr(LHS, RHS);
4053 return Builder.CreateSExt(Or, ConvertType(E->
getType()),
"sext");
4067 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
4072 return llvm::ConstantInt::get(ResTy, 1);
4090 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4092 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
4104 RHSBlock = Builder.GetInsertBlock();
4109 PN->addIncoming(RHSCond, RHSBlock);
4112 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
4118 return Visit(E->
getRHS());
4143 Value *ScalarExprEmitter::
4145 TestAndClearIgnoreResultAssign();
4158 Expr *live = lhsExpr, *dead = rhsExpr;
4159 if (!CondExprBool) std::swap(live, dead);
4165 Value *Result = Visit(live);
4188 llvm::VectorType *vecTy = cast<llvm::VectorType>(condType);
4190 unsigned numElem = vecTy->getNumElements();
4191 llvm::Type *elemType = vecTy->getElementType();
4193 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
4194 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
4196 llvm::VectorType::get(elemType,
4204 bool wasCast =
false;
4205 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
4206 if (rhsVTy->getElementType()->isFloatingPointTy()) {
4212 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
4213 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
4214 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
4235 assert(!RHS &&
"LHS and RHS types must match");
4238 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
4252 Value *LHS = Visit(lhsExpr);
4255 LHSBlock = Builder.GetInsertBlock();
4256 Builder.CreateBr(ContBlock);
4260 Value *RHS = Visit(rhsExpr);
4263 RHSBlock = Builder.GetInsertBlock();
4273 llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2,
"cond");
4274 PN->addIncoming(LHS, LHSBlock);
4275 PN->addIncoming(RHS, RHSBlock);
4297 return llvm::UndefValue::get(ArgTy);
4304 if (ArgTy != Val->getType()) {
4305 if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
4306 Val = Builder.CreateIntToPtr(Val, ArgTy);
4308 Val = Builder.CreateTrunc(Val, ArgTy);
4314 Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
4320 Value *Src,
unsigned NumElementsDst) {
4321 llvm::Value *UnV = llvm::UndefValue::get(Src->getType());
4323 Args.push_back(Builder.getInt32(0));
4324 Args.push_back(Builder.getInt32(1));
4325 Args.push_back(Builder.getInt32(2));
4326 if (NumElementsDst == 4)
4327 Args.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
4328 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
4329 return Builder.CreateShuffleVector(Src, UnV, Mask);
4349 const llvm::DataLayout &DL,
4351 StringRef Name =
"") {
4352 auto SrcTy = Src->getType();
4355 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
4359 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
4363 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
4365 if (!DstTy->isIntegerTy())
4366 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
4368 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
4372 if (!SrcTy->isIntegerTy())
4375 return Builder.CreateIntToPtr(Src, DstTy, Name);
4383 unsigned NumElementsSrc = isa<llvm::VectorType>(SrcTy) ?
4384 cast<llvm::VectorType>(SrcTy)->getNumElements() : 0;
4385 unsigned NumElementsDst = isa<llvm::VectorType>(DstTy) ?
4386 cast<llvm::VectorType>(DstTy)->getNumElements() : 0;
4390 if (NumElementsSrc == 3 && NumElementsDst != 3) {
4398 Src->setName(
"astype");
4405 if (NumElementsSrc != 3 && NumElementsDst == 3) {
4407 auto Vec4Ty = llvm::VectorType::get(DstTy->getVectorElementType(), 4);
4413 Src->setName(
"astype");
4418 Src, DstTy,
"astype");
4432 assert(E && hasScalarEvaluationKind(E->
getType()) &&
4433 "Invalid scalar expression to emit");
4435 return ScalarExprEmitter(*
this, IgnoreResultAssign)
4436 .Visit(const_cast<Expr *>(E));
4444 assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
4445 "Invalid scalar expression to emit");
4446 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
4456 "Invalid complex -> scalar conversion");
4457 return ScalarExprEmitter(*
this)
4458 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
4464 bool isInc,
bool isPre) {
4465 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
4475 Addr =
Address(EmitScalarExpr(BaseExpr), getPointerAlign());
4477 Addr = EmitLValue(BaseExpr).getAddress();
4482 return MakeAddrLValue(Addr, E->
getType());
4488 ScalarExprEmitter Scalar(*
this);
4489 Value *Result =
nullptr;
4491 #define COMPOUND_OP(Op) \ 4492 case BO_##Op##Assign: \ 4493 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \ 4530 llvm_unreachable(
"Not valid compound assignment operators");
4533 llvm_unreachable(
"Unhandled compound assignment operator");
4541 const Twine &Name) {
4542 Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name);
4545 if (!SanOpts.has(SanitizerKind::PointerOverflow))
4549 if (isa<llvm::Constant>(GEPVal))
4553 if (GEPVal->getType()->getPointerAddressSpace())
4556 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
4557 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
4560 auto &VMContext = getLLVMContext();
4561 const auto &DL = CGM.getDataLayout();
4562 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
4565 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
4566 auto *SAddIntrinsic =
4567 CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
4568 auto *SMulIntrinsic =
4569 CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
4574 llvm::Value *OffsetOverflows = Builder.getFalse();
4579 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
4582 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
4583 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
4585 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
4588 OffsetOverflows = Builder.getTrue();
4589 return llvm::ConstantInt::get(VMContext, N);
4594 auto *ResultAndOverflow = Builder.CreateCall(
4595 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
4596 OffsetOverflows = Builder.CreateOr(
4597 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
4598 return Builder.CreateExtractValue(ResultAndOverflow, 0);
4602 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
4603 GTI != GTE; ++GTI) {
4605 auto *Index = GTI.getOperand();
4607 if (
auto *STy = GTI.getStructTypeOrNull()) {
4610 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
4611 LocalOffset = llvm::ConstantInt::get(
4612 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
4616 auto *ElementSize = llvm::ConstantInt::get(
4617 IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType()));
4618 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
4619 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
4624 if (!TotalOffset || TotalOffset == Zero)
4625 TotalOffset = LocalOffset;
4627 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
4631 if (TotalOffset == Zero)
4636 auto *IntPtr = Builder.CreatePtrToInt(GEP->getPointerOperand(), IntPtrTy);
4637 auto *ComputedGEP = Builder.CreateAdd(IntPtr, TotalOffset);
4644 auto *NoOffsetOverflow = Builder.CreateNot(OffsetOverflows);
4645 if (SignedIndices) {
4646 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4647 auto *PosOrZeroOffset = Builder.CreateICmpSGE(TotalOffset, Zero);
4648 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
4649 ValidGEP = Builder.CreateAnd(
4650 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid),
4652 }
else if (!SignedIndices && !IsSubtraction) {
4653 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4654 ValidGEP = Builder.CreateAnd(PosOrZeroValid, NoOffsetOverflow);
4656 auto *NegOrZeroValid = Builder.CreateICmpULE(ComputedGEP, IntPtr);
4657 ValidGEP = Builder.CreateAnd(NegOrZeroValid, NoOffsetOverflow);
4660 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
4662 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4663 EmitCheck(std::make_pair(ValidGEP, SanitizerKind::PointerOverflow),
4664 SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
const llvm::DataLayout & getDataLayout() const
const Expr * getSubExpr() const
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Defines the clang::ASTContext interface.
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())
Emit a compare-and-exchange op for atomic type.
The null pointer literal (C++11 [lex.nullptr])
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
static APFixedPoint getMax(const FixedPointSemantics &Sema)
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
void end(CodeGenFunction &CGF)
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc)
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled...
bool isSignedOverflowDefined() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
uint64_t getValue() const
CodeGenTypes & getTypes()
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
static Opcode getOpForCompoundAssignment(Opcode Opc)
const CodeGenOptions & getCodeGenOpts() const
SourceLocation getExprLoc() const
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler...
void enterFullExpression(const FullExpr *E)
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
llvm::APSInt getValue() const
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Expr * getResultExpr()
Return the result expression of this controlling expression.
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
CompoundStmt * getSubStmt()
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const Expr * getInit(unsigned Init) const
static llvm::Constant * getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
Stmt - This represents one statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
bool isRealFloatingType() const
Floating point categories.
The fixed point semantics work similarly to llvm::fltSemantics.
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr)
Generate code to get an argument from the passed in pointer and update it accordingly.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::APFloat getValue() const
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
bool isExtVectorType() const
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
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...
ParenExpr - This represents a parethesized expression, e.g.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Expr * getFalseExpr() const
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
FPOptions getFPFeatures() const
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent...
const TargetInfo & getTargetInfo() const
SourceLocation getLocation() const
Floating point control options.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
static Value * buildFMulAdd(llvm::BinaryOperator *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant, or if it does but contains a label, return false.
QualType getElementType() const
Expr * getIndexExpr(unsigned Idx)
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
CompoundLiteralExpr - [C99 6.5.2.5].
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const T * getAs() const
Member-template getAs<specific type>'.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
const llvm::fltSemantics & getHalfFormat() const
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::Value * getPointer() const
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
A C++ throw-expression (C++ [except.throw]).
Represents an expression – generally a full-expression – that introduces cleanups to be run at the ...
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
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.
Represents a struct/union/class.
const TargetInfo & getTarget() const
An object to manage conditionally-evaluated expressions.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
FieldDecl * getField() const
For a field offsetof node, returns the field.
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(), or __builtin_FILE().
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Address getAddress() const
QualType getComputationResultType() const
CGDebugInfo * getDebugInfo()
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
llvm::IntegerType * Int64Ty
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVolatileQualified() const
Represents a member of a struct/union/class.
llvm::IntegerType * SizeTy
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
unsigned getIntegralBits() const
Return the number of integral bits represented by these semantics.
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
bool isReferenceType() const
__DEVICE__ int max(int __a, int __b)
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method...
bool hadArrayRangeDesignator() const
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
Describes an C or C++ initializer list.
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
static APFixedPoint getMin(const FixedPointSemantics &Sema)
const Expr * getDefaultExpr() const
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
APValue Val
Val - This is the value the expression can be folded to.
bool isOne() const
isOne - Test whether the quantity equals one.
path_iterator path_begin()
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
llvm::PointerType * VoidPtrTy
A builtin binary operation expression such as "x + y" or "x <= y".
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
ObjCStringLiteral, used for Objective-C string literals i.e.
static llvm::Constant * getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off, llvm::Type *I32Ty)
Scope - A scope is a transient data structure that is used while parsing the program.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
unsigned getScale() const
field_iterator field_begin() const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a best-effort attempt to peephole expressions that naturally produce retained objects.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Helper class for OffsetOfExpr.
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
RValue EmitAtomicExpr(AtomicExpr *E)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
QualType getReturnType() const
A default argument (C++ [dcl.fct.default]).
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
void begin(CodeGenFunction &CGF)
Checking the operand of a load. Must be suitably sized and aligned.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point...
This object can be modified without requiring retains or releases.
Represents the this expression in C++.
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.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, Expr *LHS, Expr *RHS)
const Expr * getExpr() const
Get the initialization expression that will be used.
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...
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
VersionTuple getVersion()
Sema - This implements semantic analysis and AST building for C.
bool isPromotableIntegerType() const
More type predicates useful for type checking/promotion.
static CharUnits One()
One - Construct a CharUnits quantity of one.
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ASTContext & getContext() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
QualType getComputationLHSType() const
CastKind
CastKind - The kind of operation required for a conversion.
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Represents a call to the builtin function __builtin_va_arg.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
const llvm::fltSemantics & getLongDoubleFormat() const
unsigned getValue() const
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
Allow any unmodeled side effect.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type, where the destination type is an LLVM scalar type.
SourceLocation getExprLoc() const LLVM_READONLY
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to...
unsigned getPackLength() const
Retrieve the length of the parameter pack.
const T * castAs() const
Member-template castAs<specific type>.
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
unsigned getNumInits() const
bool isNullPtrType() const
void SetFPAccuracy(llvm::Value *Val, float Accuracy)
SetFPAccuracy - Set the minimum required accuracy of the given floating point operation, expressed as the maximum relative error in ulp.
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements, of a variable length array type, plus that largest non-variably-sized element type.
field_iterator field_end() const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation...
bool isAnyComplexType() const
ObjCSelectorExpr used for @selector in Objective-C.
TypeSourceInfo * getTypeSourceInfo() const
Represents an expression that computes the length of a parameter pack.
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
llvm::LLVMContext & getLLVMContext()
llvm::IntegerType * Int32Ty
Kind getKind() const
Determine what kind of offsetof node this is.
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...
An RAII object to record that we're evaluating a statement expression.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
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 ...
An expression that sends a message to the given Objective-C object or class.
FixedPointSemantics getCommonSemantics(const FixedPointSemantics &Other) const
Return the FixedPointSemantics that allows for calculating the full precision semantic that can preci...
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
Represents a GCC generic vector type.
bool isNullPointer() const
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
Try to emit a reference to the given value without producing it as an l-value.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
The scope of a CXXDefaultInitExpr.
const OffsetOfNode & getComponent(unsigned Idx) const
const TargetInfo & getTarget() const
Expr * getTrueExpr() const
const Expr * getSubExpr() const
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
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...
There is no lifetime qualification on this type.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
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. ...
Assigning into this object requires the old value to be released and the new value to be retained...
A field in a dependent type, known only by its name.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Encodes a location in the source.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go...
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
LangAS getAddressSpace() const
Return the address space of this type.
bool allowFPContractAcrossStatement() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
Expr * getSubExpr() const
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior...
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation...
CastKind getCastKind() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
QualType getElementType() const
A scoped helper to set the current debug location to the specified location or preferred location of ...
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
SanitizerSet SanOpts
Sanitizers enabled for this function.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>, and corresponding __opencl_atomic_* for OpenCL 2.0.
UnaryExprOrTypeTrait getKind() const
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded...
ObjCProtocolExpr used for protocol expression in Objective-C.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
An expression trait intrinsic.
const ObjCMethodDecl * getMethodDecl() const
bool isVectorType() const
Assigning into this object requires a lifetime extension.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
ObjCBoxedExpr - used for generalized expression boxing.
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
bool isArgumentType() const
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot())
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.
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
Defines the fixed point number interface.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
CompoundAssignOperator - For compound assignments (e.g.
const llvm::fltSemantics & getFloat128Format() const
Represents a C11 generic selection.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
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.
AddrLabelExpr - The GNU address of label extension, representing &&label.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
SourceLocation getExprLoc() const LLVM_READONLY
Dataflow Directional Tag Classes.
void EmitVTablePtrCheckForCast(QualType T, llvm::Value *Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
EvalResult is a struct with detailed info about an evaluated expression.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one...
A runtime availability query.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Represents a 'co_yield' expression.
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static Value * emitPointerArithmetic(CodeGenFunction &CGF, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
bool isBooleanType() const
const Expr * getExpr() const
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Checking the destination of a store. Must be suitably sized and aligned.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type *> Tys=None)
A pointer to member type per C++ 8.3.3 - Pointers to members.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
ExplicitCastExpr - An explicit cast written in the source code.
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
llvm::APInt getValue() const
LabelDecl * getLabel() const
#define VISITCOMP(CODE, UI, SI, FP)
Represents a pointer to an Objective C object.
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
unsigned getIntWidth(QualType T) const
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
bool HasSideEffects
Whether the evaluated expression has side effects.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Complex values, per C99 6.2.5p11.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
Checking the operand of a static_cast to a derived pointer type.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
An implicit indirection through a C++ base class, when the field found is in a base class...
uint64_t getCharWidth() const
Return the size of the character type, in bits.
bool isFunctionType() const
llvm::Value * EmitCheckedInBoundsGEP(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...
Represents a 'co_await' expression.
Expr * getReplacement() const
ExtVectorType - Extended vector type.
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create or return a runtime function declaration with the specified type and name. ...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
unsigned getWidth() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type, returning the result.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Reading or writing from this object requires a barrier call.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
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...
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet...
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Represents a C++ struct/union/class.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
llvm::Type * ConvertType(QualType T)
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
void EmitTrapCheck(llvm::Value *Checked)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it...
ASTImporterLookupTable & LT
This class is used for builtin types like 'int'.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
bool isOCLIntelSubgroupAVCType() const
RetTy Visit(PTR(Stmt) S, ParamTys... P)
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...
CGCXXABI & getCXXABI() const
const VariableArrayType * getAsVariableArrayType(QualType T) const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
unsigned getNumComponents() const
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 mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void EmitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
bool isFloatingType() const
LValue - This represents an lvalue references.
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
A boolean literal, per ([C++ lex.bool] Boolean literals).
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type, member-designator).
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
Represents a C array with a specified size that is not an integer-constant-expression.
const LangOptions & getLangOpts() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
void setTBAAInfo(TBAAAccessInfo Info)
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, CodeGenFunction &CGF)
isCheapEnoughToEvaluateUnconditionally - Return true if the specified expression is cheap enough and ...
const LangOptions & getLangOpts() const
static TBAAAccessInfo getMayAliasInfo()
llvm::Value * getPointer() const
Represents an implicitly-generated value initialization of an object of a given type.
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
QualType getType() const
Return the type wrapped by this type source info.
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
llvm::Value * EmitBuiltinAvailable(ArrayRef< llvm::Value *> Args)
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point...
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
SourceLocation getExprLoc() const
bool isCompoundAssignmentOp() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
QualType getType() const
Retrieves the type of the base class.