31 #include "llvm/ADT/Optional.h" 32 #include "llvm/IR/CFG.h" 33 #include "llvm/IR/Constants.h" 34 #include "llvm/IR/DataLayout.h" 35 #include "llvm/IR/Function.h" 36 #include "llvm/IR/GetElementPtrTypeIterator.h" 37 #include "llvm/IR/GlobalVariable.h" 38 #include "llvm/IR/Intrinsics.h" 39 #include "llvm/IR/IntrinsicsPowerPC.h" 40 #include "llvm/IR/Module.h" 43 using namespace clang;
44 using namespace CodeGen;
58 bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
63 const auto &LHSAP = LHS->getValue();
64 const auto &RHSAP = RHS->getValue();
65 if (Opcode == BO_Add) {
67 Result = LHSAP.sadd_ov(RHSAP, Overflow);
69 Result = LHSAP.uadd_ov(RHSAP, Overflow);
70 }
else if (Opcode == BO_Sub) {
72 Result = LHSAP.ssub_ov(RHSAP, Overflow);
74 Result = LHSAP.usub_ov(RHSAP, Overflow);
75 }
else if (Opcode == BO_Mul) {
77 Result = LHSAP.smul_ov(RHSAP, Overflow);
79 Result = LHSAP.umul_ov(RHSAP, Overflow);
80 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
81 if (Signed && !RHS->isZero())
82 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
98 bool mayHaveIntegerOverflow()
const {
100 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
101 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
102 if (!LHSCI || !RHSCI)
106 return ::mayHaveIntegerOverflow(
111 bool isDivremOp()
const {
112 return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
113 Opcode == BO_RemAssign;
117 bool mayHaveIntegerDivisionByZero()
const {
119 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
125 bool mayHaveFloatDivisionByZero()
const {
127 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
128 return CFP->isZero();
136 bool isFixedPointBinOp()
const {
139 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
140 QualType LHSType = BinOp->getLHS()->getType();
141 QualType RHSType = BinOp->getRHS()->getType();
148 static bool MustVisitNullValue(
const Expr *E) {
171 static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
172 return getUnwidenedIntegerType(Ctx, E).hasValue();
176 static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
177 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
178 "Expected a unary or binary operator");
182 if (!Op.mayHaveIntegerOverflow())
186 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
187 return !UO->canOverflow();
191 const auto *BO = cast<BinaryOperator>(Op.E);
192 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
196 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
205 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
211 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
212 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
217 static void updateFastMathFlags(llvm::FastMathFlags &FMF,
223 static Value *propagateFMFlags(
Value *
V,
const BinOpInfo &Op) {
224 if (
auto *I = dyn_cast<llvm::Instruction>(V)) {
225 llvm::FastMathFlags FMF = I->getFastMathFlags();
226 updateFastMathFlags(FMF, Op.FPFeatures);
227 I->setFastMathFlags(FMF);
232 class ScalarExprEmitter
236 bool IgnoreResultAssign;
237 llvm::LLVMContext &VMContext;
241 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
242 VMContext(cgf.getLLVMContext()) {
249 bool TestAndClearIgnoreResultAssign() {
250 bool I = IgnoreResultAssign;
251 IgnoreResultAssign =
false;
261 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
262 const BinOpInfo &Info);
268 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *V) {
269 const AlignValueAttr *AVAttr =
nullptr;
270 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
274 if (
const auto *TTy =
276 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
283 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
286 AVAttr = VD->
getAttr<AlignValueAttr>();
291 if (
const auto *TTy =
292 dyn_cast<TypedefType>(E->
getType()))
293 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
299 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
310 EmitLValueAlignmentAssumption(E, V);
320 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
326 enum ImplicitConversionCheckKind :
unsigned char {
327 ICCK_IntegerTruncation = 0,
328 ICCK_UnsignedIntegerTruncation = 1,
329 ICCK_SignedIntegerTruncation = 2,
330 ICCK_IntegerSignChange = 3,
331 ICCK_SignedIntegerTruncationOrSignChange = 4,
347 struct ScalarConversionOpts {
348 bool TreatBooleanAsSigned;
349 bool EmitImplicitIntegerTruncationChecks;
350 bool EmitImplicitIntegerSignChangeChecks;
352 ScalarConversionOpts()
353 : TreatBooleanAsSigned(
false),
354 EmitImplicitIntegerTruncationChecks(
false),
355 EmitImplicitIntegerSignChangeChecks(
false) {}
358 : TreatBooleanAsSigned(
false),
359 EmitImplicitIntegerTruncationChecks(
361 EmitImplicitIntegerSignChangeChecks(
367 ScalarConversionOpts Opts = ScalarConversionOpts());
376 bool DstIsInteger =
false);
391 return Builder.CreateFCmpUNE(V, Zero,
"tobool");
398 return Builder.CreateICmpNE(V, Zero,
"tobool");
405 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
406 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
407 Value *Result = ZI->getOperand(0);
412 ZI->eraseFromParent();
417 return Builder.CreateIsNotNull(V,
"tobool");
431 llvm_unreachable(
"Stmt can't have complex result type!");
459 return Builder.getInt(E->
getValue());
462 return Builder.getInt(E->
getValue());
465 return llvm::ConstantFP::get(VMContext, E->
getValue());
468 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
471 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
474 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
477 return EmitNullValue(E->
getType());
480 return EmitNullValue(E->
getType());
510 return EmitLoadOfLValue(E);
520 return EmitLoadOfLValue(E);
525 return EmitLoadOfLValue(E);
541 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
545 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, Version.getMajor()),
546 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, Min ? *Min : 0),
547 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, SMin ? *SMin : 0),
557 Value *VisitExtVectorElementExpr(
Expr *E) {
return EmitLoadOfLValue(E); }
559 return EmitLoadOfLValue(E);
566 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
571 return EmitNullValue(E->
getType());
575 return VisitCastExpr(E);
581 return EmitLoadOfLValue(E);
585 EmitLValueAlignmentAssumption(E, V);
594 return EmitScalarPrePostIncDec(E, LV,
false,
false);
598 return EmitScalarPrePostIncDec(E, LV,
true,
false);
602 return EmitScalarPrePostIncDec(E, LV,
false,
true);
606 return EmitScalarPrePostIncDec(E, LV,
true,
true);
614 bool isInc,
bool isPre);
618 if (isa<MemberPointerType>(E->
getType()))
621 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
626 return EmitLoadOfLValue(E);
630 TestAndClearIgnoreResultAssign();
644 return EmitLoadOfLValue(E);
676 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
688 return llvm::ConstantInt::get(Builder.getInt32Ty(), E->
getValue());
692 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
706 return EmitNullValue(E->
getType());
715 return Builder.getInt1(E->
getValue());
719 Value *EmitMul(
const BinOpInfo &Ops) {
720 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
721 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
723 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
725 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
726 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
729 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
730 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
731 return EmitOverflowCheckedBinOp(Ops);
735 if (Ops.Ty->isUnsignedIntegerType() &&
736 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
737 !CanElideOverflowCheck(CGF.
getContext(), Ops))
738 return EmitOverflowCheckedBinOp(Ops);
740 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
741 Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
742 return propagateFMFlags(V, Ops);
744 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
748 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
751 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
755 Value *EmitDiv(
const BinOpInfo &Ops);
756 Value *EmitRem(
const BinOpInfo &Ops);
757 Value *EmitAdd(
const BinOpInfo &Ops);
758 Value *EmitSub(
const BinOpInfo &Ops);
759 Value *EmitShl(
const BinOpInfo &Ops);
760 Value *EmitShr(
const BinOpInfo &Ops);
761 Value *EmitAnd(
const BinOpInfo &Ops) {
762 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
764 Value *EmitXor(
const BinOpInfo &Ops) {
765 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
767 Value *EmitOr (
const BinOpInfo &Ops) {
768 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
772 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
776 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
780 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
783 #define HANDLEBINOP(OP) \ 784 Value *VisitBin ## OP(const BinaryOperator *E) { \ 785 return Emit ## OP(EmitBinOps(E)); \ 787 Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \ 788 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \ 804 llvm::CmpInst::Predicate SICmpOpc,
805 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
806 #define VISITCOMP(CODE, UI, SI, FP, SIG) \ 807 Value *VisitBin##CODE(const BinaryOperator *E) { \ 808 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \ 809 llvm::FCmpInst::FP, SIG); } 824 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
825 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
860 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
863 return EmitFloatToBoolConversion(Src);
868 assert((SrcType->
isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
869 "Unknown scalar type to convert");
871 if (isa<llvm::IntegerType>(Src->getType()))
872 return EmitIntToBoolConversion(Src);
874 assert(isa<llvm::PointerType>(Src->getType()));
875 return EmitPointerToBoolConversion(Src, SrcType);
878 void ScalarExprEmitter::EmitFloatConversionCheck(
881 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
882 if (!isa<llvm::IntegerType>(DstTy))
890 const llvm::fltSemantics &SrcSema =
899 APSInt Min = APSInt::getMinValue(Width, Unsigned);
900 APFloat MinSrc(SrcSema, APFloat::uninitialized);
901 if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
905 MinSrc = APFloat::getInf(SrcSema,
true);
909 MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
911 APSInt Max = APSInt::getMaxValue(Width, Unsigned);
912 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
913 if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
917 MaxSrc = APFloat::getInf(SrcSema,
false);
921 MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
926 const llvm::fltSemantics &
Sema =
929 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
930 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
934 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
936 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
937 Check = Builder.CreateAnd(GE, LE);
942 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
943 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
948 static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
949 std::pair<llvm::Value *, SanitizerMask>>
958 assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits());
959 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
960 "non-integer llvm type");
967 ScalarExprEmitter::ImplicitConversionCheckKind
Kind;
969 if (!SrcSigned && !DstSigned) {
970 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
971 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
973 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
974 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
979 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
981 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
983 return std::make_pair(Kind, std::make_pair(Check, Mask));
991 void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1003 unsigned SrcBits = Src->getType()->getScalarSizeInBits();
1004 unsigned DstBits = Dst->getType()->getScalarSizeInBits();
1006 if (SrcBits <= DstBits)
1009 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1016 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1017 (!SrcSigned && DstSigned))
1022 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1023 std::pair<llvm::Value *, SanitizerMask>>
1032 llvm::Constant *StaticArgs[] = {
1035 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)};
1036 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1042 static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1043 std::pair<llvm::Value *, SanitizerMask>>
1049 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1050 "non-integer llvm type");
1056 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1057 unsigned DstBits = DstTy->getScalarSizeInBits();
1061 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1062 "either the widths should be different, or the signednesses.");
1066 const char *Name) ->
Value * {
1068 bool VSigned = VType->isSignedIntegerOrEnumerationType();
1073 return llvm::ConstantInt::getFalse(VTy->getContext());
1076 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1079 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
1080 llvm::Twine(Name) +
"." + V->getName() +
1081 ".negativitycheck");
1085 llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType,
"src");
1087 llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType,
"dst");
1093 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1095 return std::make_pair(
1096 ScalarExprEmitter::ICCK_IntegerSignChange,
1097 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1100 void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1103 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1117 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1118 unsigned DstBits = DstTy->getScalarSizeInBits();
1125 if (SrcSigned == DstSigned && SrcBits == DstBits)
1129 if (!SrcSigned && !DstSigned)
1134 if ((DstBits > SrcBits) && DstSigned)
1136 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1137 (SrcBits > DstBits) && SrcSigned) {
1147 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1148 std::pair<llvm::Value *, SanitizerMask>>
1152 ImplicitConversionCheckKind CheckKind;
1158 CheckKind = Check.first;
1159 Checks.emplace_back(Check.second);
1161 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1162 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1168 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1169 Checks.emplace_back(Check.second);
1173 llvm::Constant *StaticArgs[] = {
1176 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)};
1178 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1187 ScalarConversionOpts Opts) {
1202 return Builder.CreateIsNotNull(Src,
"tobool");
1204 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1207 "Unhandled scalar conversion from a fixed point type to another type.");
1211 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1214 "Unhandled scalar conversion to a fixed point type from another type.");
1217 QualType NoncanonicalSrcType = SrcType;
1218 QualType NoncanonicalDstType = DstType;
1222 if (SrcType == DstType)
return Src;
1232 return EmitConversionToBool(Src, SrcType);
1239 if (DstTy->isFloatingPointTy()) {
1241 return Builder.CreateCall(
1249 Src = Builder.CreateCall(
1254 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1262 if (SrcTy == DstTy) {
1263 if (Opts.EmitImplicitIntegerSignChangeChecks)
1264 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1265 NoncanonicalDstType, Loc);
1273 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1275 if (isa<llvm::PointerType>(SrcTy))
1278 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1284 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1286 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1289 if (isa<llvm::PointerType>(SrcTy)) {
1291 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1292 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1301 "Splatted expr doesn't match with vector element type?");
1304 unsigned NumElements = DstTy->getVectorNumElements();
1305 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1308 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1310 unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
1311 unsigned DstSize = DstTy->getPrimitiveSizeInBits();
1312 if (SrcSize == DstSize)
1322 llvm::Type *SrcElementTy = SrcTy->getVectorElementType();
1323 llvm::Type *DstElementTy = DstTy->getVectorElementType();
1326 assert(((SrcElementTy->isIntegerTy() &&
1327 DstElementTy->isIntegerTy()) ||
1328 (SrcElementTy->isFloatingPointTy() &&
1329 DstElementTy->isFloatingPointTy())) &&
1330 "unexpected conversion between a floating-point vector and an " 1334 if (SrcElementTy->isIntegerTy())
1335 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1338 if (SrcSize > DstSize)
1339 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1342 return Builder.CreateFPExt(Src, DstTy,
"conv");
1346 Value *Res =
nullptr;
1354 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1356 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1362 if (SrcTy->isFloatingPointTy()) {
1366 return Builder.CreateCall(
1369 return Builder.CreateFPTrunc(Src, DstTy);
1374 if (isa<llvm::IntegerType>(SrcTy)) {
1376 if (SrcType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1379 if (isa<llvm::IntegerType>(DstTy))
1380 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1381 else if (InputSigned)
1382 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1384 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1385 }
else if (isa<llvm::IntegerType>(DstTy)) {
1386 assert(SrcTy->isFloatingPointTy() &&
"Unknown real conversion");
1388 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1390 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1392 assert(SrcTy->isFloatingPointTy() && DstTy->isFloatingPointTy() &&
1393 "Unknown real conversion");
1394 if (DstTy->getTypeID() < SrcTy->getTypeID())
1395 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1397 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1400 if (DstTy != ResTy) {
1402 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1403 Res = Builder.CreateCall(
1407 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1411 if (Opts.EmitImplicitIntegerTruncationChecks)
1412 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1413 NoncanonicalDstType, Loc);
1415 if (Opts.EmitImplicitIntegerSignChangeChecks)
1416 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1417 NoncanonicalDstType, Loc);
1429 return EmitFixedPointConversion(Src, SrcFPSema, DstFPSema, Loc,
1433 Value *ScalarExprEmitter::EmitFixedPointConversion(
1437 using llvm::ConstantInt;
1440 unsigned SrcWidth = SrcFPSema.
getWidth();
1441 unsigned DstWidth = DstFPSema.
getWidth();
1442 unsigned SrcScale = SrcFPSema.
getScale();
1443 unsigned DstScale = DstFPSema.
getScale();
1444 bool SrcIsSigned = SrcFPSema.
isSigned();
1445 bool DstIsSigned = DstFPSema.
isSigned();
1447 llvm::Type *DstIntTy = Builder.getIntNTy(DstWidth);
1449 Value *Result = Src;
1450 unsigned ResultWidth = SrcWidth;
1453 if (DstScale < SrcScale) {
1457 if (DstIsInteger && SrcIsSigned) {
1458 Value *Zero = llvm::Constant::getNullValue(Result->getType());
1459 Value *IsNegative = Builder.CreateICmpSLT(Result, Zero);
1460 Value *LowBits = ConstantInt::get(
1461 CGF.
getLLVMContext(), APInt::getLowBitsSet(ResultWidth, SrcScale));
1462 Value *Rounded = Builder.CreateAdd(Result, LowBits);
1463 Result = Builder.CreateSelect(IsNegative, Rounded, Result);
1466 Result = SrcIsSigned
1467 ? Builder.CreateAShr(Result, SrcScale - DstScale,
"downscale")
1468 : Builder.CreateLShr(Result, SrcScale - DstScale,
"downscale");
1473 Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
1476 if (DstScale > SrcScale)
1477 Result = Builder.CreateShl(Result, DstScale - SrcScale,
"upscale");
1480 if (DstScale > SrcScale) {
1482 ResultWidth =
std::max(SrcWidth + DstScale - SrcScale, DstWidth);
1483 llvm::Type *UpscaledTy = Builder.getIntNTy(ResultWidth);
1484 Result = Builder.CreateIntCast(Result, UpscaledTy, SrcIsSigned,
"resize");
1485 Result = Builder.CreateShl(Result, DstScale - SrcScale,
"upscale");
1491 Value *Max = ConstantInt::get(
1494 Value *TooHigh = SrcIsSigned ? Builder.CreateICmpSGT(Result, Max)
1495 : Builder.CreateICmpUGT(Result, Max);
1496 Result = Builder.CreateSelect(TooHigh, Max, Result,
"satmax");
1500 if (SrcIsSigned && (LessIntBits || !DstIsSigned)) {
1501 Value *Min = ConstantInt::get(
1504 Value *TooLow = Builder.CreateICmpSLT(Result, Min);
1505 Result = Builder.CreateSelect(TooLow, Min, Result,
"satmin");
1509 if (ResultWidth != DstWidth)
1510 Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
1517 Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1526 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1527 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1528 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1535 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1546 void ScalarExprEmitter::EmitBinOpCheck(
1547 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1559 if (UO && UO->
getOpcode() == UO_Minus) {
1560 Check = SanitizerHandler::NegateOverflow;
1562 DynamicData.push_back(Info.RHS);
1566 Check = SanitizerHandler::ShiftOutOfBounds;
1568 StaticData.push_back(
1570 StaticData.push_back(
1572 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1574 Check = SanitizerHandler::DivremOverflow;
1579 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1580 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1581 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1582 default: llvm_unreachable(
"unexpected opcode for bin op check");
1586 DynamicData.push_back(Info.LHS);
1587 DynamicData.push_back(Info.RHS);
1590 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1597 Value *ScalarExprEmitter::VisitExpr(
Expr *E) {
1611 llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType());
1612 unsigned LHSElts = LTy->getNumElements();
1616 llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType());
1620 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1621 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1629 llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(),
1630 MTy->getNumElements());
1631 Value* NewV = llvm::UndefValue::get(RTy);
1632 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1633 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1634 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1636 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1637 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1649 if (Idx.isSigned() && Idx.isAllOnesValue())
1650 indices.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
1652 indices.push_back(Builder.getInt32(Idx.getZExtValue()));
1655 Value *SV = llvm::ConstantVector::get(indices);
1656 return Builder.CreateShuffleVector(V1, V2, SV,
"shuffle");
1667 if (SrcType == DstType)
return Src;
1670 "ConvertVector source type must be a vector");
1672 "ConvertVector destination type must be a vector");
1684 assert(SrcTy->isVectorTy() &&
1685 "ConvertVector source IR type must be a vector");
1686 assert(DstTy->isVectorTy() &&
1687 "ConvertVector destination IR type must be a vector");
1689 llvm::Type *SrcEltTy = SrcTy->getVectorElementType(),
1690 *DstEltTy = DstTy->getVectorElementType();
1692 if (DstEltType->isBooleanType()) {
1693 assert((SrcEltTy->isFloatingPointTy() ||
1694 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1696 llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
1697 if (SrcEltTy->isFloatingPointTy()) {
1698 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1700 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1705 Value *Res =
nullptr;
1707 if (isa<llvm::IntegerType>(SrcEltTy)) {
1709 if (isa<llvm::IntegerType>(DstEltTy))
1710 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1711 else if (InputSigned)
1712 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1714 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1715 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1716 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1717 if (DstEltType->isSignedIntegerOrEnumerationType())
1718 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1720 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1722 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1723 "Unknown real conversion");
1724 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1725 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1727 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1742 return Builder.getInt(Value);
1746 return EmitLoadOfLValue(E);
1750 TestAndClearIgnoreResultAssign();
1757 return EmitLoadOfLValue(E);
1765 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1768 return Builder.CreateExtractElement(Base, Idx,
"vecext");
1771 static llvm::Constant *
getMaskElt(llvm::ShuffleVectorInst *SVI,
unsigned Idx,
1773 int MV = SVI->getMaskValue(Idx);
1775 return llvm::UndefValue::get(I32Ty);
1776 return llvm::ConstantInt::get(I32Ty, Off+MV);
1780 if (C->getBitWidth() != 32) {
1781 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
1782 C->getZExtValue()) &&
1783 "Index operand too large for shufflevector mask!");
1784 return llvm::ConstantInt::get(I32Ty, C->getZExtValue());
1790 bool Ignore = TestAndClearIgnoreResultAssign();
1792 assert (Ignore ==
false &&
"init list ignored");
1798 llvm::VectorType *VType =
1799 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
1802 if (NumInitElements == 0) {
1804 return EmitNullValue(E->
getType());
1810 unsigned ResElts = VType->getNumElements();
1817 unsigned CurIdx = 0;
1818 bool VIsUndefShuffle =
false;
1820 for (
unsigned i = 0; i != NumInitElements; ++i) {
1822 Value *Init = Visit(IE);
1825 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
1831 if (isa<ExtVectorElementExpr>(IE)) {
1832 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
1834 if (EI->getVectorOperandType()->getNumElements() == ResElts) {
1835 llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
1836 Value *LHS =
nullptr, *RHS =
nullptr;
1841 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1843 LHS = EI->getVectorOperand();
1845 VIsUndefShuffle =
true;
1846 }
else if (VIsUndefShuffle) {
1848 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
1849 for (
unsigned j = 0; j != CurIdx; ++j)
1851 Args.push_back(Builder.getInt32(ResElts + C->getZExtValue()));
1852 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1854 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
1855 RHS = EI->getVectorOperand();
1856 VIsUndefShuffle =
false;
1858 if (!Args.empty()) {
1859 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1860 V = Builder.CreateShuffleVector(LHS, RHS, Mask);
1866 V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
1868 VIsUndefShuffle =
false;
1873 unsigned InitElts = VVT->getNumElements();
1878 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
1879 if (isa<ExtVectorElementExpr>(IE)) {
1880 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
1881 Value *SVOp = SVI->getOperand(0);
1882 llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType());
1884 if (OpTy->getNumElements() == ResElts) {
1885 for (
unsigned j = 0; j != CurIdx; ++j) {
1888 if (VIsUndefShuffle) {
1889 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0,
1892 Args.push_back(Builder.getInt32(j));
1895 for (
unsigned j = 0, je = InitElts; j != je; ++j)
1897 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1899 if (VIsUndefShuffle)
1900 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
1909 for (
unsigned j = 0; j != InitElts; ++j)
1910 Args.push_back(Builder.getInt32(j));
1911 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1912 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1913 Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT),
1917 for (
unsigned j = 0; j != CurIdx; ++j)
1918 Args.push_back(Builder.getInt32(j));
1919 for (
unsigned j = 0; j != InitElts; ++j)
1920 Args.push_back(Builder.getInt32(j+Offset));
1921 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1928 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1929 V = Builder.CreateShuffleVector(V, Init, Mask,
"vecinit");
1930 VIsUndefShuffle = isa<llvm::UndefValue>(Init);
1939 for (; CurIdx < ResElts; ++CurIdx) {
1940 Value *Idx = Builder.getInt32(CurIdx);
1941 llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
1942 V = Builder.CreateInsertElement(V, Init, Idx,
"vecinit");
1950 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
1977 bool Ignored = TestAndClearIgnoreResultAssign();
1983 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
1984 case CK_BuiltinFnToFnPtr:
1985 llvm_unreachable(
"builtin functions are handled elsewhere");
1987 case CK_LValueBitCast:
1988 case CK_ObjCObjectLValueCast: {
1989 Address Addr = EmitLValue(E).getAddress(CGF);
1992 return EmitLoadOfLValue(LV, CE->
getExprLoc());
1995 case CK_LValueToRValueBitCast: {
2001 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2004 case CK_CPointerToObjCPointerCast:
2005 case CK_BlockPointerToObjCPointerCast:
2006 case CK_AnyPointerToBlockPointerCast:
2008 Value *Src = Visit(const_cast<Expr*>(E));
2011 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2012 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2013 llvm_unreachable(
"wrong cast for pointers in different address spaces" 2014 "(must be an address space cast)!");
2017 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2031 Src = Builder.CreateLaunderInvariantGroup(Src);
2039 Src = Builder.CreateStripInvariantGroup(Src);
2044 if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(Src))
2045 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE))
2051 case CK_AddressSpaceConversion: {
2061 ConvertType(DestTy)), DestTy);
2069 case CK_AtomicToNonAtomic:
2070 case CK_NonAtomicToAtomic:
2072 case CK_UserDefinedConversion:
2073 return Visit(const_cast<Expr*>(E));
2075 case CK_BaseToDerived: {
2077 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2091 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2099 case CK_UncheckedDerivedToBase:
2100 case CK_DerivedToBase: {
2112 case CK_ArrayToPointerDecay:
2114 case CK_FunctionToPointerDecay:
2115 return EmitLValue(E).getPointer(CGF);
2117 case CK_NullToPointer:
2118 if (MustVisitNullValue(E))
2124 case CK_NullToMemberPointer: {
2125 if (MustVisitNullValue(E))
2132 case CK_ReinterpretMemberPointer:
2133 case CK_BaseToDerivedMemberPointer:
2134 case CK_DerivedToBaseMemberPointer: {
2135 Value *Src = Visit(E);
2146 case CK_ARCProduceObject:
2148 case CK_ARCConsumeObject:
2150 case CK_ARCReclaimReturnedObject:
2152 case CK_ARCExtendBlockObject:
2155 case CK_CopyAndAutoreleaseBlockObject:
2158 case CK_FloatingRealToComplex:
2159 case CK_FloatingComplexCast:
2160 case CK_IntegralRealToComplex:
2161 case CK_IntegralComplexCast:
2162 case CK_IntegralComplexToFloatingComplex:
2163 case CK_FloatingComplexToIntegralComplex:
2164 case CK_ConstructorConversion:
2166 llvm_unreachable(
"scalar cast to non-scalar value");
2168 case CK_LValueToRValue:
2170 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2171 return Visit(const_cast<Expr*>(E));
2173 case CK_IntegralToPointer: {
2174 Value *Src = Visit(const_cast<Expr*>(E));
2178 auto DestLLVMTy = ConvertType(DestTy);
2182 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2184 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2190 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2194 case CK_PointerToIntegral: {
2195 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2196 auto *PtrExpr = Visit(E);
2204 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2207 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2213 case CK_VectorSplat: {
2215 Value *Elt = Visit(const_cast<Expr*>(E));
2217 unsigned NumElements = DstTy->getVectorNumElements();
2218 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2221 case CK_FixedPointCast:
2222 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2225 case CK_FixedPointToBoolean:
2227 "Expected src type to be fixed point type");
2228 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2229 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2232 case CK_FixedPointToIntegral:
2234 "Expected src type to be fixed point type");
2235 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2236 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2239 case CK_IntegralToFixedPoint:
2241 "Expected src type to be an integer");
2243 "Expected dest type to be fixed point type");
2244 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2247 case CK_IntegralCast: {
2248 ScalarConversionOpts Opts;
2249 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2250 if (!ICE->isPartOfExplicitCast())
2251 Opts = ScalarConversionOpts(CGF.
SanOpts);
2253 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2256 case CK_IntegralToFloating:
2257 case CK_FloatingToIntegral:
2258 case CK_FloatingCast:
2259 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2261 case CK_BooleanToSignedIntegral: {
2262 ScalarConversionOpts Opts;
2263 Opts.TreatBooleanAsSigned =
true;
2264 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2267 case CK_IntegralToBoolean:
2268 return EmitIntToBoolConversion(Visit(E));
2269 case CK_PointerToBoolean:
2270 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2271 case CK_FloatingToBoolean:
2272 return EmitFloatToBoolConversion(Visit(E));
2273 case CK_MemberPointerToBoolean: {
2279 case CK_FloatingComplexToReal:
2280 case CK_IntegralComplexToReal:
2283 case CK_FloatingComplexToBoolean:
2284 case CK_IntegralComplexToBoolean: {
2288 return EmitComplexToScalarConversion(V, E->
getType(), DestTy,
2292 case CK_ZeroToOCLOpaqueType: {
2295 "CK_ZeroToOCLEvent cast on non-event type");
2296 return llvm::Constant::getNullValue(ConvertType(DestTy));
2299 case CK_IntToOCLSampler:
2304 llvm_unreachable(
"unknown scalar cast");
2307 Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
2335 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2337 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2343 llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2346 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2347 StringRef Name = IsInc ?
"inc" :
"dec";
2348 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2350 return Builder.CreateAdd(InVal, Amount, Name);
2352 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2353 return Builder.CreateNSWAdd(InVal, Amount, Name);
2357 return Builder.CreateNSWAdd(InVal, Amount, Name);
2360 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2365 class OMPLastprivateConditionalUpdateRAII {
2374 ~OMPLastprivateConditionalUpdateRAII() {
2384 bool isInc,
bool isPre) {
2385 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
2387 llvm::PHINode *atomicPHI =
nullptr;
2391 int amount = (isInc ? 1 : -1);
2392 bool isSubtraction = !isInc;
2395 type = atomicTy->getValueType();
2400 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2401 return Builder.getTrue();
2405 return Builder.CreateAtomicRMW(
2406 llvm::AtomicRMWInst::Xchg, LV.
getPointer(CGF), True,
2407 llvm::AtomicOrdering::SequentiallyConsistent);
2414 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2422 llvm::ConstantInt::get(ConvertType(type), 1,
true), type);
2424 Builder.CreateAtomicRMW(aop, LV.
getPointer(CGF), amt,
2425 llvm::AtomicOrdering::SequentiallyConsistent);
2426 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2428 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2431 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2434 Builder.CreateBr(opBB);
2435 Builder.SetInsertPoint(opBB);
2436 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2437 atomicPHI->addIncoming(value, startBB);
2440 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2452 value = Builder.getTrue();
2457 bool canPerformLossyDemotionCheck =
false;
2460 assert(promotedType != type &&
"Shouldn't promote to the same type.");
2461 canPerformLossyDemotionCheck =
true;
2462 canPerformLossyDemotionCheck &=
2465 canPerformLossyDemotionCheck &=
2467 type, promotedType);
2468 assert((!canPerformLossyDemotionCheck ||
2471 ConvertType(type)->getScalarSizeInBits() ==
2472 ConvertType(promotedType)->getScalarSizeInBits()) &&
2473 "The following check expects that if we do promotion to different " 2474 "underlying canonical type, at least one of the types (either " 2475 "base or promoted) will be signed, or the bitwidths will match.");
2478 SanitizerKind::ImplicitIntegerArithmeticValueChange) &&
2479 canPerformLossyDemotionCheck) {
2489 value = EmitScalarConversion(value, type, promotedType, E->
getExprLoc());
2490 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2491 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2494 value = EmitScalarConversion(value, promotedType, type, E->
getExprLoc(),
2495 ScalarConversionOpts(CGF.
SanOpts));
2501 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
2503 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2507 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2508 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2519 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2521 value = Builder.CreateGEP(value, numElts,
"vla.inc");
2524 value, numElts,
false, isSubtraction,
2533 value = Builder.CreateGEP(value, amt,
"incdec.funcptr");
2544 value = Builder.CreateGEP(value, amt,
"incdec.ptr");
2554 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2556 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2558 value = Builder.CreateFAdd(
2560 llvm::ConstantFP::get(value->getType(), amount),
2561 isInc ?
"inc" :
"dec");
2572 value = Builder.CreateCall(
2575 input,
"incdec.conv");
2577 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
2581 if (value->getType()->isFloatTy())
2582 amt = llvm::ConstantFP::get(VMContext,
2583 llvm::APFloat(static_cast<float>(amount)));
2584 else if (value->getType()->isDoubleTy())
2585 amt = llvm::ConstantFP::get(VMContext,
2586 llvm::APFloat(static_cast<double>(amount)));
2589 llvm::APFloat F(static_cast<float>(amount));
2591 const llvm::fltSemantics *FS;
2594 if (value->getType()->isFP128Ty())
2596 else if (value->getType()->isHalfTy())
2600 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
2601 amt = llvm::ConstantFP::get(VMContext, F);
2603 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
2607 value = Builder.CreateCall(
2610 value,
"incdec.conv");
2612 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
2622 if (!isInc) size = -size;
2627 value = Builder.CreateGEP(value, sizeValue,
"incdec.objptr");
2630 false, isSubtraction,
2636 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
2642 atomicPHI->addIncoming(old, curBlock);
2643 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
2644 Builder.SetInsertPoint(contBB);
2645 return isPre ? value : input;
2656 return isPre ? value : input;
2662 TestAndClearIgnoreResultAssign();
2666 if (Op->getType()->isFPOrFPVectorTy())
2667 return Builder.CreateFNeg(Op,
"fneg");
2672 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
2674 BinOp.Opcode = BO_Sub;
2677 return EmitSub(BinOp);
2681 TestAndClearIgnoreResultAssign();
2683 return Builder.CreateNot(Op,
"neg");
2690 Value *Zero = llvm::Constant::getNullValue(Oper->getType());
2692 if (Oper->getType()->isFPOrFPVectorTy())
2693 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
2695 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
2696 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
2705 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
2708 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
2716 return Builder.getInt(Value);
2722 llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
2724 for (
unsigned i = 0; i != n; ++i) {
2733 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
2740 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
2744 Offset = Builder.CreateMul(Idx, ElemSize);
2758 Field != FieldEnd; ++Field, ++i) {
2759 if (*Field == MemberDecl)
2762 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
2767 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
2770 CurrentType = MemberDecl->
getType();
2775 llvm_unreachable(
"dependent __builtin_offsetof");
2793 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
2797 Result = Builder.CreateAdd(Result, Offset);
2805 ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
2825 if (!eltSize.
isOne())
2836 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
2881 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
2888 BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E) {
2889 TestAndClearIgnoreResultAssign();
2891 Result.LHS = Visit(E->
getLHS());
2892 Result.RHS = Visit(E->
getRHS());
2900 LValue ScalarExprEmitter::EmitCompoundAssignLValue(
2902 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &),
2912 OpInfo.RHS = Visit(E->
getRHS());
2920 llvm::PHINode *atomicPHI =
nullptr;
2925 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2928 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
2929 llvm::Instruction::BinaryOps Op;
2930 switch (OpInfo.Opcode) {
2932 case BO_MulAssign:
case BO_DivAssign:
2950 AtomicOp = llvm::AtomicRMWInst::Xor;
2951 Op = llvm::Instruction::Xor;
2954 AtomicOp = llvm::AtomicRMWInst::Or;
2955 Op = llvm::Instruction::Or;
2958 llvm_unreachable(
"Invalid compound assignment type");
2960 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
2962 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
2965 Value *OldVal = Builder.CreateAtomicRMW(
2967 llvm::AtomicOrdering::SequentiallyConsistent);
2971 Result = Builder.CreateBinOp(Op, OldVal, Amt);
2977 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2979 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2981 Builder.CreateBr(opBB);
2982 Builder.SetInsertPoint(opBB);
2983 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
2984 atomicPHI->addIncoming(OpInfo.LHS, startBB);
2985 OpInfo.LHS = atomicPHI;
2988 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2995 Result = (this->*Func)(OpInfo);
3000 Loc, ScalarConversionOpts(CGF.
SanOpts));
3003 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3009 atomicPHI->addIncoming(old, curBlock);
3010 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3011 Builder.SetInsertPoint(contBB);
3031 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &)) {
3032 bool Ignore = TestAndClearIgnoreResultAssign();
3033 Value *RHS =
nullptr;
3034 LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
3049 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3052 void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3053 const BinOpInfo &Ops,
llvm::Value *Zero,
bool isDiv) {
3056 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3057 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
3058 SanitizerKind::IntegerDivideByZero));
3061 const auto *BO = cast<BinaryOperator>(Ops.E);
3062 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
3063 Ops.Ty->hasSignedIntegerRepresentation() &&
3064 !IsWidenedIntegerOp(CGF.
getContext(), BO->getLHS()) &&
3065 Ops.mayHaveIntegerOverflow()) {
3066 llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
3069 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3070 llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL);
3072 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
3073 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
3074 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
3076 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3079 if (Checks.size() > 0)
3080 EmitBinOpCheck(Checks, Ops);
3083 Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
3086 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3087 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3088 Ops.Ty->isIntegerType() &&
3089 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3090 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3091 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
3092 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
3093 Ops.Ty->isRealFloatingType() &&
3094 Ops.mayHaveFloatDivisionByZero()) {
3095 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3096 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
3097 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3102 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3103 llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3112 if (ValTy->isFloatTy() ||
3113 (isa<llvm::VectorType>(ValTy) &&
3114 cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy()))
3119 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3120 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3122 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3125 Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3127 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3128 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3129 Ops.Ty->isIntegerType() &&
3130 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3132 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3133 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3136 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3137 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3139 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3142 Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3146 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3147 switch (Ops.Opcode) {
3151 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3152 llvm::Intrinsic::uadd_with_overflow;
3157 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3158 llvm::Intrinsic::usub_with_overflow;
3163 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3164 llvm::Intrinsic::umul_with_overflow;
3167 llvm_unreachable(
"Unsupported operation for overflow detection");
3178 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3179 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3180 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3183 const std::string *handlerName =
3185 if (handlerName->empty()) {
3188 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3189 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3191 : SanitizerKind::UnsignedIntegerOverflow;
3192 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3199 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3200 llvm::BasicBlock *continueBB =
3204 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3208 Builder.SetInsertPoint(overflowBB);
3213 llvm::FunctionType *handlerTy =
3214 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3215 llvm::FunctionCallee handler =
3228 Builder.getInt8(OpID),
3229 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3235 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3236 Builder.CreateBr(continueBB);
3238 Builder.SetInsertPoint(continueBB);
3239 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3240 phi->addIncoming(result, initialBB);
3241 phi->addIncoming(handlerResult, overflowBB);
3248 const BinOpInfo &op,
3249 bool isSubtraction) {
3254 Value *pointer = op.LHS;
3256 Value *index = op.RHS;
3260 if (!isSubtraction && !pointer->getType()->isPointerTy()) {
3261 std::swap(pointer, index);
3262 std::swap(pointerOperand, indexOperand);
3267 unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
3269 auto PtrTy = cast<llvm::PointerType>(pointer->getType());
3292 return CGF.
Builder.CreateIntToPtr(index, pointer->getType());
3294 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
3297 index = CGF.
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
3303 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3305 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
3318 index = CGF.
Builder.CreateMul(index, objectSize);
3321 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
3336 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
3337 pointer = CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
3339 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
3342 op.E->getExprLoc(),
"add.ptr");
3352 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
3357 return CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
3360 op.E->getExprLoc(),
"add.ptr");
3370 bool negMul,
bool negAdd) {
3371 assert(!(negMul && negAdd) &&
"Only one of negMul and negAdd should be set.");
3373 Value *MulOp0 = MulOp->getOperand(0);
3374 Value *MulOp1 = MulOp->getOperand(1);
3376 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
3378 Addend = Builder.CreateFNeg(Addend,
"neg");
3380 Value *FMulAdd = Builder.CreateCall(
3382 {MulOp0, MulOp1, Addend});
3383 MulOp->eraseFromParent();
3398 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
3399 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
3400 "Only fadd/fsub can be the root of an fmuladd.");
3403 if (!op.FPFeatures.allowFPContractWithinStatement())
3409 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) {
3410 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3411 LHSBinOp->use_empty())
3412 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder,
false, isSub);
3414 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) {
3415 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3416 RHSBinOp->use_empty())
3417 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub,
false);
3423 Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
3424 if (op.LHS->getType()->isPointerTy() ||
3425 op.RHS->getType()->isPointerTy())
3428 if (op.Ty->isSignedIntegerOrEnumerationType()) {
3429 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3431 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3433 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3434 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3437 if (CanElideOverflowCheck(CGF.
getContext(), op))
3438 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3439 return EmitOverflowCheckedBinOp(op);
3443 if (op.Ty->isUnsignedIntegerType() &&
3444 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3445 !CanElideOverflowCheck(CGF.
getContext(), op))
3446 return EmitOverflowCheckedBinOp(op);
3448 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3453 Value *V = Builder.CreateFAdd(op.LHS, op.RHS,
"add");
3454 return propagateFMFlags(V, op);
3457 if (op.isFixedPointBinOp())
3458 return EmitFixedPointBinOp(op);
3460 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3465 Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
3467 using llvm::ConstantInt;
3469 const auto *BinOp = cast<BinaryOperator>(op.E);
3475 QualType LHSTy = BinOp->getLHS()->getType();
3476 QualType RHSTy = BinOp->getRHS()->getType();
3478 Value *LHS = op.LHS;
3479 Value *RHS = op.RHS;
3487 Value *FullLHS = EmitFixedPointConversion(LHS, LHSFixedSema, CommonFixedSema,
3488 BinOp->getExprLoc());
3489 Value *FullRHS = EmitFixedPointConversion(RHS, RHSFixedSema, CommonFixedSema,
3490 BinOp->getExprLoc());
3494 switch (BinOp->getOpcode()) {
3496 if (ResultFixedSema.isSaturated()) {
3498 ? llvm::Intrinsic::sadd_sat
3499 : llvm::Intrinsic::uadd_sat;
3500 Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS);
3502 Result = Builder.CreateAdd(FullLHS, FullRHS);
3507 if (ResultFixedSema.isSaturated()) {
3509 ? llvm::Intrinsic::ssub_sat
3510 : llvm::Intrinsic::usub_sat;
3511 Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS);
3513 Result = Builder.CreateSub(FullLHS, FullRHS);
3518 return CommonFixedSema.isSigned() ? Builder.CreateICmpSLT(FullLHS, FullRHS)
3519 : Builder.CreateICmpULT(FullLHS, FullRHS);
3521 return CommonFixedSema.isSigned() ? Builder.CreateICmpSGT(FullLHS, FullRHS)
3522 : Builder.CreateICmpUGT(FullLHS, FullRHS);
3524 return CommonFixedSema.isSigned() ? Builder.CreateICmpSLE(FullLHS, FullRHS)
3525 : Builder.CreateICmpULE(FullLHS, FullRHS);
3527 return CommonFixedSema.isSigned() ? Builder.CreateICmpSGE(FullLHS, FullRHS)
3528 : Builder.CreateICmpUGE(FullLHS, FullRHS);
3533 return Builder.CreateICmpEQ(FullLHS, FullRHS);
3535 return Builder.CreateICmpNE(FullLHS, FullRHS);
3549 llvm_unreachable(
"Found unimplemented fixed point binary operation");
3562 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
3566 return EmitFixedPointConversion(Result, CommonFixedSema, ResultFixedSema,
3567 BinOp->getExprLoc());
3570 Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
3572 if (!op.LHS->getType()->isPointerTy()) {
3573 if (op.Ty->isSignedIntegerOrEnumerationType()) {
3574 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3576 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
3578 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3579 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
3582 if (CanElideOverflowCheck(CGF.
getContext(), op))
3583 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
3584 return EmitOverflowCheckedBinOp(op);
3588 if (op.Ty->isUnsignedIntegerType() &&
3589 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3590 !CanElideOverflowCheck(CGF.
getContext(), op))
3591 return EmitOverflowCheckedBinOp(op);
3593 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3597 Value *V = Builder.CreateFSub(op.LHS, op.RHS,
"sub");
3598 return propagateFMFlags(V, op);
3601 if (op.isFixedPointBinOp())
3602 return EmitFixedPointBinOp(op);
3604 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
3609 if (!op.RHS->getType()->isPointerTy())
3616 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
3618 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
3619 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
3631 elementType = VlaSize.
Type;
3632 divisor = VlaSize.NumElts;
3636 if (!eltSize.
isOne())
3646 if (elementType->isVoidType() || elementType->isFunctionType())
3652 if (elementSize.
isOne())
3661 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
3664 Value *ScalarExprEmitter::GetWidthMinusOneValue(
Value* LHS,
Value* RHS) {
3665 llvm::IntegerType *Ty;
3666 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
3667 Ty = cast<llvm::IntegerType>(VT->getElementType());
3669 Ty = cast<llvm::IntegerType>(LHS->getType());
3670 return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1);
3673 Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
3676 Value *RHS = Ops.RHS;
3677 if (Ops.LHS->getType() != RHS->getType())
3678 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3680 bool SanitizeBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
3681 Ops.Ty->hasSignedIntegerRepresentation() &&
3684 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
3688 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shl.mask");
3689 else if ((SanitizeBase || SanitizeExponent) &&
3690 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3693 llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
3694 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
3696 if (SanitizeExponent) {
3698 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
3705 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
3708 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
3710 (RHS == Ops.RHS) ? WidthMinusOne
3711 : GetWidthMinusOneValue(Ops.LHS, RHS);
3714 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
3722 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
3723 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
3725 llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
3726 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
3728 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
3729 BaseCheck->addIncoming(Builder.getTrue(), Orig);
3730 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
3731 Checks.push_back(std::make_pair(BaseCheck, SanitizerKind::ShiftBase));
3734 assert(!Checks.empty());
3735 EmitBinOpCheck(Checks, Ops);
3738 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
3741 Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
3744 Value *RHS = Ops.RHS;
3745 if (Ops.LHS->getType() != RHS->getType())
3746 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3751 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shr.mask");
3752 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
3753 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3756 Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
3757 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
3760 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3761 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
3762 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
3770 default: llvm_unreachable(
"unexpected element type");
3771 case BuiltinType::Char_U:
3772 case BuiltinType::UChar:
3773 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3774 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
3775 case BuiltinType::Char_S:
3776 case BuiltinType::SChar:
3777 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3778 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
3779 case BuiltinType::UShort:
3780 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3781 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
3782 case BuiltinType::Short:
3783 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3784 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
3785 case BuiltinType::UInt:
3786 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3787 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
3788 case BuiltinType::Int:
3789 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3790 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
3791 case BuiltinType::ULong:
3792 case BuiltinType::ULongLong:
3793 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3794 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
3795 case BuiltinType::Long:
3796 case BuiltinType::LongLong:
3797 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3798 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
3799 case BuiltinType::Float:
3800 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
3801 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
3802 case BuiltinType::Double:
3803 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
3804 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
3809 llvm::CmpInst::Predicate UICmpOpc,
3810 llvm::CmpInst::Predicate SICmpOpc,
3811 llvm::CmpInst::Predicate FCmpOpc,
3813 TestAndClearIgnoreResultAssign();
3823 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
3825 BinOpInfo BOInfo = EmitBinOps(E);
3826 Value *LHS = BOInfo.LHS;
3827 Value *RHS = BOInfo.RHS;
3833 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
3838 Value *FirstVecArg = LHS,
3839 *SecondVecArg = RHS;
3845 default: llvm_unreachable(
"is not a comparison operation");
3857 std::swap(FirstVecArg, SecondVecArg);
3864 if (ElementKind == BuiltinType::Float) {
3866 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3867 std::swap(FirstVecArg, SecondVecArg);
3875 if (ElementKind == BuiltinType::Float) {
3877 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3882 std::swap(FirstVecArg, SecondVecArg);
3887 Value *CR6Param = Builder.getInt32(CR6);
3889 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
3896 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
3897 if (ResultTy->getBitWidth() > 1 &&
3899 Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
3904 if (BOInfo.isFixedPointBinOp()) {
3905 Result = EmitFixedPointBinOp(BOInfo);
3906 }
else if (LHS->getType()->isFPOrFPVectorTy()) {
3908 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
3910 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
3912 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
3917 !isa<llvm::ConstantPointerNull>(LHS) &&
3918 !isa<llvm::ConstantPointerNull>(RHS)) {
3927 LHS = Builder.CreateStripInvariantGroup(LHS);
3929 RHS = Builder.CreateStripInvariantGroup(RHS);
3932 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
3938 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
3946 CETy = CTy->getElementType();
3948 LHS.first = Visit(E->
getLHS());
3949 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
3955 CTy->getElementType()) &&
3956 "The element types must always match.");
3959 RHS.first = Visit(E->
getRHS());
3960 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
3962 "The element types must always match.");
3965 Value *ResultR, *ResultI;
3969 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
3970 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
3974 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
3975 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
3979 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
3982 "Complex comparison other than == or != ?");
3983 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
3992 bool Ignore = TestAndClearIgnoreResultAssign();
4011 RHS = Visit(E->
getRHS());
4019 RHS = Visit(E->
getRHS());
4026 if (LHS.isBitField()) {
4047 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4057 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
4058 if (LHS->getType()->isFPOrFPVectorTy()) {
4059 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4060 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4062 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4063 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4065 Value *
And = Builder.CreateAnd(LHS, RHS);
4066 return Builder.CreateSExt(And, ConvertType(E->
getType()),
"sext");
4080 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
4085 return llvm::Constant::getNullValue(ResTy);
4102 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4104 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
4113 RHSBlock = Builder.GetInsertBlock();
4122 PN->addIncoming(RHSCond, RHSBlock);
4127 PN->setDebugLoc(Builder.getCurrentDebugLocation());
4131 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
4141 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
4142 if (LHS->getType()->isFPOrFPVectorTy()) {
4143 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4144 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4146 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4147 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4149 Value *Or = Builder.CreateOr(LHS, RHS);
4150 return Builder.CreateSExt(Or, ConvertType(E->
getType()),
"sext");
4164 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
4169 return llvm::ConstantInt::get(ResTy, 1);
4187 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4189 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
4201 RHSBlock = Builder.GetInsertBlock();
4206 PN->addIncoming(RHSCond, RHSBlock);
4209 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
4215 return Visit(E->
getRHS());
4240 Value *ScalarExprEmitter::
4242 TestAndClearIgnoreResultAssign();
4255 Expr *live = lhsExpr, *dead = rhsExpr;
4256 if (!CondExprBool) std::swap(live, dead);
4262 Value *Result = Visit(live);
4285 llvm::VectorType *vecTy = cast<llvm::VectorType>(condType);
4287 unsigned numElem = vecTy->getNumElements();
4288 llvm::Type *elemType = vecTy->getElementType();
4290 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
4291 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
4293 llvm::VectorType::get(elemType,
4301 bool wasCast =
false;
4302 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
4303 if (rhsVTy->getElementType()->isFloatingPointTy()) {
4309 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
4310 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
4311 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
4326 auto *VecTy = cast<llvm::VectorType>(CondType);
4327 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
4329 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
4330 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
4347 assert(!RHS &&
"LHS and RHS types must match");
4350 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
4364 Value *LHS = Visit(lhsExpr);
4367 LHSBlock = Builder.GetInsertBlock();
4368 Builder.CreateBr(ContBlock);
4372 Value *RHS = Visit(rhsExpr);
4375 RHSBlock = Builder.GetInsertBlock();
4385 llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2,
"cond");
4386 PN->addIncoming(LHS, LHSBlock);
4387 PN->addIncoming(RHS, RHSBlock);
4409 return llvm::UndefValue::get(ArgTy);
4416 if (ArgTy != Val->getType()) {
4417 if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
4418 Val = Builder.CreateIntToPtr(Val, ArgTy);
4420 Val = Builder.CreateTrunc(Val, ArgTy);
4426 Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
4432 Value *Src,
unsigned NumElementsDst) {
4433 llvm::Value *UnV = llvm::UndefValue::get(Src->getType());
4435 Args.push_back(Builder.getInt32(0));
4436 Args.push_back(Builder.getInt32(1));
4437 Args.push_back(Builder.getInt32(2));
4438 if (NumElementsDst == 4)
4439 Args.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
4440 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
4441 return Builder.CreateShuffleVector(Src, UnV, Mask);
4461 const llvm::DataLayout &DL,
4463 StringRef Name =
"") {
4464 auto SrcTy = Src->getType();
4467 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
4471 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
4475 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
4477 if (!DstTy->isIntegerTy())
4478 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
4480 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
4484 if (!SrcTy->isIntegerTy())
4487 return Builder.CreateIntToPtr(Src, DstTy, Name);
4495 unsigned NumElementsSrc = isa<llvm::VectorType>(SrcTy) ?
4496 cast<llvm::VectorType>(SrcTy)->getNumElements() : 0;
4497 unsigned NumElementsDst = isa<llvm::VectorType>(DstTy) ?
4498 cast<llvm::VectorType>(DstTy)->getNumElements() : 0;
4502 if (NumElementsSrc == 3 && NumElementsDst != 3) {
4510 Src->setName(
"astype");
4517 if (NumElementsSrc != 3 && NumElementsDst == 3) {
4519 auto Vec4Ty = llvm::VectorType::get(DstTy->getVectorElementType(), 4);
4525 Src->setName(
"astype");
4530 Src, DstTy,
"astype");
4544 assert(E && hasScalarEvaluationKind(E->
getType()) &&
4545 "Invalid scalar expression to emit");
4547 return ScalarExprEmitter(*
this, IgnoreResultAssign)
4548 .Visit(const_cast<Expr *>(E));
4556 assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
4557 "Invalid scalar expression to emit");
4558 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
4568 "Invalid complex -> scalar conversion");
4569 return ScalarExprEmitter(*
this)
4570 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
4576 bool isInc,
bool isPre) {
4577 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
4587 Addr =
Address(EmitScalarExpr(BaseExpr), getPointerAlign());
4589 Addr = EmitLValue(BaseExpr).getAddress(*
this);
4594 return MakeAddrLValue(Addr, E->
getType());
4600 ScalarExprEmitter Scalar(*
this);
4601 Value *Result =
nullptr;
4603 #define COMPOUND_OP(Op) \ 4604 case BO_##Op##Assign: \ 4605 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \ 4642 llvm_unreachable(
"Not valid compound assignment operators");
4645 llvm_unreachable(
"Unhandled compound assignment operator");
4660 llvm::LLVMContext &VMContext,
4669 if (isa<llvm::Constant>(GEPVal)) {
4672 Value *BasePtr_int =
4673 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->getType()));
4675 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->getType()));
4676 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
4677 return {TotalOffset, Builder.getFalse()};
4680 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
4681 assert(GEP->getPointerOperand() == BasePtr &&
4682 "BasePtr must be the the base of the GEP.");
4683 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
4685 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
4688 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
4689 auto *SAddIntrinsic =
4690 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
4691 auto *SMulIntrinsic =
4692 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
4695 llvm::Value *OffsetOverflows = Builder.getFalse();
4700 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
4703 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
4704 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
4706 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
4709 OffsetOverflows = Builder.getTrue();
4710 return llvm::ConstantInt::get(VMContext, N);
4715 auto *ResultAndOverflow = Builder.CreateCall(
4716 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
4717 OffsetOverflows = Builder.CreateOr(
4718 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
4719 return Builder.CreateExtractValue(ResultAndOverflow, 0);
4723 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
4724 GTI != GTE; ++GTI) {
4726 auto *Index = GTI.getOperand();
4728 if (
auto *STy = GTI.getStructTypeOrNull()) {
4731 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
4732 LocalOffset = llvm::ConstantInt::get(
4733 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
4737 auto *ElementSize = llvm::ConstantInt::get(
4738 IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType()));
4739 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
4740 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
4745 if (!TotalOffset || TotalOffset == Zero)
4746 TotalOffset = LocalOffset;
4748 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
4751 return {TotalOffset, OffsetOverflows};
4756 bool SignedIndices,
bool IsSubtraction,
4758 Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name);
4761 if (!SanOpts.has(SanitizerKind::PointerOverflow))
4767 bool PerformNullCheck = !NullPointerIsDefined(
4768 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
4771 bool PerformOverflowCheck =
4772 !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
4774 if (!(PerformNullCheck || PerformOverflowCheck))
4777 const auto &DL = CGM.getDataLayout();
4780 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
4785 assert((!isa<llvm::Constant>(EvaluatedGEP.
TotalOffset) ||
4787 "If the offset got constant-folded, we don't expect that there was an " 4790 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
4794 if (EvaluatedGEP.
TotalOffset == Zero && CGM.getLangOpts().CPlusPlus)
4799 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
4800 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
4804 if (PerformNullCheck) {
4816 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
4817 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
4819 CGM.getLangOpts().CPlusPlus
4820 ? Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
4821 : Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
4822 Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
4825 if (PerformOverflowCheck) {
4831 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
4832 if (SignedIndices) {
4838 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4839 auto *PosOrZeroOffset =
4840 Builder.CreateICmpSGE(EvaluatedGEP.
TotalOffset, Zero);
4841 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
4843 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
4844 }
else if (!IsSubtraction) {
4849 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4855 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
4857 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
4858 Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
4861 assert(!Checks.empty() &&
"Should have produced some checks.");
4863 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
4865 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4866 EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
const llvm::DataLayout & getDataLayout() const
const Expr * getSubExpr() const
bool Mul(InterpState &S, CodePtr OpPC)
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)
llvm::Value * OffsetOverflows
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...
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created...
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
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
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.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
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().
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
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.
bool Zero(InterpState &S, CodePtr OpPC)
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
bool GE(InterpState &S, CodePtr OpPC)
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
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
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.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
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.
Address getAddress(CodeGenFunction &CGF) const
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.
bool Shl(InterpState &S, CodePtr OpPC)
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 ...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
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)"...
llvm::Value * getPointer(CodeGenFunction &CGF) const
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.
bool Shr(InterpState &S, CodePtr OpPC)
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.
This class organizes the cross-function state that is used while generating LLVM code.
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
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.
bool GT(InterpState &S, CodePtr OpPC)
EvalResult is a struct with detailed info about an evaluated expression.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
bool NE(InterpState &S, CodePtr OpPC)
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::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name. ...
llvm::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::Value * TotalOffset
llvm::APInt getValue() const
LabelDecl * getLabel() const
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)
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...
true
A convenience builder class for complex constant initializers, especially for anonymous global struct...
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.
bool LE(InterpState &S, CodePtr OpPC)
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...
bool Add(InterpState &S, CodePtr OpPC)
Represents the specialization of a concept - evaluates to a prvalue of type bool. ...
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
static Decl::Kind getKind(const Decl *D)
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...
A rewritten comparison expression that was originally written using operator syntax.
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="")
#define VISITCOMP(CODE, UI, SI, FP, SIG)
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()
Represents an implicitly-generated value initialization of an object of a given type.
bool Sub(InterpState &S, CodePtr OpPC)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool EQ(InterpState &S, CodePtr OpPC)
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.