31#include "llvm/ADT/APFixedPoint.h"
32#include "llvm/IR/CFG.h"
33#include "llvm/IR/Constants.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/DerivedTypes.h"
36#include "llvm/IR/FixedPointBuilder.h"
37#include "llvm/IR/Function.h"
38#include "llvm/IR/GetElementPtrTypeIterator.h"
39#include "llvm/IR/GlobalVariable.h"
40#include "llvm/IR/Intrinsics.h"
41#include "llvm/IR/IntrinsicsPowerPC.h"
42#include "llvm/IR/MatrixBuilder.h"
43#include "llvm/IR/Module.h"
44#include "llvm/Support/TypeSize.h"
49using namespace CodeGen;
67bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
69 llvm::APInt &Result) {
72 const auto &LHSAP = LHS->getValue();
73 const auto &RHSAP = RHS->getValue();
74 if (Opcode == BO_Add) {
75 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
76 : LHSAP.uadd_ov(RHSAP, Overflow);
77 }
else if (Opcode == BO_Sub) {
78 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
79 : LHSAP.usub_ov(RHSAP, Overflow);
80 }
else if (Opcode == BO_Mul) {
81 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
82 : LHSAP.umul_ov(RHSAP, Overflow);
83 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
84 if (
Signed && !RHS->isZero())
85 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
101 bool mayHaveIntegerOverflow()
const {
103 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
104 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
105 if (!LHSCI || !RHSCI)
109 return ::mayHaveIntegerOverflow(
114 bool isDivremOp()
const {
120 bool mayHaveIntegerDivisionByZero()
const {
122 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
128 bool mayHaveFloatDivisionByZero()
const {
130 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
131 return CFP->isZero();
138 bool isFixedPointOp()
const {
141 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
142 QualType LHSType = BinOp->getLHS()->getType();
143 QualType RHSType = BinOp->getRHS()->getType();
146 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
147 return UnOp->getSubExpr()->getType()->isFixedPointType();
152 bool rhsHasSignedIntegerRepresentation()
const {
153 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
154 QualType RHSType = BinOp->getRHS()->getType();
161static bool MustVisitNullValue(
const Expr *E) {
169static std::optional<QualType> getUnwidenedIntegerType(
const ASTContext &Ctx,
184static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
185 return getUnwidenedIntegerType(Ctx, E).has_value();
189static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
190 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
191 "Expected a unary or binary operator");
195 if (!Op.mayHaveIntegerOverflow())
199 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
200 return !UO->canOverflow();
204 const auto *BO = cast<BinaryOperator>(Op.E);
205 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
209 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
218 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
224 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
225 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
229class ScalarExprEmitter
233 bool IgnoreResultAssign;
234 llvm::LLVMContext &VMContext;
238 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
239 VMContext(cgf.getLLVMContext()) {
246 bool TestAndClearIgnoreResultAssign() {
247 bool I = IgnoreResultAssign;
248 IgnoreResultAssign =
false;
254 LValue EmitCheckedLValue(
const Expr *E, CodeGenFunction::TypeCheckKind TCK) {
258 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
259 const BinOpInfo &Info);
265 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
266 const AlignValueAttr *AVAttr =
nullptr;
267 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
271 if (
const auto *TTy =
273 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
280 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
283 AVAttr = VD->
getAttr<AlignValueAttr>();
289 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
295 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
303 Value *
V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load),
306 EmitLValueAlignmentAssumption(E,
V);
316 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
323 enum ImplicitConversionCheckKind :
unsigned char {
324 ICCK_IntegerTruncation = 0,
325 ICCK_UnsignedIntegerTruncation = 1,
326 ICCK_SignedIntegerTruncation = 2,
327 ICCK_IntegerSignChange = 3,
328 ICCK_SignedIntegerTruncationOrSignChange = 4,
344 struct ScalarConversionOpts {
345 bool TreatBooleanAsSigned;
346 bool EmitImplicitIntegerTruncationChecks;
347 bool EmitImplicitIntegerSignChangeChecks;
349 ScalarConversionOpts()
350 : TreatBooleanAsSigned(
false),
351 EmitImplicitIntegerTruncationChecks(
false),
352 EmitImplicitIntegerSignChangeChecks(
false) {}
355 : TreatBooleanAsSigned(
false),
356 EmitImplicitIntegerTruncationChecks(
358 EmitImplicitIntegerSignChangeChecks(
362 llvm::Type *SrcTy, llvm::Type *DstTy,
363 ScalarConversionOpts Opts);
367 ScalarConversionOpts Opts = ScalarConversionOpts());
376 Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
386 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
387 return Builder.CreateFCmpUNE(
V, Zero,
"tobool");
394 return Builder.CreateICmpNE(
V, Zero,
"tobool");
401 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
402 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
403 Value *Result = ZI->getOperand(0);
408 ZI->eraseFromParent();
413 return Builder.CreateIsNotNull(
V,
"tobool");
427 llvm_unreachable(
"Stmt can't have complex result type!");
453 return Visit(
GE->getResultExpr());
467 return Builder.getInt(E->
getValue());
470 return Builder.getInt(E->
getValue());
473 return llvm::ConstantFP::get(VMContext, E->
getValue());
476 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
479 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
482 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
488 return EmitNullValue(E->
getType());
491 return EmitNullValue(E->
getType());
497 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
523 return EmitLoadOfLValue(E);
533 return EmitLoadOfLValue(E);
538 return EmitLoadOfLValue(E);
554 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
564 Value *VisitExtVectorElementExpr(
Expr *E) {
return EmitLoadOfLValue(E); }
571 return EmitLoadOfLValue(E);
578 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
583 return EmitNullValue(E->
getType());
587 return VisitCastExpr(E);
593 return EmitLoadOfLValue(E);
597 EmitLValueAlignmentAssumption(E,
V);
606 return EmitScalarPrePostIncDec(E, LV,
false,
false);
610 return EmitScalarPrePostIncDec(E, LV,
true,
false);
614 return EmitScalarPrePostIncDec(E, LV,
false,
true);
618 return EmitScalarPrePostIncDec(E, LV,
true,
true);
621 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
626 bool isInc,
bool isPre);
630 if (isa<MemberPointerType>(E->
getType()))
633 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
638 return EmitLoadOfLValue(E);
662 return EmitLoadOfLValue(E);
673 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
677 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
694 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
706 return llvm::ConstantInt::get(Builder.getInt32Ty(), E->
getValue());
710 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
724 return EmitNullValue(E->
getType());
733 return Builder.getInt1(E->
getValue());
737 Value *EmitMul(
const BinOpInfo &Ops) {
738 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
739 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
741 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
742 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
745 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
746 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
749 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
750 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
751 return EmitOverflowCheckedBinOp(Ops);
755 if (Ops.Ty->isConstantMatrixType()) {
756 llvm::MatrixBuilder MB(Builder);
759 auto *BO = cast<BinaryOperator>(Ops.E);
760 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
761 BO->getLHS()->getType().getCanonicalType());
762 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
763 BO->getRHS()->getType().getCanonicalType());
764 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
765 if (LHSMatTy && RHSMatTy)
766 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
767 LHSMatTy->getNumColumns(),
768 RHSMatTy->getNumColumns());
769 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
772 if (Ops.Ty->isUnsignedIntegerType() &&
773 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
774 !CanElideOverflowCheck(CGF.
getContext(), Ops))
775 return EmitOverflowCheckedBinOp(Ops);
777 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
779 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
780 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
782 if (Ops.isFixedPointOp())
783 return EmitFixedPointBinOp(Ops);
784 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
788 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
791 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
792 llvm::Value *Zero,
bool isDiv);
794 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
800 Value *EmitDiv(
const BinOpInfo &Ops);
801 Value *EmitRem(
const BinOpInfo &Ops);
802 Value *EmitAdd(
const BinOpInfo &Ops);
803 Value *EmitSub(
const BinOpInfo &Ops);
804 Value *EmitShl(
const BinOpInfo &Ops);
805 Value *EmitShr(
const BinOpInfo &Ops);
806 Value *EmitAnd(
const BinOpInfo &Ops) {
807 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
809 Value *EmitXor(
const BinOpInfo &Ops) {
810 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
812 Value *EmitOr (
const BinOpInfo &Ops) {
813 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
817 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
827 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
831 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
836 QualType ElementType = CT->getElementType();
843 unsigned NumElements = VT->getNumElements();
853#define HANDLEBINOP(OP) \
854 Value *VisitBin##OP(const BinaryOperator *E) { \
855 QualType promotionTy = getPromotionType(E->getType()); \
856 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
857 if (result && !promotionTy.isNull()) \
858 result = EmitUnPromotedValue(result, E->getType()); \
861 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
862 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
878 llvm::CmpInst::Predicate SICmpOpc,
879 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
880#define VISITCOMP(CODE, UI, SI, FP, SIG) \
881 Value *VisitBin##CODE(const BinaryOperator *E) { \
882 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
883 llvm::FCmpInst::FP, SIG); }
898 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
899 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
937 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
940 return EmitFloatToBoolConversion(Src);
946 "Unknown scalar type to convert");
948 if (isa<llvm::IntegerType>(Src->
getType()))
949 return EmitIntToBoolConversion(Src);
951 assert(isa<llvm::PointerType>(Src->
getType()));
952 return EmitPointerToBoolConversion(Src, SrcType);
955void ScalarExprEmitter::EmitFloatConversionCheck(
958 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
959 if (!isa<llvm::IntegerType>(DstTy))
962 CodeGenFunction::SanitizerScope SanScope(&CGF);
966 llvm::Value *Check =
nullptr;
967 const llvm::fltSemantics &SrcSema =
977 APFloat MinSrc(SrcSema, APFloat::uninitialized);
978 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
982 MinSrc = APFloat::getInf(SrcSema,
true);
986 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
989 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
990 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
994 MaxSrc = APFloat::getInf(SrcSema,
false);
998 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1003 const llvm::fltSemantics &
Sema =
1006 MinSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1007 MaxSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1011 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1013 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1014 Check = Builder.CreateAnd(GE, LE);
1019 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
1020 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
1025static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1026 std::pair<llvm::Value *, SanitizerMask>>
1029 llvm::Type *SrcTy = Src->
getType();
1030 llvm::Type *DstTy = Dst->
getType();
1035 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1036 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1037 "non-integer llvm type");
1044 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1046 if (!SrcSigned && !DstSigned) {
1047 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1048 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
1050 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1051 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
1054 llvm::Value *Check =
nullptr;
1056 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1058 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1060 return std::make_pair(Kind, std::make_pair(Check, Mask));
1068void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1080 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1081 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1083 if (SrcBits <= DstBits)
1086 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1093 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1094 (!SrcSigned && DstSigned))
1097 CodeGenFunction::SanitizerScope SanScope(&CGF);
1099 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1100 std::pair<llvm::Value *, SanitizerMask>>
1109 llvm::Constant *StaticArgs[] = {
1112 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1113 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1115 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1123 llvm::Type *VTy =
V->getType();
1126 return llvm::ConstantInt::getFalse(VTy->getContext());
1128 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1129 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V, Zero,
1130 llvm::Twine(Name) +
"." +
V->getName() +
1131 ".negativitycheck");
1136static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1137 std::pair<llvm::Value *, SanitizerMask>>
1140 llvm::Type *SrcTy = Src->
getType();
1141 llvm::Type *DstTy = Dst->
getType();
1143 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1144 "non-integer llvm type");
1150 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1151 unsigned DstBits = DstTy->getScalarSizeInBits();
1155 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1156 "either the widths should be different, or the signednesses.");
1159 llvm::Value *SrcIsNegative =
1162 llvm::Value *DstIsNegative =
1168 llvm::Value *Check =
nullptr;
1169 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1171 return std::make_pair(
1172 ScalarExprEmitter::ICCK_IntegerSignChange,
1173 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1176void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1179 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1182 llvm::Type *SrcTy = Src->
getType();
1183 llvm::Type *DstTy = Dst->
getType();
1193 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1194 unsigned DstBits = DstTy->getScalarSizeInBits();
1201 if (SrcSigned == DstSigned && SrcBits == DstBits)
1205 if (!SrcSigned && !DstSigned)
1210 if ((DstBits > SrcBits) && DstSigned)
1212 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1213 (SrcBits > DstBits) && SrcSigned) {
1221 CodeGenFunction::SanitizerScope SanScope(&CGF);
1223 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1224 std::pair<llvm::Value *, SanitizerMask>>
1228 ImplicitConversionCheckKind CheckKind;
1234 CheckKind = Check.first;
1235 Checks.emplace_back(Check.second);
1237 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1238 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1244 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1245 Checks.emplace_back(Check.second);
1249 llvm::Constant *StaticArgs[] = {
1252 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1253 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1255 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1261static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1262 std::pair<llvm::Value *, SanitizerMask>>
1268 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1269 if (!SrcSigned && !DstSigned)
1270 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1272 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1274 llvm::Value *Check =
nullptr;
1276 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1278 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1281 return std::make_pair(
1282 Kind, std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1287static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1288 std::pair<llvm::Value *, SanitizerMask>>
1292 llvm::Value *SrcIsNegative =
1295 llvm::Value *DstIsNegative =
1301 llvm::Value *Check =
nullptr;
1303 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1305 return std::make_pair(
1306 ScalarExprEmitter::ICCK_IntegerSignChange,
1307 std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1310void CodeGenFunction::EmitBitfieldConversionCheck(
Value *Src,
QualType SrcType,
1315 if (!
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion))
1328 assert(isa<llvm::IntegerType>(Src->
getType()) &&
1329 isa<llvm::IntegerType>(Dst->
getType()) &&
"non-integer llvm type");
1333 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1334 unsigned DstBits = Info.
Size;
1339 CodeGenFunction::SanitizerScope SanScope(
this);
1341 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1342 std::pair<llvm::Value *, SanitizerMask>>
1346 bool EmitTruncation = DstBits < SrcBits;
1350 bool EmitTruncationFromUnsignedToSigned =
1351 EmitTruncation && DstSigned && !SrcSigned;
1353 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1354 bool BothUnsigned = !SrcSigned && !DstSigned;
1355 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1362 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1367 else if (EmitSignChange) {
1368 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1369 "either the widths should be different, or the signednesses.");
1375 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1376 if (EmitTruncationFromUnsignedToSigned)
1377 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1379 llvm::Constant *StaticArgs[] = {
1382 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1383 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1385 EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1390 QualType DstType, llvm::Type *SrcTy,
1392 ScalarConversionOpts Opts) {
1394 llvm::Type *SrcElementTy;
1395 llvm::Type *DstElementTy;
1399 SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1400 DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1405 "cannot cast between matrix and non-matrix types");
1406 SrcElementTy = SrcTy;
1407 DstElementTy = DstTy;
1408 SrcElementType = SrcType;
1409 DstElementType = DstType;
1412 if (isa<llvm::IntegerType>(SrcElementTy)) {
1414 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1418 if (isa<llvm::IntegerType>(DstElementTy))
1419 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1421 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1422 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1425 if (isa<llvm::IntegerType>(DstElementTy)) {
1426 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1433 llvm::Intrinsic::ID IID =
1434 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1435 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1439 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1440 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1443 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1444 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1445 return Builder.CreateFPExt(Src, DstTy,
"conv");
1453 ScalarConversionOpts Opts) {
1468 return Builder.CreateIsNotNull(Src,
"tobool");
1471 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1474 "Unhandled scalar conversion from a fixed point type to another type.");
1478 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1481 "Unhandled scalar conversion to a fixed point type from another type.");
1484 QualType NoncanonicalSrcType = SrcType;
1485 QualType NoncanonicalDstType = DstType;
1489 if (SrcType == DstType)
return Src;
1493 llvm::Value *OrigSrc = Src;
1495 llvm::Type *SrcTy = Src->
getType();
1499 return EmitConversionToBool(Src, SrcType);
1501 llvm::Type *DstTy = ConvertType(DstType);
1506 if (DstTy->isFloatingPointTy()) {
1508 return Builder.CreateCall(
1516 Src = Builder.CreateCall(
1521 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1529 if (SrcTy == DstTy) {
1530 if (Opts.EmitImplicitIntegerSignChangeChecks)
1531 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1532 NoncanonicalDstType, Loc);
1540 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1542 if (isa<llvm::PointerType>(SrcTy))
1545 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1550 llvm::Value* IntResult =
1551 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1553 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1556 if (isa<llvm::PointerType>(SrcTy)) {
1558 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1559 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1568 "Splatted expr doesn't match with vector element type?");
1571 unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
1572 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1576 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1578 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1580 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1581 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1582 if (SrcSize == DstSize)
1583 return Builder.CreateBitCast(Src, DstTy,
"conv");
1592 llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1593 llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1596 assert(((SrcElementTy->isIntegerTy() &&
1597 DstElementTy->isIntegerTy()) ||
1598 (SrcElementTy->isFloatingPointTy() &&
1599 DstElementTy->isFloatingPointTy())) &&
1600 "unexpected conversion between a floating-point vector and an "
1604 if (SrcElementTy->isIntegerTy())
1605 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1608 if (SrcSize > DstSize)
1609 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1612 return Builder.CreateFPExt(Src, DstTy,
"conv");
1616 Value *Res =
nullptr;
1617 llvm::Type *ResTy = DstTy;
1624 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1626 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1632 if (SrcTy->isFloatingPointTy()) {
1636 return Builder.CreateCall(
1639 return Builder.CreateFPTrunc(Src, DstTy);
1644 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1646 if (DstTy != ResTy) {
1648 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1649 Res = Builder.CreateCall(
1653 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1657 if (Opts.EmitImplicitIntegerTruncationChecks)
1658 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1659 NoncanonicalDstType, Loc);
1661 if (Opts.EmitImplicitIntegerSignChangeChecks)
1662 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1663 NoncanonicalDstType, Loc);
1671 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1674 Result = FPBuilder.CreateFloatingToFixed(Src,
1677 Result = FPBuilder.CreateFixedToFloating(Src,
1679 ConvertType(DstTy));
1685 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1686 DstFPSema.getWidth(),
1687 DstFPSema.isSigned());
1689 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1692 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1699Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1708 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1709 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1710 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1717 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1728void ScalarExprEmitter::EmitBinOpCheck(
1729 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1741 if (UO && UO->
getOpcode() == UO_Minus) {
1742 Check = SanitizerHandler::NegateOverflow;
1744 DynamicData.push_back(Info.RHS);
1748 Check = SanitizerHandler::ShiftOutOfBounds;
1750 StaticData.push_back(
1752 StaticData.push_back(
1754 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1756 Check = SanitizerHandler::DivremOverflow;
1761 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1762 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1763 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1764 default: llvm_unreachable(
"unexpected opcode for bin op check");
1768 DynamicData.push_back(Info.LHS);
1769 DynamicData.push_back(Info.RHS);
1772 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1779Value *ScalarExprEmitter::VisitExpr(
Expr *E) {
1789 unsigned AddrSpace =
1791 llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1794 llvm::Type *ExprTy = ConvertType(E->
getType());
1795 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1806 auto *LTy = cast<llvm::FixedVectorType>(LHS->
getType());
1807 unsigned LHSElts = LTy->getNumElements();
1811 auto *MTy = cast<llvm::FixedVectorType>(Mask->
getType());
1815 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1816 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1824 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1825 MTy->getNumElements());
1826 Value* NewV = llvm::PoisonValue::get(RTy);
1827 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1828 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1829 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1831 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1832 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1844 if (Idx.isSigned() && Idx.isAllOnes())
1845 Indices.push_back(-1);
1847 Indices.push_back(Idx.getZExtValue());
1850 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1861 if (SrcType == DstType)
return Src;
1864 "ConvertVector source type must be a vector");
1866 "ConvertVector destination type must be a vector");
1868 llvm::Type *SrcTy = Src->
getType();
1869 llvm::Type *DstTy = ConvertType(DstType);
1878 assert(SrcTy->isVectorTy() &&
1879 "ConvertVector source IR type must be a vector");
1880 assert(DstTy->isVectorTy() &&
1881 "ConvertVector destination IR type must be a vector");
1883 llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
1884 *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
1886 if (DstEltType->isBooleanType()) {
1887 assert((SrcEltTy->isFloatingPointTy() ||
1888 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1890 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
1891 if (SrcEltTy->isFloatingPointTy()) {
1892 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1894 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1899 Value *Res =
nullptr;
1901 if (isa<llvm::IntegerType>(SrcEltTy)) {
1903 if (isa<llvm::IntegerType>(DstEltTy))
1904 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1905 else if (InputSigned)
1906 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1908 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1909 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1910 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1911 if (DstEltType->isSignedIntegerOrEnumerationType())
1912 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1914 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1916 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1917 "Unknown real conversion");
1918 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1919 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1921 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1936 return Builder.getInt(
Value);
1940 return EmitLoadOfLValue(E);
1944 TestAndClearIgnoreResultAssign();
1952 return EmitLoadOfLValue(E);
1960 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1963 return Builder.CreateExtractElement(
Base, Idx,
"vecext");
1967 TestAndClearIgnoreResultAssign();
1976 llvm::MatrixBuilder MB(Builder);
1977 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
1979 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
1984 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
1989 int MV = SVI->getMaskValue(Idx);
1996 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
1997 "Index operand too large for shufflevector mask!");
1998 return C->getZExtValue();
2002 bool Ignore = TestAndClearIgnoreResultAssign();
2004 assert (Ignore ==
false &&
"init list ignored");
2010 llvm::VectorType *VType =
2011 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2014 if (NumInitElements == 0) {
2016 return EmitNullValue(E->
getType());
2022 if (isa<llvm::ScalableVectorType>(VType)) {
2023 if (NumInitElements == 0) {
2025 return EmitNullValue(E->
getType());
2028 if (NumInitElements == 1) {
2033 return Visit(InitVector);
2036 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2039 unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
2046 unsigned CurIdx = 0;
2047 bool VIsPoisonShuffle =
false;
2048 llvm::Value *
V = llvm::PoisonValue::get(VType);
2049 for (
unsigned i = 0; i != NumInitElements; ++i) {
2054 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2060 if (isa<ExtVectorElementExpr>(IE)) {
2061 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(
Init);
2063 if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
2064 ->getNumElements() == ResElts) {
2065 llvm::ConstantInt *
C = cast<llvm::ConstantInt>(EI->getIndexOperand());
2066 Value *LHS =
nullptr, *RHS =
nullptr;
2071 Args.resize(ResElts, -1);
2073 LHS = EI->getVectorOperand();
2075 VIsPoisonShuffle =
true;
2076 }
else if (VIsPoisonShuffle) {
2078 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
2079 for (
unsigned j = 0; j != CurIdx; ++j)
2081 Args.push_back(ResElts +
C->getZExtValue());
2082 Args.resize(ResElts, -1);
2084 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2085 RHS = EI->getVectorOperand();
2086 VIsPoisonShuffle =
false;
2088 if (!Args.empty()) {
2089 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2095 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2097 VIsPoisonShuffle =
false;
2102 unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
2107 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2108 if (isa<ExtVectorElementExpr>(IE)) {
2109 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(
Init);
2110 Value *SVOp = SVI->getOperand(0);
2111 auto *OpTy = cast<llvm::FixedVectorType>(SVOp->
getType());
2113 if (OpTy->getNumElements() == ResElts) {
2114 for (
unsigned j = 0; j != CurIdx; ++j) {
2117 if (VIsPoisonShuffle) {
2118 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(
V), j, 0));
2123 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2125 Args.resize(ResElts, -1);
2127 if (VIsPoisonShuffle)
2128 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2137 for (
unsigned j = 0; j != InitElts; ++j)
2139 Args.resize(ResElts, -1);
2140 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2143 for (
unsigned j = 0; j != CurIdx; ++j)
2145 for (
unsigned j = 0; j != InitElts; ++j)
2146 Args.push_back(j + Offset);
2147 Args.resize(ResElts, -1);
2154 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2155 VIsPoisonShuffle = isa<llvm::PoisonValue>(
Init);
2161 llvm::Type *EltTy = VType->getElementType();
2164 for (; CurIdx < ResElts; ++CurIdx) {
2165 Value *Idx = Builder.getInt32(CurIdx);
2166 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2167 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2175 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2185 if (ICE->isGLValue())
2199 CodeGenFunction::CGFPOptionsRAII
FPOptions(CGF, CE);
2203 bool Ignored = TestAndClearIgnoreResultAssign();
2209 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2210 case CK_BuiltinFnToFnPtr:
2211 llvm_unreachable(
"builtin functions are handled elsewhere");
2213 case CK_LValueBitCast:
2214 case CK_ObjCObjectLValueCast: {
2215 Address Addr = EmitLValue(E).getAddress(CGF);
2218 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2221 case CK_LValueToRValueBitCast: {
2227 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2230 case CK_CPointerToObjCPointerCast:
2231 case CK_BlockPointerToObjCPointerCast:
2232 case CK_AnyPointerToBlockPointerCast:
2234 Value *Src = Visit(
const_cast<Expr*
>(E));
2235 llvm::Type *SrcTy = Src->
getType();
2236 llvm::Type *DstTy = ConvertType(DestTy);
2238 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2239 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2240 "Address-space cast must be used to convert address spaces");
2242 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2245 PT->getPointeeType(),
2261 Src = Builder.CreateLaunderInvariantGroup(Src);
2269 Src = Builder.CreateStripInvariantGroup(Src);
2274 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2275 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE) &&
2276 !isa<CastExpr>(E)) {
2278 if (!PointeeType.
isNull())
2287 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2288 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2291 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2292 ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
2293 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2294 ScalableDstTy = llvm::ScalableVectorType::get(
2295 FixedSrcTy->getElementType(),
2296 ScalableDstTy->getElementCount().getKnownMinValue() / 8);
2298 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2299 llvm::Value *UndefVec = llvm::UndefValue::get(ScalableDstTy);
2300 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2301 llvm::Value *
Result = Builder.CreateInsertVector(
2302 ScalableDstTy, UndefVec, Src, Zero,
"cast.scalable");
2303 if (
Result->getType() != DstTy)
2313 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2314 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2317 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2318 ScalableSrcTy->getElementCount().isKnownMultipleOf(8) &&
2319 FixedDstTy->getElementType()->isIntegerTy(8)) {
2320 ScalableSrcTy = llvm::ScalableVectorType::get(
2321 FixedDstTy->getElementType(),
2322 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2323 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2325 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType()) {
2326 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2327 return Builder.CreateExtractVector(DstTy, Src, Zero,
"cast.fixed");
2338 if ((isa<llvm::FixedVectorType>(SrcTy) &&
2339 isa<llvm::ScalableVectorType>(DstTy)) ||
2340 (isa<llvm::ScalableVectorType>(SrcTy) &&
2341 isa<llvm::FixedVectorType>(DstTy))) {
2348 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2350 return Builder.CreateBitCast(Src, DstTy);
2352 case CK_AddressSpaceConversion: {
2355 Result.Val.isNullPointer()) {
2359 if (
Result.HasSideEffects)
2362 ConvertType(DestTy)), DestTy);
2370 case CK_AtomicToNonAtomic:
2371 case CK_NonAtomicToAtomic:
2372 case CK_UserDefinedConversion:
2373 return Visit(
const_cast<Expr*
>(E));
2377 : Visit(const_cast<
Expr *>(E));
2380 case CK_BaseToDerived: {
2382 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2396 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2404 case CK_UncheckedDerivedToBase:
2405 case CK_DerivedToBase: {
2418 case CK_ArrayToPointerDecay:
2421 case CK_FunctionToPointerDecay:
2422 return EmitLValue(E).getPointer(CGF);
2424 case CK_NullToPointer:
2425 if (MustVisitNullValue(E))
2431 case CK_NullToMemberPointer: {
2432 if (MustVisitNullValue(E))
2439 case CK_ReinterpretMemberPointer:
2440 case CK_BaseToDerivedMemberPointer:
2441 case CK_DerivedToBaseMemberPointer: {
2442 Value *Src = Visit(E);
2453 case CK_ARCProduceObject:
2455 case CK_ARCConsumeObject:
2457 case CK_ARCReclaimReturnedObject:
2459 case CK_ARCExtendBlockObject:
2462 case CK_CopyAndAutoreleaseBlockObject:
2465 case CK_FloatingRealToComplex:
2466 case CK_FloatingComplexCast:
2467 case CK_IntegralRealToComplex:
2468 case CK_IntegralComplexCast:
2469 case CK_IntegralComplexToFloatingComplex:
2470 case CK_FloatingComplexToIntegralComplex:
2471 case CK_ConstructorConversion:
2473 case CK_HLSLArrayRValue:
2474 llvm_unreachable(
"scalar cast to non-scalar value");
2476 case CK_LValueToRValue:
2478 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2479 return Visit(
const_cast<Expr*
>(E));
2481 case CK_IntegralToPointer: {
2482 Value *Src = Visit(
const_cast<Expr*
>(E));
2486 auto DestLLVMTy = ConvertType(DestTy);
2489 llvm::Value* IntResult =
2490 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2492 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2498 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2502 case CK_PointerToIntegral: {
2503 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2504 auto *PtrExpr = Visit(E);
2512 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2515 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2521 case CK_MatrixCast: {
2522 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2525 case CK_VectorSplat: {
2526 llvm::Type *DstTy = ConvertType(DestTy);
2527 Value *Elt = Visit(
const_cast<Expr *
>(E));
2529 llvm::ElementCount NumElements =
2530 cast<llvm::VectorType>(DstTy)->getElementCount();
2531 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2534 case CK_FixedPointCast:
2535 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2538 case CK_FixedPointToBoolean:
2540 "Expected src type to be fixed point type");
2541 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2542 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2545 case CK_FixedPointToIntegral:
2547 "Expected src type to be fixed point type");
2548 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2549 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2552 case CK_IntegralToFixedPoint:
2554 "Expected src type to be an integer");
2556 "Expected dest type to be fixed point type");
2557 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2560 case CK_IntegralCast: {
2563 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
2567 ScalarConversionOpts Opts;
2568 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2569 if (!ICE->isPartOfExplicitCast())
2570 Opts = ScalarConversionOpts(CGF.
SanOpts);
2572 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2575 case CK_IntegralToFloating: {
2580 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
2581 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
2583 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2584 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2587 case CK_FloatingToIntegral: {
2592 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
2593 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
2595 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2596 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2599 case CK_FloatingCast: {
2606 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
2607 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
2609 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2610 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2613 case CK_FixedPointToFloating:
2614 case CK_FloatingToFixedPoint: {
2615 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2616 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2619 case CK_BooleanToSignedIntegral: {
2620 ScalarConversionOpts Opts;
2621 Opts.TreatBooleanAsSigned =
true;
2622 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2625 case CK_IntegralToBoolean:
2626 return EmitIntToBoolConversion(Visit(E));
2627 case CK_PointerToBoolean:
2628 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2629 case CK_FloatingToBoolean: {
2630 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2631 return EmitFloatToBoolConversion(Visit(E));
2633 case CK_MemberPointerToBoolean: {
2634 llvm::Value *MemPtr = Visit(E);
2639 case CK_FloatingComplexToReal:
2640 case CK_IntegralComplexToReal:
2643 case CK_FloatingComplexToBoolean:
2644 case CK_IntegralComplexToBoolean: {
2648 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
2652 case CK_ZeroToOCLOpaqueType: {
2655 "CK_ZeroToOCLEvent cast on non-event type");
2656 return llvm::Constant::getNullValue(ConvertType(DestTy));
2659 case CK_IntToOCLSampler:
2662 case CK_HLSLVectorTruncation: {
2663 assert(DestTy->
isVectorType() &&
"Expected dest type to be vector type");
2664 Value *Vec = Visit(
const_cast<Expr *
>(E));
2667 for (
unsigned I = 0; I != NumElts; ++I)
2670 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2675 llvm_unreachable(
"unknown scalar cast");
2679 CodeGenFunction::StmtExprEvaluation eval(CGF);
2689 CodeGenFunction::RunCleanupsScope
Scope(CGF);
2693 Scope.ForceCleanup({&
V});
2702 llvm::Value *InVal,
bool IsInc,
2706 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2708 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2709 BinOp.FPFeatures = FPFeatures;
2714llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2716 llvm::Value *Amount =
2717 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2718 StringRef Name = IsInc ?
"inc" :
"dec";
2719 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2721 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2722 return Builder.CreateAdd(InVal, Amount, Name);
2725 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2726 return Builder.CreateNSWAdd(InVal, Amount, Name);
2730 return Builder.CreateNSWAdd(InVal, Amount, Name);
2734 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2739class OMPLastprivateConditionalUpdateRAII {
2748 ~OMPLastprivateConditionalUpdateRAII() {
2758 bool isInc,
bool isPre) {
2759 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
2761 llvm::PHINode *atomicPHI =
nullptr;
2767 int amount = (isInc ? 1 : -1);
2768 bool isSubtraction = !isInc;
2771 type = atomicTy->getValueType();
2772 if (isInc &&
type->isBooleanType()) {
2776 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2777 return Builder.getTrue();
2781 return Builder.CreateAtomicRMW(
2782 llvm::AtomicRMWInst::Xchg, LV.
getAddress(CGF), True,
2783 llvm::AtomicOrdering::SequentiallyConsistent);
2788 if (!
type->isBooleanType() &&
type->isIntegerType() &&
2789 !(
type->isUnsignedIntegerType() &&
2790 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2793 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2794 llvm::AtomicRMWInst::Sub;
2795 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2796 llvm::Instruction::Sub;
2798 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
2800 Builder.CreateAtomicRMW(aop, LV.
getAddress(CGF), amt,
2801 llvm::AtomicOrdering::SequentiallyConsistent);
2802 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2804 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2807 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2810 Builder.CreateBr(opBB);
2811 Builder.SetInsertPoint(opBB);
2812 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2813 atomicPHI->addIncoming(value, startBB);
2816 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2827 if (isInc &&
type->isBooleanType()) {
2828 value = Builder.getTrue();
2831 }
else if (
type->isIntegerType()) {
2833 bool canPerformLossyDemotionCheck =
false;
2836 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
2837 canPerformLossyDemotionCheck =
true;
2838 canPerformLossyDemotionCheck &=
2841 canPerformLossyDemotionCheck &=
2843 type, promotedType);
2844 assert((!canPerformLossyDemotionCheck ||
2845 type->isSignedIntegerOrEnumerationType() ||
2847 ConvertType(
type)->getScalarSizeInBits() ==
2848 ConvertType(promotedType)->getScalarSizeInBits()) &&
2849 "The following check expects that if we do promotion to different "
2850 "underlying canonical type, at least one of the types (either "
2851 "base or promoted) will be signed, or the bitwidths will match.");
2854 SanitizerKind::ImplicitIntegerArithmeticValueChange |
2855 SanitizerKind::ImplicitBitfieldConversion) &&
2856 canPerformLossyDemotionCheck) {
2870 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
2871 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2872 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2876 ScalarConversionOpts Opts;
2878 Opts = ScalarConversionOpts(CGF.
SanOpts);
2879 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
2881 SrcType = promotedType;
2884 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
2890 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
2891 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
2893 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2897 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2898 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2909 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2912 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
2915 elemTy, value, numElts,
false, isSubtraction,
2919 }
else if (
type->isFunctionType()) {
2920 llvm::Value *amt = Builder.getInt32(amount);
2923 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
2927 false, isSubtraction,
2932 llvm::Value *amt = Builder.getInt32(amount);
2935 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
2938 elemTy, value, amt,
false, isSubtraction,
2943 }
else if (
type->isVectorType()) {
2944 if (
type->hasIntegerRepresentation()) {
2945 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2947 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2949 value = Builder.CreateFAdd(
2951 llvm::ConstantFP::get(value->getType(), amount),
2952 isInc ?
"inc" :
"dec");
2956 }
else if (
type->isRealFloatingType()) {
2959 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
2964 value = Builder.CreateCall(
2967 input,
"incdec.conv");
2969 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
2973 if (value->getType()->isFloatTy())
2974 amt = llvm::ConstantFP::get(VMContext,
2975 llvm::APFloat(
static_cast<float>(amount)));
2976 else if (value->getType()->isDoubleTy())
2977 amt = llvm::ConstantFP::get(VMContext,
2978 llvm::APFloat(
static_cast<double>(amount)));
2982 llvm::APFloat F(
static_cast<float>(amount));
2984 const llvm::fltSemantics *FS;
2987 if (value->getType()->isFP128Ty())
2989 else if (value->getType()->isHalfTy())
2991 else if (value->getType()->isBFloatTy())
2993 else if (value->getType()->isPPC_FP128Ty())
2997 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
2998 amt = llvm::ConstantFP::get(VMContext, F);
3000 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3004 value = Builder.CreateCall(
3007 value,
"incdec.conv");
3009 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3014 }
else if (
type->isFixedPointType()) {
3021 Info.Opcode = isInc ? BO_Add : BO_Sub;
3023 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3026 if (
type->isSignedFixedPointType()) {
3027 Info.Opcode = isInc ? BO_Sub : BO_Add;
3028 Info.RHS = Builder.CreateNeg(Info.RHS);
3033 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3035 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3036 value = EmitFixedPointBinOp(Info);
3043 if (!isInc) size = -size;
3044 llvm::Value *sizeValue =
3045 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3048 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3051 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3053 value = Builder.CreateBitCast(value, input->getType());
3057 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3062 llvm::Value *
success = Pair.second;
3063 atomicPHI->addIncoming(old, curBlock);
3064 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3065 Builder.SetInsertPoint(contBB);
3066 return isPre ? value : input;
3080 return isPre ? value : input;
3089 Value *result = VisitPlus(E, promotionTy);
3090 if (result && !promotionTy.
isNull())
3091 result = EmitUnPromotedValue(result, E->
getType());
3098 TestAndClearIgnoreResultAssign();
3099 if (!PromotionType.
isNull())
3109 Value *result = VisitMinus(E, promotionTy);
3110 if (result && !promotionTy.
isNull())
3111 result = EmitUnPromotedValue(result, E->
getType());
3117 TestAndClearIgnoreResultAssign();
3119 if (!PromotionType.
isNull())
3125 if (Op->
getType()->isFPOrFPVectorTy())
3126 return Builder.CreateFNeg(Op,
"fneg");
3131 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3133 BinOp.Opcode = BO_Sub;
3136 return EmitSub(BinOp);
3140 TestAndClearIgnoreResultAssign();
3142 return Builder.CreateNot(Op,
"not");
3153 if (Oper->
getType()->isFPOrFPVectorTy()) {
3154 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3156 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
3158 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
3159 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3168 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3171 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3179 return Builder.getInt(
Value);
3184 llvm::Type* ResultType = ConvertType(E->
getType());
3185 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3187 for (
unsigned i = 0; i != n; ++i) {
3189 llvm::Value *Offset =
nullptr;
3196 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3203 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3207 Offset = Builder.CreateMul(Idx, ElemSize);
3221 Field != FieldEnd; ++Field, ++i) {
3222 if (*Field == MemberDecl)
3225 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3230 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3233 CurrentType = MemberDecl->
getType();
3238 llvm_unreachable(
"dependent __builtin_offsetof");
3254 auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
3256 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3268ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3272 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
3285 llvm::Value *size = VlaSize.
NumElts;
3289 if (!eltSize.
isOne())
3294 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3300 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3301 }
else if (E->
getKind() == UETT_VectorElements) {
3303 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3316 Value *result = VisitReal(E, promotionTy);
3317 if (result && !promotionTy.
isNull())
3318 result = EmitUnPromotedValue(result, E->
getType());
3330 if (!PromotionType.
isNull()) {
3332 Op, IgnoreResultAssign,
true);
3335 return result.first;
3345 if (!PromotionType.
isNull())
3355 Value *result = VisitImag(E, promotionTy);
3356 if (result && !promotionTy.
isNull())
3357 result = EmitUnPromotedValue(result, E->
getType());
3369 if (!PromotionType.
isNull()) {
3371 Op,
true, IgnoreResultAssign);
3374 return result.second;
3388 else if (!PromotionType.
isNull())
3392 if (!PromotionType.
isNull())
3393 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3394 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3401Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3403 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3406Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3408 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3413 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3415#define HANDLE_BINOP(OP) \
3417 return Emit##OP(EmitBinOps(BO, PromotionType));
3426 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3429 return VisitImag(UO, PromotionType);
3431 return VisitReal(UO, PromotionType);
3433 return VisitMinus(UO, PromotionType);
3435 return VisitPlus(UO, PromotionType);
3440 auto result = Visit(
const_cast<Expr *
>(E));
3442 if (!PromotionType.
isNull())
3443 return EmitPromotedValue(result, PromotionType);
3445 return EmitUnPromotedValue(result, E->
getType());
3452 TestAndClearIgnoreResultAssign();
3456 if (!PromotionType.
isNull())
3457 Result.Ty = PromotionType;
3466LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3468 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3481 if (PromotionTypeCR.
isNull())
3485 if (!PromotionTypeRHS.
isNull())
3488 OpInfo.RHS = Visit(E->
getRHS());
3489 OpInfo.Ty = PromotionTypeCR;
3496 llvm::PHINode *atomicPHI =
nullptr;
3499 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3500 !(
type->isUnsignedIntegerType() &&
3501 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3504 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3505 llvm::Instruction::BinaryOps Op;
3506 switch (OpInfo.Opcode) {
3508 case BO_MulAssign:
case BO_DivAssign:
3514 AtomicOp = llvm::AtomicRMWInst::Add;
3515 Op = llvm::Instruction::Add;
3518 AtomicOp = llvm::AtomicRMWInst::Sub;
3519 Op = llvm::Instruction::Sub;
3522 AtomicOp = llvm::AtomicRMWInst::And;
3523 Op = llvm::Instruction::And;
3526 AtomicOp = llvm::AtomicRMWInst::Xor;
3527 Op = llvm::Instruction::Xor;
3530 AtomicOp = llvm::AtomicRMWInst::Or;
3531 Op = llvm::Instruction::Or;
3534 llvm_unreachable(
"Invalid compound assignment type");
3536 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3538 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3541 Value *OldVal = Builder.CreateAtomicRMW(
3543 llvm::AtomicOrdering::SequentiallyConsistent);
3547 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3553 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3555 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3557 Builder.CreateBr(opBB);
3558 Builder.SetInsertPoint(opBB);
3559 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3560 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3561 OpInfo.LHS = atomicPHI;
3564 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3566 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3568 if (!PromotionTypeLHS.
isNull())
3569 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3572 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3585 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
3587 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
3588 ScalarConversionOpts(CGF.
SanOpts));
3591 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3595 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3596 llvm::Value *
success = Pair.second;
3597 atomicPHI->addIncoming(old, curBlock);
3598 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3599 Builder.SetInsertPoint(contBB);
3624 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3625 bool Ignore = TestAndClearIgnoreResultAssign();
3626 Value *RHS =
nullptr;
3627 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
3642 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3645void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3646 const BinOpInfo &Ops, llvm::Value *Zero,
bool isDiv) {
3649 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3650 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
3651 SanitizerKind::IntegerDivideByZero));
3654 const auto *BO = cast<BinaryOperator>(Ops.E);
3655 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
3656 Ops.Ty->hasSignedIntegerRepresentation() &&
3658 Ops.mayHaveIntegerOverflow()) {
3659 llvm::IntegerType *Ty = cast<llvm::IntegerType>(
Zero->getType());
3661 llvm::Value *IntMin =
3662 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3663 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
3665 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
3666 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
3667 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
3669 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3672 if (Checks.size() > 0)
3673 EmitBinOpCheck(Checks, Ops);
3676Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
3678 CodeGenFunction::SanitizerScope SanScope(&CGF);
3679 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3680 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3681 Ops.Ty->isIntegerType() &&
3682 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3683 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3684 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
3685 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
3686 Ops.Ty->isRealFloatingType() &&
3687 Ops.mayHaveFloatDivisionByZero()) {
3688 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3689 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
3690 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3695 if (Ops.Ty->isConstantMatrixType()) {
3696 llvm::MatrixBuilder MB(Builder);
3699 auto *BO = cast<BinaryOperator>(Ops.E);
3703 "first operand must be a matrix");
3705 "second operand must be an arithmetic type");
3706 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3707 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3708 Ops.Ty->hasUnsignedIntegerRepresentation());
3711 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3713 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3714 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3718 else if (Ops.isFixedPointOp())
3719 return EmitFixedPointBinOp(Ops);
3720 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3721 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3723 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3726Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3728 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3729 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3730 Ops.Ty->isIntegerType() &&
3731 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3732 CodeGenFunction::SanitizerScope SanScope(&CGF);
3733 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3734 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3737 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3738 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3740 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3743Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3748 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3749 switch (Ops.Opcode) {
3753 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3754 llvm::Intrinsic::uadd_with_overflow;
3755 OverflowKind = SanitizerHandler::AddOverflow;
3760 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3761 llvm::Intrinsic::usub_with_overflow;
3762 OverflowKind = SanitizerHandler::SubOverflow;
3767 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3768 llvm::Intrinsic::umul_with_overflow;
3769 OverflowKind = SanitizerHandler::MulOverflow;
3772 llvm_unreachable(
"Unsupported operation for overflow detection");
3778 CodeGenFunction::SanitizerScope SanScope(&CGF);
3783 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3784 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3785 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3788 const std::string *handlerName =
3790 if (handlerName->empty()) {
3793 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3794 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3796 : SanitizerKind::UnsignedIntegerOverflow;
3797 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3799 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
3804 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3805 llvm::BasicBlock *continueBB =
3809 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3813 Builder.SetInsertPoint(overflowBB);
3816 llvm::Type *Int8Ty = CGF.
Int8Ty;
3817 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
3818 llvm::FunctionType *handlerTy =
3819 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3820 llvm::FunctionCallee handler =
3825 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
3826 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
3830 llvm::Value *handlerArgs[] = {
3833 Builder.getInt8(OpID),
3834 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3836 llvm::Value *handlerResult =
3840 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3841 Builder.CreateBr(continueBB);
3843 Builder.SetInsertPoint(continueBB);
3844 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3845 phi->addIncoming(result, initialBB);
3846 phi->addIncoming(handlerResult, overflowBB);
3853 const BinOpInfo &op,
3854 bool isSubtraction) {
3859 Value *pointer = op.LHS;
3860 Expr *pointerOperand =
expr->getLHS();
3861 Value *index = op.RHS;
3862 Expr *indexOperand =
expr->getRHS();
3865 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
3866 std::swap(pointer, index);
3867 std::swap(pointerOperand, indexOperand);
3872 unsigned width = cast<llvm::IntegerType>(index->
getType())->getBitWidth();
3874 auto PtrTy = cast<llvm::PointerType>(pointer->
getType());
3899 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
3902 index = CGF.
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
3908 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3910 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
3920 llvm::Value *objectSize
3923 index = CGF.
Builder.CreateMul(index, objectSize);
3942 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
3945 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
3947 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
3966 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
3977 bool negMul,
bool negAdd) {
3978 Value *MulOp0 = MulOp->getOperand(0);
3979 Value *MulOp1 = MulOp->getOperand(1);
3981 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
3983 Addend = Builder.CreateFNeg(Addend,
"neg");
3985 Value *FMulAdd =
nullptr;
3986 if (Builder.getIsFPConstrained()) {
3987 assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
3988 "Only constrained operation should be created when Builder is in FP "
3989 "constrained mode");
3990 FMulAdd = Builder.CreateConstrainedFPCall(
3991 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
3993 {MulOp0, MulOp1, Addend});
3995 FMulAdd = Builder.CreateCall(
3997 {MulOp0, MulOp1, Addend});
3999 MulOp->eraseFromParent();
4014 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4015 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4016 "Only fadd/fsub can be the root of an fmuladd.");
4019 if (!op.FPFeatures.allowFPContractWithinStatement())
4022 Value *LHS = op.LHS;
4023 Value *RHS = op.RHS;
4027 bool NegLHS =
false;
4028 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4029 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4030 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4031 LHS = LHSUnOp->getOperand(0);
4036 bool NegRHS =
false;
4037 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4038 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4039 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4040 RHS = RHSUnOp->getOperand(0);
4048 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4049 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4050 (LHSBinOp->use_empty() || NegLHS)) {
4053 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4054 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4057 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4058 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4059 (RHSBinOp->use_empty() || NegRHS)) {
4062 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4063 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4067 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4068 if (LHSBinOp->getIntrinsicID() ==
4069 llvm::Intrinsic::experimental_constrained_fmul &&
4070 (LHSBinOp->use_empty() || NegLHS)) {
4073 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4074 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4077 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4078 if (RHSBinOp->getIntrinsicID() ==
4079 llvm::Intrinsic::experimental_constrained_fmul &&
4080 (RHSBinOp->use_empty() || NegRHS)) {
4083 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4084 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4091Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4092 if (op.LHS->getType()->isPointerTy() ||
4093 op.RHS->getType()->isPointerTy())
4096 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4097 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4099 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4100 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4103 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4104 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4107 if (CanElideOverflowCheck(CGF.
getContext(), op))
4108 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4109 return EmitOverflowCheckedBinOp(op);
4114 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4115 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4121 if (op.Ty->isConstantMatrixType()) {
4122 llvm::MatrixBuilder MB(Builder);
4123 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4124 return MB.CreateAdd(op.LHS, op.RHS);
4127 if (op.Ty->isUnsignedIntegerType() &&
4128 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4129 !CanElideOverflowCheck(CGF.
getContext(), op))
4130 return EmitOverflowCheckedBinOp(op);
4132 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4133 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4134 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4137 if (op.isFixedPointOp())
4138 return EmitFixedPointBinOp(op);
4140 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4145Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4147 using llvm::ConstantInt;
4155 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4156 RHSTy = BinOp->getRHS()->getType();
4157 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4162 LHSTy = CAO->getComputationLHSType();
4163 ResultTy = CAO->getComputationResultType();
4165 LHSTy = BinOp->getLHS()->getType();
4166 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4167 LHSTy = UnOp->getSubExpr()->getType();
4168 RHSTy = UnOp->getSubExpr()->getType();
4171 Value *LHS = op.LHS;
4172 Value *RHS = op.RHS;
4177 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4181 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4182 switch (op.Opcode) {
4185 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4189 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4193 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4197 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4201 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4205 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4208 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4210 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4212 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4214 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4219 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4221 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4225 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4238 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4244 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4249Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4251 if (!op.LHS->getType()->isPointerTy()) {
4252 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4253 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4255 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4256 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4259 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4260 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4263 if (CanElideOverflowCheck(CGF.
getContext(), op))
4264 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4265 return EmitOverflowCheckedBinOp(op);
4270 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4271 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4277 if (op.Ty->isConstantMatrixType()) {
4278 llvm::MatrixBuilder MB(Builder);
4279 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4280 return MB.CreateSub(op.LHS, op.RHS);
4283 if (op.Ty->isUnsignedIntegerType() &&
4284 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4285 !CanElideOverflowCheck(CGF.
getContext(), op))
4286 return EmitOverflowCheckedBinOp(op);
4288 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4289 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4290 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4293 if (op.isFixedPointOp())
4294 return EmitFixedPointBinOp(op);
4296 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4301 if (!op.RHS->getType()->isPointerTy())
4308 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4310 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4311 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4315 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4317 llvm::Value *divisor =
nullptr;
4323 elementType = VlaSize.Type;
4324 divisor = VlaSize.NumElts;
4328 if (!eltSize.
isOne())
4344 if (elementSize.
isOne())
4353 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4356Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4358 llvm::IntegerType *Ty;
4359 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4360 Ty = cast<llvm::IntegerType>(VT->getElementType());
4362 Ty = cast<llvm::IntegerType>(LHS->
getType());
4367 llvm::Type *RHSTy = RHS->
getType();
4368 llvm::APInt RHSMax =
4369 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4370 :
llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4371 if (RHSMax.ult(Ty->getBitWidth()))
4372 return llvm::ConstantInt::get(RHSTy, RHSMax);
4373 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4377 const Twine &Name) {
4378 llvm::IntegerType *Ty;
4379 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4380 Ty = cast<llvm::IntegerType>(VT->getElementType());
4382 Ty = cast<llvm::IntegerType>(LHS->
getType());
4384 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4385 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4387 return Builder.CreateURem(
4388 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4391Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4393 if (Ops.isFixedPointOp())
4394 return EmitFixedPointBinOp(Ops);
4398 Value *RHS = Ops.RHS;
4399 if (Ops.LHS->getType() != RHS->
getType())
4400 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4402 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4403 Ops.Ty->hasSignedIntegerRepresentation() &&
4406 bool SanitizeUnsignedBase =
4407 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4408 Ops.Ty->hasUnsignedIntegerRepresentation();
4409 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4410 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4413 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4414 else if ((SanitizeBase || SanitizeExponent) &&
4415 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4416 CodeGenFunction::SanitizerScope SanScope(&CGF);
4418 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4419 llvm::Value *WidthMinusOne =
4420 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4421 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4423 if (SanitizeExponent) {
4425 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
4432 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4435 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4436 llvm::Value *PromotedWidthMinusOne =
4437 (RHS == Ops.RHS) ? WidthMinusOne
4438 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4440 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4441 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4444 if (SanitizeUnsignedBase || CGF.
getLangOpts().CPlusPlus) {
4450 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4451 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4453 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4454 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
4456 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4457 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4458 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4459 Checks.push_back(std::make_pair(
4460 BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4461 : SanitizerKind::UnsignedShiftBase));
4464 assert(!Checks.empty());
4465 EmitBinOpCheck(Checks, Ops);
4468 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4471Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4473 if (Ops.isFixedPointOp())
4474 return EmitFixedPointBinOp(Ops);
4478 Value *RHS = Ops.RHS;
4479 if (Ops.LHS->getType() != RHS->
getType())
4480 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4484 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4485 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4486 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4487 CodeGenFunction::SanitizerScope SanScope(&CGF);
4488 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4489 llvm::Value *Valid = Builder.CreateICmpULE(
4490 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4491 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
4494 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4495 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4496 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4504 default: llvm_unreachable(
"unexpected element type");
4505 case BuiltinType::Char_U:
4506 case BuiltinType::UChar:
4507 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4508 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4509 case BuiltinType::Char_S:
4510 case BuiltinType::SChar:
4511 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4512 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4513 case BuiltinType::UShort:
4514 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4515 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4516 case BuiltinType::Short:
4517 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4518 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4519 case BuiltinType::UInt:
4520 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4521 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4522 case BuiltinType::Int:
4523 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4524 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4525 case BuiltinType::ULong:
4526 case BuiltinType::ULongLong:
4527 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4528 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4529 case BuiltinType::Long:
4530 case BuiltinType::LongLong:
4531 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4532 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4533 case BuiltinType::Float:
4534 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4535 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4536 case BuiltinType::Double:
4537 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4538 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4539 case BuiltinType::UInt128:
4540 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4541 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4542 case BuiltinType::Int128:
4543 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4544 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4549 llvm::CmpInst::Predicate UICmpOpc,
4550 llvm::CmpInst::Predicate SICmpOpc,
4551 llvm::CmpInst::Predicate FCmpOpc,
4553 TestAndClearIgnoreResultAssign();
4563 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
4565 BinOpInfo BOInfo = EmitBinOps(E);
4566 Value *LHS = BOInfo.LHS;
4567 Value *RHS = BOInfo.RHS;
4573 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4575 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4578 Value *FirstVecArg = LHS,
4579 *SecondVecArg = RHS;
4585 default: llvm_unreachable(
"is not a comparison operation");
4597 std::swap(FirstVecArg, SecondVecArg);
4604 if (ElementKind == BuiltinType::Float) {
4606 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4607 std::swap(FirstVecArg, SecondVecArg);
4615 if (ElementKind == BuiltinType::Float) {
4617 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4622 std::swap(FirstVecArg, SecondVecArg);
4627 Value *CR6Param = Builder.getInt32(CR6);
4629 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
4636 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(
Result->getType());
4637 if (ResultTy->getBitWidth() > 1 &&
4639 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
4644 if (BOInfo.isFixedPointOp()) {
4645 Result = EmitFixedPointBinOp(BOInfo);
4646 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
4647 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4649 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
4651 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
4653 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
4658 !isa<llvm::ConstantPointerNull>(LHS) &&
4659 !isa<llvm::ConstantPointerNull>(RHS)) {
4668 LHS = Builder.CreateStripInvariantGroup(LHS);
4670 RHS = Builder.CreateStripInvariantGroup(RHS);
4673 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
4679 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
4687 CETy = CTy->getElementType();
4689 LHS.first = Visit(E->
getLHS());
4690 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
4696 CTy->getElementType()) &&
4697 "The element types must always match.");
4700 RHS.first = Visit(E->
getRHS());
4701 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
4703 "The element types must always match.");
4706 Value *ResultR, *ResultI;
4710 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
4711 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
4715 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
4716 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
4720 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
4723 "Complex comparison other than == or != ?");
4724 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
4736 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
4738 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
4739 *SrcType = ICE->getSubExpr()->getType();
4751 bool Ignore = TestAndClearIgnoreResultAssign();
4770 RHS = Visit(E->
getRHS());
4786 RHS = Visit(E->
getRHS());
4821 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4832 if (LHS->
getType()->isFPOrFPVectorTy()) {
4833 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4835 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4836 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4838 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4839 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4841 Value *
And = Builder.CreateAnd(LHS, RHS);
4842 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
4846 llvm::Type *ResTy = ConvertType(E->
getType());
4867 if (InstrumentRegions &&
4872 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4885 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
4890 return llvm::Constant::getNullValue(ResTy);
4902 CodeGenFunction::ConditionalEvaluation eval(CGF);
4911 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
4913 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4915 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
4924 RHSBlock = Builder.GetInsertBlock();
4929 if (InstrumentRegions &&
4933 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
4937 PN->addIncoming(RHSCond, RHSBlockCnt);
4947 PN->addIncoming(RHSCond, RHSBlock);
4957 PN->setDebugLoc(Builder.getCurrentDebugLocation());
4961 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
4972 if (LHS->
getType()->isFPOrFPVectorTy()) {
4973 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4975 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4976 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4978 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4979 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4981 Value *
Or = Builder.CreateOr(LHS, RHS);
4982 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
4986 llvm::Type *ResTy = ConvertType(E->
getType());
5007 if (InstrumentRegions &&
5012 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5025 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5030 return llvm::ConstantInt::get(ResTy, 1);
5042 CodeGenFunction::ConditionalEvaluation eval(CGF);
5052 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5054 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5056 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5068 RHSBlock = Builder.GetInsertBlock();
5073 if (InstrumentRegions &&
5077 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5081 PN->addIncoming(RHSCond, RHSBlockCnt);
5087 PN->addIncoming(RHSCond, RHSBlock);
5095 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5101 return Visit(E->
getRHS());
5126Value *ScalarExprEmitter::
5128 TestAndClearIgnoreResultAssign();
5131 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5141 Expr *live = lhsExpr, *dead = rhsExpr;
5142 if (!CondExprBool) std::swap(live, dead);
5172 llvm::Value *LHS = Visit(lhsExpr);
5173 llvm::Value *RHS = Visit(rhsExpr);
5175 llvm::Type *condType = ConvertType(condExpr->
getType());
5176 auto *vecTy = cast<llvm::FixedVectorType>(condType);
5178 unsigned numElem = vecTy->getNumElements();
5179 llvm::Type *elemType = vecTy->getElementType();
5181 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5182 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5183 llvm::Value *tmp = Builder.CreateSExt(
5184 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5185 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5188 llvm::Value *RHSTmp = RHS;
5189 llvm::Value *LHSTmp = LHS;
5190 bool wasCast =
false;
5191 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
5192 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5193 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5194 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5198 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5199 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5200 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5202 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5212 llvm::Value *LHS = Visit(lhsExpr);
5213 llvm::Value *RHS = Visit(rhsExpr);
5215 llvm::Type *CondType = ConvertType(condExpr->
getType());
5216 auto *VecTy = cast<llvm::VectorType>(CondType);
5217 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5219 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5220 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5229 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5238 llvm::Value *LHS = Visit(lhsExpr);
5239 llvm::Value *RHS = Visit(rhsExpr);
5242 assert(!RHS &&
"LHS and RHS types must match");
5245 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5256 CodeGenFunction::ConditionalEvaluation eval(CGF);
5274 Value *LHS = Visit(lhsExpr);
5277 LHSBlock = Builder.GetInsertBlock();
5278 Builder.CreateBr(ContBlock);
5292 Value *RHS = Visit(rhsExpr);
5295 RHSBlock = Builder.GetInsertBlock();
5305 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5306 PN->addIncoming(LHS, LHSBlock);
5307 PN->addIncoming(RHS, RHSBlock);
5330 llvm::Type *ArgTy = ConvertType(VE->
getType());
5335 return llvm::UndefValue::get(ArgTy);
5339 llvm::Value *Val = Builder.CreateLoad(ArgPtr);
5342 if (ArgTy != Val->getType()) {
5343 if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
5344 Val = Builder.CreateIntToPtr(Val, ArgTy);
5346 Val = Builder.CreateTrunc(Val, ArgTy);
5352Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5358 Value *Src,
unsigned NumElementsDst) {
5359 static constexpr int Mask[] = {0, 1, 2, -1};
5360 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5380 const llvm::DataLayout &DL,
5381 Value *Src, llvm::Type *DstTy,
5382 StringRef Name =
"") {
5386 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5387 return Builder.CreateBitCast(Src, DstTy, Name);
5390 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5391 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5394 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5396 if (!DstTy->isIntegerTy())
5397 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5399 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5403 if (!SrcTy->isIntegerTy())
5404 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5406 return Builder.CreateIntToPtr(Src, DstTy, Name);
5411 llvm::Type *DstTy = ConvertType(E->
getType());
5413 llvm::Type *SrcTy = Src->
getType();
5414 unsigned NumElementsSrc =
5415 isa<llvm::VectorType>(SrcTy)
5416 ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5418 unsigned NumElementsDst =
5419 isa<llvm::VectorType>(DstTy)
5420 ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5429 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5434 Src->setName(
"astype");
5441 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5442 auto *Vec4Ty = llvm::FixedVectorType::get(
5443 cast<llvm::VectorType>(DstTy)->getElementType(), 4);
5448 Src->setName(
"astype");
5453 Src, DstTy,
"astype");
5468 "Invalid scalar expression to emit");
5470 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5471 .Visit(
const_cast<Expr *
>(E));
5480 "Invalid scalar expression to emit");
5481 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
5491 "Invalid complex -> scalar conversion");
5492 return ScalarExprEmitter(*
this)
5493 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
5500 if (!PromotionType.
isNull())
5501 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5503 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
5509 bool isInc,
bool isPre) {
5510 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
5520 llvm::Type *BaseTy =
5535 ScalarExprEmitter
Scalar(*
this);
5538#define COMPOUND_OP(Op) \
5539 case BO_##Op##Assign: \
5540 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5577 llvm_unreachable(
"Not valid compound assignment operators");
5580 llvm_unreachable(
"Unhandled compound assignment operator");
5595 llvm::LLVMContext &VMContext,
5601 llvm::Value *TotalOffset =
nullptr;
5604 if (isa<llvm::Constant>(GEPVal)) {
5607 Value *BasePtr_int =
5608 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
5610 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
5611 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5612 return {TotalOffset, Builder.getFalse()};
5615 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5616 assert(GEP->getPointerOperand() == BasePtr &&
5617 "BasePtr must be the base of the GEP.");
5618 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
5620 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
5623 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5624 auto *SAddIntrinsic =
5625 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
5626 auto *SMulIntrinsic =
5627 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
5630 llvm::Value *OffsetOverflows = Builder.getFalse();
5634 llvm::Value *RHS) -> llvm::Value * {
5635 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
5638 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
5639 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
5641 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
5644 OffsetOverflows = Builder.getTrue();
5645 return llvm::ConstantInt::get(VMContext, N);
5650 auto *ResultAndOverflow = Builder.CreateCall(
5651 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
5652 OffsetOverflows = Builder.CreateOr(
5653 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
5654 return Builder.CreateExtractValue(ResultAndOverflow, 0);
5658 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
5659 GTI != GTE; ++GTI) {
5660 llvm::Value *LocalOffset;
5661 auto *Index = GTI.getOperand();
5663 if (
auto *STy = GTI.getStructTypeOrNull()) {
5666 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
5667 LocalOffset = llvm::ConstantInt::get(
5668 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
5673 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
5674 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
5675 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
5680 if (!TotalOffset || TotalOffset == Zero)
5681 TotalOffset = LocalOffset;
5683 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
5686 return {TotalOffset, OffsetOverflows};
5692 bool SignedIndices,
bool IsSubtraction,
5694 llvm::Type *PtrTy = Ptr->
getType();
5698 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5702 bool PerformNullCheck = !NullPointerIsDefined(
5703 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5706 bool PerformOverflowCheck =
5707 !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5709 if (!(PerformNullCheck || PerformOverflowCheck))
5714 SanitizerScope SanScope(
this);
5715 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
5720 assert((!isa<llvm::Constant>(EvaluatedGEP.
TotalOffset) ||
5722 "If the offset got constant-folded, we don't expect that there was an "
5725 auto *
Zero = llvm::ConstantInt::getNullValue(
IntPtrTy);
5739 if (PerformNullCheck) {
5751 auto *BaseIsNotNullptr =
Builder.CreateIsNotNull(Ptr);
5752 auto *ResultIsNotNullptr =
Builder.CreateIsNotNull(ComputedGEP);
5755 ?
Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5756 :
Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5757 Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5760 if (PerformOverflowCheck) {
5765 llvm::Value *ValidGEP;
5767 if (SignedIndices) {
5773 auto *PosOrZeroValid =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5774 auto *PosOrZeroOffset =
5776 llvm::Value *NegValid =
Builder.CreateICmpULT(ComputedGEP, IntPtr);
5778 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5784 ValidGEP =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5790 ValidGEP =
Builder.CreateICmpULE(ComputedGEP, IntPtr);
5792 ValidGEP =
Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5793 Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5796 assert(!Checks.empty() &&
"Should have produced some checks.");
5800 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5801 EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
5809 const Twine &Name) {
5810 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5816 elementType, Align);
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
CodeGenFunction::ComplexPairTy ComplexPairTy
#define VISITCOMP(CODE, UI, SI, FP, SIG)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static Value * emitPointerArithmetic(CodeGenFunction &CGF, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, CodeGenFunction &CGF)
isCheapEnoughToEvaluateUnconditionally - Return true if the specified expression is cheap enough and ...
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static Decl::Kind getKind(const Decl *D)
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
const LangOptions & getLangOpts() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
AddrLabelExpr - The GNU address of label extension, representing &&label.
LabelDecl * getLabel() const
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
uint64_t getValue() const
QualType getElementType() const
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
This class is used for builtin types like 'int'.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
A boolean literal, per ([C++ lex.bool] Boolean literals).
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a delete expression for memory deallocation and destructor calls, e.g.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Represents a C++ struct/union/class.
A rewritten comparison expression that was originally written using operator syntax.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
unsigned getValue() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Represents a 'co_await' expression.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
SanitizerSet SanOpts
Sanitizers enabled for this function.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
static bool hasScalarEvaluationKind(QualType T)
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, llvm::Value *Dst, QualType DstType, const CGBitFieldInfo &Info, SourceLocation Loc)
Emit a check that an [implicit] conversion of a bitfield.
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
const TargetInfo & getTarget() const
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
CGDebugInfo * getDebugInfo()
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
llvm::Type * ConvertType(QualType T)
Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr)
Generate code to get an argument from the passed in pointer and update it accordingly.
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, llvm::Value **Previous, QualType *SrcType)
Retrieve the implicit cast expression of the rhs in a binary operator expression by passing pointers ...
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot())
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
RValue EmitAtomicExpr(AtomicExpr *E)
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
void setTBAAInfo(TBAAAccessInfo Info)
Address getAddress(CodeGenFunction &CGF) const
const CGBitFieldInfo & getBitFieldInfo() const
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
An abstract representation of an aligned address.
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Complex values, per C99 6.2.5p11.
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
CompoundLiteralExpr - [C99 6.5.2.5].
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumRows() const
Returns the number of rows in the matrix.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents a 'co_yield' expression.
const Expr * getDefaultExpr() const
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
A reference to a declared variable, function, enum, etc.
ExplicitCastExpr - An explicit cast written in the source code.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
unsigned getNumInits() const
bool hadArrayRangeDesignator() const
const Expr * getInit(unsigned Init) const
bool isSignedOverflowDefined() const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Represents a matrix type, as defined in the Matrix Types clang extensions.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
A runtime availability query.
VersionTuple getVersion() const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
SourceLocation getExprLoc() const LLVM_READONLY
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
ObjCProtocolExpr used for protocol expression in Objective-C.
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
ParenExpr - This represents a parethesized expression, e.g.
const Expr * getSubExpr() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Represents a struct/union/class.
field_iterator field_end() const
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
Sema - This implements semantic analysis and AST building for C.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Represents an expression that computes the length of a parameter pack.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
CompoundStmt * getSubStmt()
RetTy Visit(PTR(Stmt) S, ParamTys... P)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represents a call to the builtin function __builtin_va_arg.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
VectorKind getVectorKind() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool LE(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
const FunctionProtoType * T
@ Generic
not a target-specific vector type
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.