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;
2805 if (
type->isFloatingType()) {
2806 llvm::AtomicRMWInst::BinOp aop =
2807 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
2808 llvm::Instruction::BinaryOps op =
2809 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
2810 llvm::Value *amt = llvm::ConstantFP::get(
2811 VMContext, llvm::APFloat(
static_cast<float>(1.0)));
2813 Builder.CreateAtomicRMW(aop, LV.
getAddress(CGF), amt,
2814 llvm::AtomicOrdering::SequentiallyConsistent);
2815 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2817 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2820 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2823 Builder.CreateBr(opBB);
2824 Builder.SetInsertPoint(opBB);
2825 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2826 atomicPHI->addIncoming(value, startBB);
2829 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2840 if (isInc &&
type->isBooleanType()) {
2841 value = Builder.getTrue();
2844 }
else if (
type->isIntegerType()) {
2846 bool canPerformLossyDemotionCheck =
false;
2849 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
2850 canPerformLossyDemotionCheck =
true;
2851 canPerformLossyDemotionCheck &=
2854 canPerformLossyDemotionCheck &=
2856 type, promotedType);
2857 assert((!canPerformLossyDemotionCheck ||
2858 type->isSignedIntegerOrEnumerationType() ||
2860 ConvertType(
type)->getScalarSizeInBits() ==
2861 ConvertType(promotedType)->getScalarSizeInBits()) &&
2862 "The following check expects that if we do promotion to different "
2863 "underlying canonical type, at least one of the types (either "
2864 "base or promoted) will be signed, or the bitwidths will match.");
2867 SanitizerKind::ImplicitIntegerArithmeticValueChange |
2868 SanitizerKind::ImplicitBitfieldConversion) &&
2869 canPerformLossyDemotionCheck) {
2883 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
2884 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2885 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2889 ScalarConversionOpts Opts;
2891 Opts = ScalarConversionOpts(CGF.
SanOpts);
2892 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
2894 SrcType = promotedType;
2897 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
2903 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
2904 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
2906 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2910 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2911 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2922 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2925 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
2928 elemTy, value, numElts,
false, isSubtraction,
2932 }
else if (
type->isFunctionType()) {
2933 llvm::Value *amt = Builder.getInt32(amount);
2936 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
2940 false, isSubtraction,
2945 llvm::Value *amt = Builder.getInt32(amount);
2948 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
2951 elemTy, value, amt,
false, isSubtraction,
2956 }
else if (
type->isVectorType()) {
2957 if (
type->hasIntegerRepresentation()) {
2958 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2960 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2962 value = Builder.CreateFAdd(
2964 llvm::ConstantFP::get(value->getType(), amount),
2965 isInc ?
"inc" :
"dec");
2969 }
else if (
type->isRealFloatingType()) {
2972 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
2977 value = Builder.CreateCall(
2980 input,
"incdec.conv");
2982 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
2986 if (value->getType()->isFloatTy())
2987 amt = llvm::ConstantFP::get(VMContext,
2988 llvm::APFloat(
static_cast<float>(amount)));
2989 else if (value->getType()->isDoubleTy())
2990 amt = llvm::ConstantFP::get(VMContext,
2991 llvm::APFloat(
static_cast<double>(amount)));
2995 llvm::APFloat F(
static_cast<float>(amount));
2997 const llvm::fltSemantics *FS;
3000 if (value->getType()->isFP128Ty())
3002 else if (value->getType()->isHalfTy())
3004 else if (value->getType()->isBFloatTy())
3006 else if (value->getType()->isPPC_FP128Ty())
3010 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3011 amt = llvm::ConstantFP::get(VMContext, F);
3013 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3017 value = Builder.CreateCall(
3020 value,
"incdec.conv");
3022 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3027 }
else if (
type->isFixedPointType()) {
3034 Info.Opcode = isInc ? BO_Add : BO_Sub;
3036 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3039 if (
type->isSignedFixedPointType()) {
3040 Info.Opcode = isInc ? BO_Sub : BO_Add;
3041 Info.RHS = Builder.CreateNeg(Info.RHS);
3046 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3048 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3049 value = EmitFixedPointBinOp(Info);
3056 if (!isInc) size = -size;
3057 llvm::Value *sizeValue =
3058 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3061 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3064 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3066 value = Builder.CreateBitCast(value, input->getType());
3070 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3075 llvm::Value *
success = Pair.second;
3076 atomicPHI->addIncoming(old, curBlock);
3077 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3078 Builder.SetInsertPoint(contBB);
3079 return isPre ? value : input;
3093 return isPre ? value : input;
3102 Value *result = VisitPlus(E, promotionTy);
3103 if (result && !promotionTy.
isNull())
3104 result = EmitUnPromotedValue(result, E->
getType());
3111 TestAndClearIgnoreResultAssign();
3112 if (!PromotionType.
isNull())
3122 Value *result = VisitMinus(E, promotionTy);
3123 if (result && !promotionTy.
isNull())
3124 result = EmitUnPromotedValue(result, E->
getType());
3130 TestAndClearIgnoreResultAssign();
3132 if (!PromotionType.
isNull())
3138 if (Op->
getType()->isFPOrFPVectorTy())
3139 return Builder.CreateFNeg(Op,
"fneg");
3144 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3146 BinOp.Opcode = BO_Sub;
3149 return EmitSub(BinOp);
3153 TestAndClearIgnoreResultAssign();
3155 return Builder.CreateNot(Op,
"not");
3166 if (Oper->
getType()->isFPOrFPVectorTy()) {
3167 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3169 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
3171 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
3172 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3181 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3184 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3192 return Builder.getInt(
Value);
3197 llvm::Type* ResultType = ConvertType(E->
getType());
3198 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3200 for (
unsigned i = 0; i != n; ++i) {
3202 llvm::Value *Offset =
nullptr;
3209 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3216 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3220 Offset = Builder.CreateMul(Idx, ElemSize);
3234 Field != FieldEnd; ++Field, ++i) {
3235 if (*Field == MemberDecl)
3238 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3243 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3246 CurrentType = MemberDecl->
getType();
3251 llvm_unreachable(
"dependent __builtin_offsetof");
3267 auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
3269 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3281ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3285 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
3298 llvm::Value *size = VlaSize.
NumElts;
3302 if (!eltSize.
isOne())
3307 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3313 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3314 }
else if (E->
getKind() == UETT_VectorElements) {
3316 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3329 Value *result = VisitReal(E, promotionTy);
3330 if (result && !promotionTy.
isNull())
3331 result = EmitUnPromotedValue(result, E->
getType());
3343 if (!PromotionType.
isNull()) {
3345 Op, IgnoreResultAssign,
true);
3348 return result.first;
3358 if (!PromotionType.
isNull())
3368 Value *result = VisitImag(E, promotionTy);
3369 if (result && !promotionTy.
isNull())
3370 result = EmitUnPromotedValue(result, E->
getType());
3382 if (!PromotionType.
isNull()) {
3384 Op,
true, IgnoreResultAssign);
3387 return result.second;
3401 else if (!PromotionType.
isNull())
3405 if (!PromotionType.
isNull())
3406 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3407 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3414Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3416 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3419Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3421 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3426 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3428#define HANDLE_BINOP(OP) \
3430 return Emit##OP(EmitBinOps(BO, PromotionType));
3439 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3442 return VisitImag(UO, PromotionType);
3444 return VisitReal(UO, PromotionType);
3446 return VisitMinus(UO, PromotionType);
3448 return VisitPlus(UO, PromotionType);
3453 auto result = Visit(
const_cast<Expr *
>(E));
3455 if (!PromotionType.
isNull())
3456 return EmitPromotedValue(result, PromotionType);
3458 return EmitUnPromotedValue(result, E->
getType());
3465 TestAndClearIgnoreResultAssign();
3469 if (!PromotionType.
isNull())
3470 Result.Ty = PromotionType;
3479LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3481 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3494 if (PromotionTypeCR.
isNull())
3498 if (!PromotionTypeRHS.
isNull())
3501 OpInfo.RHS = Visit(E->
getRHS());
3502 OpInfo.Ty = PromotionTypeCR;
3509 llvm::PHINode *atomicPHI =
nullptr;
3512 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3513 !(
type->isUnsignedIntegerType() &&
3514 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3517 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3518 llvm::Instruction::BinaryOps Op;
3519 switch (OpInfo.Opcode) {
3521 case BO_MulAssign:
case BO_DivAssign:
3527 AtomicOp = llvm::AtomicRMWInst::Add;
3528 Op = llvm::Instruction::Add;
3531 AtomicOp = llvm::AtomicRMWInst::Sub;
3532 Op = llvm::Instruction::Sub;
3535 AtomicOp = llvm::AtomicRMWInst::And;
3536 Op = llvm::Instruction::And;
3539 AtomicOp = llvm::AtomicRMWInst::Xor;
3540 Op = llvm::Instruction::Xor;
3543 AtomicOp = llvm::AtomicRMWInst::Or;
3544 Op = llvm::Instruction::Or;
3547 llvm_unreachable(
"Invalid compound assignment type");
3549 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3551 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3554 Value *OldVal = Builder.CreateAtomicRMW(
3556 llvm::AtomicOrdering::SequentiallyConsistent);
3560 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3566 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3568 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3570 Builder.CreateBr(opBB);
3571 Builder.SetInsertPoint(opBB);
3572 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3573 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3574 OpInfo.LHS = atomicPHI;
3577 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3579 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3581 if (!PromotionTypeLHS.
isNull())
3582 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3585 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3601 ScalarConversionOpts(CGF.
SanOpts));
3604 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3608 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3609 llvm::Value *
success = Pair.second;
3610 atomicPHI->addIncoming(old, curBlock);
3611 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3612 Builder.SetInsertPoint(contBB);
3637 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3638 bool Ignore = TestAndClearIgnoreResultAssign();
3639 Value *RHS =
nullptr;
3640 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
3655 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3658void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3659 const BinOpInfo &Ops, llvm::Value *Zero,
bool isDiv) {
3662 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3663 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
3664 SanitizerKind::IntegerDivideByZero));
3667 const auto *BO = cast<BinaryOperator>(Ops.E);
3668 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
3669 Ops.Ty->hasSignedIntegerRepresentation() &&
3671 Ops.mayHaveIntegerOverflow()) {
3672 llvm::IntegerType *Ty = cast<llvm::IntegerType>(
Zero->getType());
3674 llvm::Value *IntMin =
3675 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3676 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
3678 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
3679 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
3680 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
3682 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3685 if (Checks.size() > 0)
3686 EmitBinOpCheck(Checks, Ops);
3689Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
3691 CodeGenFunction::SanitizerScope SanScope(&CGF);
3692 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3693 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3694 Ops.Ty->isIntegerType() &&
3695 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3696 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3697 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
3698 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
3699 Ops.Ty->isRealFloatingType() &&
3700 Ops.mayHaveFloatDivisionByZero()) {
3701 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3702 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
3703 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3708 if (Ops.Ty->isConstantMatrixType()) {
3709 llvm::MatrixBuilder MB(Builder);
3712 auto *BO = cast<BinaryOperator>(Ops.E);
3716 "first operand must be a matrix");
3718 "second operand must be an arithmetic type");
3719 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3720 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3721 Ops.Ty->hasUnsignedIntegerRepresentation());
3724 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3726 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3727 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3731 else if (Ops.isFixedPointOp())
3732 return EmitFixedPointBinOp(Ops);
3733 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3734 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3736 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3739Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3741 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3742 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3743 Ops.Ty->isIntegerType() &&
3744 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3745 CodeGenFunction::SanitizerScope SanScope(&CGF);
3746 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3747 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3750 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3751 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3753 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3756Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3761 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3762 switch (Ops.Opcode) {
3766 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3767 llvm::Intrinsic::uadd_with_overflow;
3768 OverflowKind = SanitizerHandler::AddOverflow;
3773 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3774 llvm::Intrinsic::usub_with_overflow;
3775 OverflowKind = SanitizerHandler::SubOverflow;
3780 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3781 llvm::Intrinsic::umul_with_overflow;
3782 OverflowKind = SanitizerHandler::MulOverflow;
3785 llvm_unreachable(
"Unsupported operation for overflow detection");
3791 CodeGenFunction::SanitizerScope SanScope(&CGF);
3796 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3797 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3798 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3801 const std::string *handlerName =
3803 if (handlerName->empty()) {
3806 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3807 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3809 : SanitizerKind::UnsignedIntegerOverflow;
3810 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3812 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
3817 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3818 llvm::BasicBlock *continueBB =
3822 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3826 Builder.SetInsertPoint(overflowBB);
3829 llvm::Type *Int8Ty = CGF.
Int8Ty;
3830 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
3831 llvm::FunctionType *handlerTy =
3832 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3833 llvm::FunctionCallee handler =
3838 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
3839 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
3843 llvm::Value *handlerArgs[] = {
3846 Builder.getInt8(OpID),
3847 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3849 llvm::Value *handlerResult =
3853 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3854 Builder.CreateBr(continueBB);
3856 Builder.SetInsertPoint(continueBB);
3857 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3858 phi->addIncoming(result, initialBB);
3859 phi->addIncoming(handlerResult, overflowBB);
3866 const BinOpInfo &op,
3867 bool isSubtraction) {
3872 Value *pointer = op.LHS;
3873 Expr *pointerOperand =
expr->getLHS();
3874 Value *index = op.RHS;
3875 Expr *indexOperand =
expr->getRHS();
3878 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
3879 std::swap(pointer, index);
3880 std::swap(pointerOperand, indexOperand);
3885 unsigned width = cast<llvm::IntegerType>(index->
getType())->getBitWidth();
3887 auto PtrTy = cast<llvm::PointerType>(pointer->
getType());
3912 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
3915 index = CGF.
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
3921 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3923 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
3933 llvm::Value *objectSize
3936 index = CGF.
Builder.CreateMul(index, objectSize);
3955 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
3958 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
3960 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
3979 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
3990 bool negMul,
bool negAdd) {
3991 Value *MulOp0 = MulOp->getOperand(0);
3992 Value *MulOp1 = MulOp->getOperand(1);
3994 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
3996 Addend = Builder.CreateFNeg(Addend,
"neg");
3998 Value *FMulAdd =
nullptr;
3999 if (Builder.getIsFPConstrained()) {
4000 assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
4001 "Only constrained operation should be created when Builder is in FP "
4002 "constrained mode");
4003 FMulAdd = Builder.CreateConstrainedFPCall(
4004 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4006 {MulOp0, MulOp1, Addend});
4008 FMulAdd = Builder.CreateCall(
4010 {MulOp0, MulOp1, Addend});
4012 MulOp->eraseFromParent();
4027 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4028 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4029 "Only fadd/fsub can be the root of an fmuladd.");
4032 if (!op.FPFeatures.allowFPContractWithinStatement())
4035 Value *LHS = op.LHS;
4036 Value *RHS = op.RHS;
4040 bool NegLHS =
false;
4041 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4042 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4043 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4044 LHS = LHSUnOp->getOperand(0);
4049 bool NegRHS =
false;
4050 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4051 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4052 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4053 RHS = RHSUnOp->getOperand(0);
4061 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4062 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4063 (LHSBinOp->use_empty() || NegLHS)) {
4066 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4067 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4070 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4071 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4072 (RHSBinOp->use_empty() || NegRHS)) {
4075 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4076 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4080 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4081 if (LHSBinOp->getIntrinsicID() ==
4082 llvm::Intrinsic::experimental_constrained_fmul &&
4083 (LHSBinOp->use_empty() || NegLHS)) {
4086 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4087 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4090 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4091 if (RHSBinOp->getIntrinsicID() ==
4092 llvm::Intrinsic::experimental_constrained_fmul &&
4093 (RHSBinOp->use_empty() || NegRHS)) {
4096 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4097 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4104Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4105 if (op.LHS->getType()->isPointerTy() ||
4106 op.RHS->getType()->isPointerTy())
4109 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4110 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4112 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4113 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4116 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4117 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4120 if (CanElideOverflowCheck(CGF.
getContext(), op))
4121 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4122 return EmitOverflowCheckedBinOp(op);
4127 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4128 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4134 if (op.Ty->isConstantMatrixType()) {
4135 llvm::MatrixBuilder MB(Builder);
4136 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4137 return MB.CreateAdd(op.LHS, op.RHS);
4140 if (op.Ty->isUnsignedIntegerType() &&
4141 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4142 !CanElideOverflowCheck(CGF.
getContext(), op))
4143 return EmitOverflowCheckedBinOp(op);
4145 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4146 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4147 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4150 if (op.isFixedPointOp())
4151 return EmitFixedPointBinOp(op);
4153 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4158Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4160 using llvm::ConstantInt;
4168 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4169 RHSTy = BinOp->getRHS()->getType();
4170 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4175 LHSTy = CAO->getComputationLHSType();
4176 ResultTy = CAO->getComputationResultType();
4178 LHSTy = BinOp->getLHS()->getType();
4179 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4180 LHSTy = UnOp->getSubExpr()->getType();
4181 RHSTy = UnOp->getSubExpr()->getType();
4184 Value *LHS = op.LHS;
4185 Value *RHS = op.RHS;
4190 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4194 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4195 switch (op.Opcode) {
4198 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4202 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4206 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4210 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4214 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4218 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4221 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4223 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4225 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4227 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4232 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4234 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4238 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4251 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4257 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4262Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4264 if (!op.LHS->getType()->isPointerTy()) {
4265 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4266 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4268 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4269 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4272 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4273 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4276 if (CanElideOverflowCheck(CGF.
getContext(), op))
4277 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4278 return EmitOverflowCheckedBinOp(op);
4283 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4284 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4290 if (op.Ty->isConstantMatrixType()) {
4291 llvm::MatrixBuilder MB(Builder);
4292 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4293 return MB.CreateSub(op.LHS, op.RHS);
4296 if (op.Ty->isUnsignedIntegerType() &&
4297 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4298 !CanElideOverflowCheck(CGF.
getContext(), op))
4299 return EmitOverflowCheckedBinOp(op);
4301 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4302 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4303 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4306 if (op.isFixedPointOp())
4307 return EmitFixedPointBinOp(op);
4309 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4314 if (!op.RHS->getType()->isPointerTy())
4321 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4323 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4324 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4328 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4330 llvm::Value *divisor =
nullptr;
4336 elementType = VlaSize.Type;
4337 divisor = VlaSize.NumElts;
4341 if (!eltSize.
isOne())
4357 if (elementSize.
isOne())
4366 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4369Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4371 llvm::IntegerType *Ty;
4372 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4373 Ty = cast<llvm::IntegerType>(VT->getElementType());
4375 Ty = cast<llvm::IntegerType>(LHS->
getType());
4380 llvm::Type *RHSTy = RHS->
getType();
4381 llvm::APInt RHSMax =
4382 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4383 :
llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4384 if (RHSMax.ult(Ty->getBitWidth()))
4385 return llvm::ConstantInt::get(RHSTy, RHSMax);
4386 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4390 const Twine &Name) {
4391 llvm::IntegerType *Ty;
4392 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4393 Ty = cast<llvm::IntegerType>(VT->getElementType());
4395 Ty = cast<llvm::IntegerType>(LHS->
getType());
4397 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4398 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4400 return Builder.CreateURem(
4401 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4404Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4406 if (Ops.isFixedPointOp())
4407 return EmitFixedPointBinOp(Ops);
4411 Value *RHS = Ops.RHS;
4412 if (Ops.LHS->getType() != RHS->
getType())
4413 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4415 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4416 Ops.Ty->hasSignedIntegerRepresentation() &&
4419 bool SanitizeUnsignedBase =
4420 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4421 Ops.Ty->hasUnsignedIntegerRepresentation();
4422 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4423 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4426 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4427 else if ((SanitizeBase || SanitizeExponent) &&
4428 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4429 CodeGenFunction::SanitizerScope SanScope(&CGF);
4431 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4432 llvm::Value *WidthMinusOne =
4433 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4434 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4436 if (SanitizeExponent) {
4438 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
4445 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4448 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4449 llvm::Value *PromotedWidthMinusOne =
4450 (RHS == Ops.RHS) ? WidthMinusOne
4451 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4453 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4454 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4457 if (SanitizeUnsignedBase || CGF.
getLangOpts().CPlusPlus) {
4463 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4464 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4466 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4467 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
4469 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4470 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4471 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4472 Checks.push_back(std::make_pair(
4473 BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4474 : SanitizerKind::UnsignedShiftBase));
4477 assert(!Checks.empty());
4478 EmitBinOpCheck(Checks, Ops);
4481 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4484Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4486 if (Ops.isFixedPointOp())
4487 return EmitFixedPointBinOp(Ops);
4491 Value *RHS = Ops.RHS;
4492 if (Ops.LHS->getType() != RHS->
getType())
4493 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4497 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4498 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4499 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4500 CodeGenFunction::SanitizerScope SanScope(&CGF);
4501 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4502 llvm::Value *Valid = Builder.CreateICmpULE(
4503 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4504 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
4507 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4508 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4509 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4517 default: llvm_unreachable(
"unexpected element type");
4518 case BuiltinType::Char_U:
4519 case BuiltinType::UChar:
4520 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4521 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4522 case BuiltinType::Char_S:
4523 case BuiltinType::SChar:
4524 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4525 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4526 case BuiltinType::UShort:
4527 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4528 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4529 case BuiltinType::Short:
4530 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4531 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4532 case BuiltinType::UInt:
4533 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4534 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4535 case BuiltinType::Int:
4536 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4537 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4538 case BuiltinType::ULong:
4539 case BuiltinType::ULongLong:
4540 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4541 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4542 case BuiltinType::Long:
4543 case BuiltinType::LongLong:
4544 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4545 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4546 case BuiltinType::Float:
4547 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4548 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4549 case BuiltinType::Double:
4550 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4551 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4552 case BuiltinType::UInt128:
4553 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4554 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4555 case BuiltinType::Int128:
4556 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4557 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4562 llvm::CmpInst::Predicate UICmpOpc,
4563 llvm::CmpInst::Predicate SICmpOpc,
4564 llvm::CmpInst::Predicate FCmpOpc,
4566 TestAndClearIgnoreResultAssign();
4576 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
4578 BinOpInfo BOInfo = EmitBinOps(E);
4579 Value *LHS = BOInfo.LHS;
4580 Value *RHS = BOInfo.RHS;
4586 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4588 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4591 Value *FirstVecArg = LHS,
4592 *SecondVecArg = RHS;
4598 default: llvm_unreachable(
"is not a comparison operation");
4610 std::swap(FirstVecArg, SecondVecArg);
4617 if (ElementKind == BuiltinType::Float) {
4619 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4620 std::swap(FirstVecArg, SecondVecArg);
4628 if (ElementKind == BuiltinType::Float) {
4630 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4635 std::swap(FirstVecArg, SecondVecArg);
4640 Value *CR6Param = Builder.getInt32(CR6);
4642 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
4649 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(
Result->getType());
4650 if (ResultTy->getBitWidth() > 1 &&
4652 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
4657 if (BOInfo.isFixedPointOp()) {
4658 Result = EmitFixedPointBinOp(BOInfo);
4659 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
4660 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4662 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
4664 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
4666 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
4671 !isa<llvm::ConstantPointerNull>(LHS) &&
4672 !isa<llvm::ConstantPointerNull>(RHS)) {
4681 LHS = Builder.CreateStripInvariantGroup(LHS);
4683 RHS = Builder.CreateStripInvariantGroup(RHS);
4686 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
4692 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
4700 CETy = CTy->getElementType();
4702 LHS.first = Visit(E->
getLHS());
4703 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
4709 CTy->getElementType()) &&
4710 "The element types must always match.");
4713 RHS.first = Visit(E->
getRHS());
4714 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
4716 "The element types must always match.");
4719 Value *ResultR, *ResultI;
4723 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
4724 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
4728 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
4729 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
4733 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
4736 "Complex comparison other than == or != ?");
4737 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
4749 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
4751 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
4752 *SrcType = ICE->getSubExpr()->getType();
4764 bool Ignore = TestAndClearIgnoreResultAssign();
4783 RHS = Visit(E->
getRHS());
4799 RHS = Visit(E->
getRHS());
4834 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4845 if (LHS->
getType()->isFPOrFPVectorTy()) {
4846 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4848 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4849 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4851 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4852 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4854 Value *
And = Builder.CreateAnd(LHS, RHS);
4855 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
4859 llvm::Type *ResTy = ConvertType(E->
getType());
4880 if (InstrumentRegions &&
4885 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4898 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
4903 return llvm::Constant::getNullValue(ResTy);
4915 CodeGenFunction::ConditionalEvaluation eval(CGF);
4924 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
4926 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4928 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
4937 RHSBlock = Builder.GetInsertBlock();
4942 if (InstrumentRegions &&
4946 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
4950 PN->addIncoming(RHSCond, RHSBlockCnt);
4960 PN->addIncoming(RHSCond, RHSBlock);
4970 PN->setDebugLoc(Builder.getCurrentDebugLocation());
4974 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
4985 if (LHS->
getType()->isFPOrFPVectorTy()) {
4986 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4988 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4989 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4991 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4992 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4994 Value *
Or = Builder.CreateOr(LHS, RHS);
4995 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
4999 llvm::Type *ResTy = ConvertType(E->
getType());
5020 if (InstrumentRegions &&
5025 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5038 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5043 return llvm::ConstantInt::get(ResTy, 1);
5055 CodeGenFunction::ConditionalEvaluation eval(CGF);
5065 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5067 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5069 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5081 RHSBlock = Builder.GetInsertBlock();
5086 if (InstrumentRegions &&
5090 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5094 PN->addIncoming(RHSCond, RHSBlockCnt);
5100 PN->addIncoming(RHSCond, RHSBlock);
5108 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5114 return Visit(E->
getRHS());
5139Value *ScalarExprEmitter::
5141 TestAndClearIgnoreResultAssign();
5144 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5154 Expr *live = lhsExpr, *dead = rhsExpr;
5155 if (!CondExprBool) std::swap(live, dead);
5185 llvm::Value *LHS = Visit(lhsExpr);
5186 llvm::Value *RHS = Visit(rhsExpr);
5188 llvm::Type *condType = ConvertType(condExpr->
getType());
5189 auto *vecTy = cast<llvm::FixedVectorType>(condType);
5191 unsigned numElem = vecTy->getNumElements();
5192 llvm::Type *elemType = vecTy->getElementType();
5194 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5195 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5196 llvm::Value *tmp = Builder.CreateSExt(
5197 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5198 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5201 llvm::Value *RHSTmp = RHS;
5202 llvm::Value *LHSTmp = LHS;
5203 bool wasCast =
false;
5204 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
5205 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5206 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5207 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5211 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5212 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5213 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5215 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5225 llvm::Value *LHS = Visit(lhsExpr);
5226 llvm::Value *RHS = Visit(rhsExpr);
5228 llvm::Type *CondType = ConvertType(condExpr->
getType());
5229 auto *VecTy = cast<llvm::VectorType>(CondType);
5230 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5232 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5233 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5242 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5251 llvm::Value *LHS = Visit(lhsExpr);
5252 llvm::Value *RHS = Visit(rhsExpr);
5255 assert(!RHS &&
"LHS and RHS types must match");
5258 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5269 CodeGenFunction::ConditionalEvaluation eval(CGF);
5287 Value *LHS = Visit(lhsExpr);
5290 LHSBlock = Builder.GetInsertBlock();
5291 Builder.CreateBr(ContBlock);
5305 Value *RHS = Visit(rhsExpr);
5308 RHSBlock = Builder.GetInsertBlock();
5318 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5319 PN->addIncoming(LHS, LHSBlock);
5320 PN->addIncoming(RHS, RHSBlock);
5343 llvm::Type *ArgTy = ConvertType(VE->
getType());
5348 return llvm::UndefValue::get(ArgTy);
5352 llvm::Value *Val = Builder.CreateLoad(ArgPtr);
5355 if (ArgTy != Val->getType()) {
5356 if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
5357 Val = Builder.CreateIntToPtr(Val, ArgTy);
5359 Val = Builder.CreateTrunc(Val, ArgTy);
5365Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5371 Value *Src,
unsigned NumElementsDst) {
5372 static constexpr int Mask[] = {0, 1, 2, -1};
5373 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5393 const llvm::DataLayout &DL,
5394 Value *Src, llvm::Type *DstTy,
5395 StringRef Name =
"") {
5399 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5400 return Builder.CreateBitCast(Src, DstTy, Name);
5403 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5404 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5407 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5409 if (!DstTy->isIntegerTy())
5410 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5412 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5416 if (!SrcTy->isIntegerTy())
5417 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5419 return Builder.CreateIntToPtr(Src, DstTy, Name);
5424 llvm::Type *DstTy = ConvertType(E->
getType());
5426 llvm::Type *SrcTy = Src->
getType();
5427 unsigned NumElementsSrc =
5428 isa<llvm::VectorType>(SrcTy)
5429 ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5431 unsigned NumElementsDst =
5432 isa<llvm::VectorType>(DstTy)
5433 ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5442 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5447 Src->setName(
"astype");
5454 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5455 auto *Vec4Ty = llvm::FixedVectorType::get(
5456 cast<llvm::VectorType>(DstTy)->getElementType(), 4);
5461 Src->setName(
"astype");
5466 Src, DstTy,
"astype");
5481 "Invalid scalar expression to emit");
5483 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5484 .Visit(
const_cast<Expr *
>(E));
5493 "Invalid scalar expression to emit");
5494 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy,
Loc);
5504 "Invalid complex -> scalar conversion");
5505 return ScalarExprEmitter(*
this)
5506 .EmitComplexToScalarConversion(Src, SrcTy, DstTy,
Loc);
5513 if (!PromotionType.
isNull())
5514 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5516 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
5522 bool isInc,
bool isPre) {
5523 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
5533 llvm::Type *BaseTy =
5548 ScalarExprEmitter
Scalar(*
this);
5551#define COMPOUND_OP(Op) \
5552 case BO_##Op##Assign: \
5553 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5590 llvm_unreachable(
"Not valid compound assignment operators");
5593 llvm_unreachable(
"Unhandled compound assignment operator");
5608 llvm::LLVMContext &VMContext,
5614 llvm::Value *TotalOffset =
nullptr;
5617 if (isa<llvm::Constant>(GEPVal)) {
5620 Value *BasePtr_int =
5621 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
5623 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
5624 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5625 return {TotalOffset, Builder.getFalse()};
5628 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5629 assert(GEP->getPointerOperand() == BasePtr &&
5630 "BasePtr must be the base of the GEP.");
5631 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
5633 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
5636 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5637 auto *SAddIntrinsic =
5638 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
5639 auto *SMulIntrinsic =
5640 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
5643 llvm::Value *OffsetOverflows = Builder.getFalse();
5647 llvm::Value *RHS) -> llvm::Value * {
5648 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
5651 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
5652 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
5654 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
5657 OffsetOverflows = Builder.getTrue();
5658 return llvm::ConstantInt::get(VMContext, N);
5663 auto *ResultAndOverflow = Builder.CreateCall(
5664 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
5665 OffsetOverflows = Builder.CreateOr(
5666 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
5667 return Builder.CreateExtractValue(ResultAndOverflow, 0);
5671 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
5672 GTI != GTE; ++GTI) {
5673 llvm::Value *LocalOffset;
5674 auto *Index = GTI.getOperand();
5676 if (
auto *STy = GTI.getStructTypeOrNull()) {
5679 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
5680 LocalOffset = llvm::ConstantInt::get(
5681 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
5686 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
5687 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
5688 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
5693 if (!TotalOffset || TotalOffset == Zero)
5694 TotalOffset = LocalOffset;
5696 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
5699 return {TotalOffset, OffsetOverflows};
5705 bool SignedIndices,
bool IsSubtraction,
5707 llvm::Type *PtrTy = Ptr->
getType();
5711 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5715 bool PerformNullCheck = !NullPointerIsDefined(
5716 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5719 bool PerformOverflowCheck =
5720 !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5722 if (!(PerformNullCheck || PerformOverflowCheck))
5727 SanitizerScope SanScope(
this);
5728 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
5733 assert((!isa<llvm::Constant>(EvaluatedGEP.
TotalOffset) ||
5735 "If the offset got constant-folded, we don't expect that there was an "
5738 auto *
Zero = llvm::ConstantInt::getNullValue(
IntPtrTy);
5752 if (PerformNullCheck) {
5764 auto *BaseIsNotNullptr =
Builder.CreateIsNotNull(Ptr);
5765 auto *ResultIsNotNullptr =
Builder.CreateIsNotNull(ComputedGEP);
5768 ?
Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5769 :
Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5770 Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5773 if (PerformOverflowCheck) {
5778 llvm::Value *ValidGEP;
5780 if (SignedIndices) {
5786 auto *PosOrZeroValid =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5787 auto *PosOrZeroOffset =
5789 llvm::Value *NegValid =
Builder.CreateICmpULT(ComputedGEP, IntPtr);
5791 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5797 ValidGEP =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5803 ValidGEP =
Builder.CreateICmpULE(ComputedGEP, IntPtr);
5805 ValidGEP =
Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5806 Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5809 assert(!Checks.empty() &&
"Should have produced some checks.");
5813 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5814 EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
5822 const Twine &Name) {
5823 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5829 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.